4

I have a Login Fragment and a Class named CServerResponse.

I'd like to call LoginFragment from CServerResponse class.

How can I do that?

Here is the CServerResponse class code:

public class CServerResponse {
    public static CServerResponse s_m_oServerResponse;
    public Context m_Context;

    private CServerResponse(Context m_Context) {
        this.m_Context = m_Context;
    }

    public static CServerResponse getInstance() {
        if (s_m_oServerResponse == null) {
            s_m_oServerResponse = new CServerResponse();
        }
        return s_m_oServerResponse;
    }

    public void getLoginResponse() throws JSONException {
        final Fragment activity = (Fragment) m_Context;
        if (CLoginScreen.m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Transaction Successful")) {

            CLoginScreen.m_oLoginSession.setLoginData(
                CLoginScreen.s_szResponseMobile, CLoginScreen.s_szResponsePassword);

            getActivity().getSupportFragmentManager()
                         .beginTransaction()
                         .replace(R.id.container, new CDealMainListing()).commit();

            CToastMessage.getInstance().showToast(getActivity(), "You are successfully Logged In");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Agentcode Can Not Be Empty")) {

            CToastMessage.getInstance().showToast(getActivity(), "Please Enter Valid Mobile Number");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Pin Can Not Be Empty")) {

            CToastMessage.getInstance().showToast(getActivity(), "Please Enter Password");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Invalid PIN")) {

            CToastMessage.getInstance().showToast(getActivity(), "Please enter correct Password");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Blocked due to Wrong Attempts")) {

            CToastMessage.getInstance().showToast(getActivity(), "You are blocked as You finished your all attempt");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Connection Not Available")) {

            CToastMessage.getInstance().showToast(getActivity(), "Connection Lost ! Please Try Again");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Not Found")) {

            CToastMessage.getInstance().showToast(getActivity(), "User not found ! Kindly Regiter before Login");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("OTP not verify")) {

            CToastMessage.getInstance().showToast(getActivity(), "Otp not Verify ! Kindly Generate Otp on Sign Up");
        }
    }
}
fredmaggiowski
  • 2,232
  • 3
  • 25
  • 44
Nitin
  • 163
  • 2
  • 11
  • 3
    Possible duplicate of [Is it possible to have a fragment without an activity?](http://stackoverflow.com/questions/21071682/is-it-possible-to-have-a-fragment-without-an-activity) – fredmaggiowski Mar 30 '16 at 07:45
  • 1
    Also: http://stackoverflow.com/questions/23731309/fragment-without-activity – fredmaggiowski Mar 30 '16 at 07:52

4 Answers4

8

You'll need the access to the context of the Activity for which the fragment needs to be called.

Lets suppose you have the context of the respective Activity in a method named startLoginFragment(Context context). The code for this method will be as follows:

public void startLoginFragmemt(Context context) {
    Activity activity = (Activity) context;
    FragmentManager fragmentManager = activity.getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    LoginFragment fragment = new LoginFragment();
    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
}
Varun Kumar
  • 1,241
  • 1
  • 9
  • 18
2

If you are using AppCompatActivity then cast your context accordingly otherwise you will get Illegel cast Exception. So use

AppCompatActivity activity = (AppCompatActivity) context;

instead of simple activity

Activity activity = (Activity) context;
Inzimam Tariq IT
  • 6,548
  • 8
  • 42
  • 69
1

You can create Fragments out of an Activity but you shouldn't use them outside of an activity since their lifecycle methods are invoked only when attached to an Activity.

If you want to manipulate data inside your Fragment you can create a Fragment class. Construct and inflate it from an Activity and then access it from another class with public methods to modify the informations.

In your situation you can have:

  • LoginFragment: class which handles UI elements
  • LoginActivity: which inflates the LoginFragment and invokes the Login service.
  • LoginService: which handles the login service (AsyncTask ?), when it's done it returns to the LoginActivity the information you need and the Activity will send the update to the Fragment which ultimately will handle the information.

Some code.. As I said in the comments, this code might not be very useful.. Everything depends on how you handle everything... I personally like to use AsyncTask with custom interfaces which I use to create callbacks between the task and the UI thread (using them to exchange data between them and trigger an UI change). This code doesn't show you this approach but just how you should (in my humble opinion) organise your flow

The fragment:

Class LoginFragment extends Fragment {

    private PROP1 prop1;
    private PROP2 prop2;

    private LoginFragment(){}

    public static LoginFragment createInstance( PROP1 prop1, PROP2 prop2){
        this.prop1 = prop1;
        this.prop2 = prop2;
    }

    // Fragment lifecycle methods

    // Methods used by activity to trigger changes in UI..
    // They could be setters or.. really.. whatever fits best in your flow. 
    public void changeProp1(PROP1 prop1){
         this.prop1 = prop1;
         // EDIT UI ELEMENTS.. DO WHATEVER YOU NEED TO DO..
    }
}

The Activity:

Class LoginActivity extends Activity { // Activity or whatever Activity class you're using.

     private LoginFragment mLoginFragment;

     @Override
     public void onCreate(){ // I don't remember the correct signature

          // Create LoginFragment
          mLoginFragmet = LoginFragment.newInstance(prop1,prop2)
          // Use FragmentManager to inflate your fragment
     }

     public void serviceInvoke(){ // I don't remember the correct signature

          // Invoke your login service. I'd use an AsyncTask and an interface implementation that allows the usage of callbacks
          // When the service is complete take the result value and pass it to the proper Fragment method
          mLoginFragment.changeProp1(theResultOfTheService);
     }
}
fredmaggiowski
  • 2,232
  • 3
  • 25
  • 44
  • I could be a pretty big copy/paste of code you don't really need.. I'll edit the answer with some samples but what you'll see is not that far from what AndroidStudio gives you when you make it create a new Fragment class file. – fredmaggiowski Mar 30 '16 at 08:01
  • Just look at the proper implementation of an AsyncTask to handle your connection, of the FragmentManager to inflate your Fragment in the Activity and you're pretty much done – fredmaggiowski Mar 30 '16 at 08:02
0

This working for me.

 public class YOUR_CLASS extends AppCompatActivity{

    public void changeFragments(Context context, Fragment fragment, String putStringName, String putStringDescription) {

         AppCompatActivity activity = (AppCompatActivity) context;
         // Pasar datos de un fragment a otro
         Bundle datosAEnviar = new Bundle();
         datosAEnviar.putString(putStringName, putStringDescription);
         fragment.setArguments(datosAEnviar);


        activity.getSupportFragmentManager().beginTransaction().addToBackStack(null).
            replace(R.id.nav_host_fragment, fragment).commit();
    }


}
Kevin Mendez
  • 651
  • 5
  • 10