0

I want to pass a complex object between activity and fragments as well as fragments and fragments. Currently, the main activity create a fragment input object and set that as a member of the fragment needed to be open. Similarly, when another fragment wants to load another fragment it creates fragment input and notifies the main activity. See Main and child fragment code below. My question, is this correct implementation. Sometimes I encountered input being null in child activity, if the activity pauses and restarts.

Please tell me what I have done wrong, whats the best way to pass data.

 public class FragmentInput {

    public String url = "";
    public String title = "";
    public String time = "";
     ... other memebers
}

Main Activity

fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
                            .beginTransaction();
 BaseFragment fragment = new LandingFragment();
 **FragmentInput input = new FragmentInput();
 input.stringinput = stringinput;
 fragment.input = input;
 fragmentTransaction.replace(R.id.fragment, fragment);
 fragmentTransaction.commit();**



    public void replaceFragment(BaseFragment fragment) {

            if (fragment == null)
                return;

            if (fragment instanceof firstFragment) {
                FragmentTransaction fragmentTransaction = fragmentManager
                        .beginTransaction();
                fragmentTransaction.setCustomAnimations(0, 0);

                fragmentManager.popBackStackImmediate(null,
                        FragmentManager.POP_BACK_STACK_INCLUSIVE);

                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();

            } else {

                String ttag = fragment
                        .getClass().toString();

                Fragment tempF = fragmentManager.findFragmentByTag(ttag);
                if (tempF != null)
                    return;
                FragmentTransaction fragmentTransaction = fragmentManager
                        .beginTransaction();
                fragmentTransaction.setCustomAnimations(R.anim.fragment_enter,
                        R.anim.fragment_exit, R.anim.fragment_leftenter,
                        R.anim.fragment_leftexit);

                fragmentTransaction.replace(R.id.fragment, fragment, ttag);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
            }


        }

ChildFragment

@Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);
        try {
            activity = getActivity();
            resource = activity.getResources();
            view = getView();

            **if (input != null) {
                String url= input.url;**

       button.onclick(){
            FragmentInput input = new FragmentInput();
            input.url = path;
            input.title = resource.getString(R.string.txt_from_gallery);

            **BaseFragment fr = new otherFragment();
            FragmentChangeListener fc = (FragmentChangeListener)     getActivity();
            fr.setInput(input);
            fc.replaceFragment(fr);**
}
}
pats
  • 1,273
  • 2
  • 20
  • 43
  • When are you going to pass values? – Anshul Tyagi Nov 10 '15 at 11:21
  • fragment.input = input; I set the value and read it from other fragment, ChildFragment onclick shows how i set the value and notify main activity which calls replacefragment method to change the fragments – pats Nov 10 '15 at 12:48

2 Answers2

6

If your fragments attach to same activity, you can store your objects in activity and access to objects like below:

((YourActivity)getActivity()).getYourObjects();

If you are storing your objects in bundle in you activity i recommand to call the code sample i gave above in onActivityCreated() method of your fragments to avoid null pointer exception.

If you want to pass your objects between activities or fragments in bundle. You should implement Parcelable to your objects and pass them.

What's Parcelable? http://developer.android.com/reference/android/os/Parcelable.html

Parcelable is more efficient but you can check Serializable: http://developer.android.com/reference/java/io/Serializable.html

It's not a good design to pass large objects in bundle.

Also you can pass your objects with interfaces or you can pass them with bus events. You can check Guava or OttoBus. http://square.github.io/otto/

savepopulation
  • 11,736
  • 4
  • 55
  • 80
  • Thanks for your response. I have a single activity with multiple fragments changing based on user events. With the first approach you are saying that the activity should have a store of input objects for fragments right. How do I manage them when fragment goes in and out of backstack. But the main question is would that store survive if the app goes inactive (user gets a phone call) and come back to the app. I feel like Parcelable is the way, but my input has 19 members with string, int and long. – pats Nov 10 '15 at 22:05
  • If your activity does not destroy your fragments can access objects which you store in your activity. If you get your fragment from backstack just check if your objects in activity null or not. If they're not null init your fragment data. But what happens when your activity gets destroyed? If your data is critical you can save it onSaveInstanceSatete and restore it onRestoreInstancestate. As i said above in this case accessing restored activity data from fragments in onActivityCreated method of your fragments is critical. – savepopulation Nov 11 '15 at 05:57
2

In this case you can use static holder (it's a bit similar to a singleton pattern).

Create a new class

public class Holder
{
    private static FragmentInput input = null;

    public static void setInput(FragmentInput value) { this.input = value; }
    public static FragmentInput getInput() { return input; }
}

In your main activity, after you create your new FragmentInput object hold it on the Holder

Holder.setInput(input);

And you can access it anywhere, simply call

FragmentInput myInput = Holder.getInput();
Eliran Kuta
  • 4,148
  • 3
  • 24
  • 28
  • Thanks for your response. I cant use a static variable, because the app has one activity and that activity has many fragments change based on user events. They also go to the back stack. – pats Nov 10 '15 at 21:51