0

If I'm adding fragments to my activity like this:

    fragment_tags = new ArrayList<String>();
    fragment_tags.add("user_fragment");
    fragment_tags.add("memorial_fragment");

    UserFragment user = new UserFragment();
    MemorialFragment memorial = new MemorialFragment();

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    ft.add(R.id.content_frame, user, fragment_tags.get(0));
    ft.add(R.id.content_frame, memorial, fragment_tags.get(1));
    ft.commit();

and then after some time I'm trying to retrieve these fragments like this:

    List<Fragment> frg = getSupportFragmentManager().getFragments();
    Fragment fragUser = getSupportFragmentManager().findFragmentByTag(
            "user_fragment");
    Fragment fragUserID = getSupportFragmentManager().findFragmentById(
            R.id.user_fragment_id);
            Log.d("MV", "fragments size:" + (frg == null ? " null" : frg.size()));

Log.d will always return size of 2, but fragUser is sometimes null and sometimes it's the fragment I put in transaction.

Which is more interesting is that this code:

    try {
        Log.d("MV", "0:" + frg.get(0).toString());
        Log.d("MV", "1:" + frg.get(1).toString());
    } catch (NullPointerException e) {
        Log.d("MV", "null caught");
    }

will sometimes work for both fragments and sometimes just for the first and if i do smething like this:

if(frg.get(0) == fragUser)

it will be sometimes evaluated as true, but not often.. I don't really understand this behaviour, but I need to implement switching between multiple fragments, so I need to get reference to exact fragment. Anybody? I'm trying to solve this for 6 hours now and I really dont understand how to do this. Thank you

Squonk
  • 48,735
  • 19
  • 103
  • 135
vanomart
  • 1,739
  • 1
  • 18
  • 39
  • Well to answer one part... **"if(frg.get(0) == fragUser)"** ...you can't compare objects using `==`. You need to use `if(frg.get(0).equals(fragUser))` – Squonk Nov 26 '13 at 00:32
  • Squonk actually this is my intention.. I don't care if objects have the same attributes, but if their references are the same, they must be the same objects.. I want the same fragment. – vanomart Nov 26 '13 at 00:37

1 Answers1

0

Since this question was posted by me back in 2013, gained over 1000 views but is still without any response, I will try to sum up what I've learned over the years when working with fragments.

  1. Don't use getSupportFragmentManager().getFragments() (more on this in getSupportFragmentManager().getFragments() shows a compile time error)
  2. FragmentManager is there to manage fragments lifecycle. Don't try to put fragments into your own lists or keep strong reference to them
  3. The reason why the if(frg.get(0) == fragUser) didn't work consistently is tied to the point 2. - FragmentManager manages the fragments, so when it decides to kill one and recreate it again, the references will not match.

Now the question - how to safely work with fragments?

  1. Pass data to fragments in a bundle using setArguments() method, so Android can kill&recreate the fragment.
  2. FragmentManager.findFragmentById(R.id.some_id) will find fragment that is attached to the view with id some_id. It is very likely that if you have multiple fragments added to R.id.some_id, FragmentManager.findFragmentById(R.id.some_id) will give different results (but it's usually a very good method to find out which fragment is currently visible unless you also hide/display your fragments)
  3. Understand different methods from FragmentTransaction API, especially differences between add and replace, hide, detach, remove and show.
  4. Sometimes things just don't work (crashes when multiple fragment transition animations run at once) or your app is not a good use case for fragments. You can read more about the latter in now classic post https://medium.com/square-corner-blog/advocating-against-android-fragments-81fd0b462c97
vanomart
  • 1,739
  • 1
  • 18
  • 39