GetFragmentManager.findFragmentByTag() returns nul

2019-02-02 09:54发布

问题:

        getFragmentManager().beginTransaction()
                .replace(R.id.graph_fragment_holder, new GraphFragment(), "GRAPH_FRAGMENT")
                .commit();

        getFragmentManager().beginTransaction()
                .replace(R.id.list_fragment_holder, new ListFragment(), "LIST_FRAGMENT")
                .commit();

        //getFragmentManager().executePendingTransactions();

        GraphFragment graphFragment = (GraphFragment) getFragmentManager().findFragmentByTag("GRAPH_FRAGMENT");
        graphFragment.setData(data);

        ListFragment listFragment = (ListFragment) getFragmentManager().findFragmentByTag("LIST_FRAGMENT");
        listFragment.setData(data);

I've supplied a tag so I'm not sure why findFragmentByTag() returns null.

What I've tried from reading other questions:

  1. this.setRetainInstance(true) in the oncreate of both fragments.

  2. Both fragment constructors are empty public fragmentName(){}.

  3. tried executePendingTransactions after adding the fragments.

  4. tried add instead of replace on the fragments (edited)

回答1:

I was having the same problem of findFragmentByTag() always returning null.

Eventually I tracked it down, I was overriding onSaveInstanceState() in my Activity but not calling super. As soon as I fixed that findFragmentByTag() returned the Fragment as expected.



回答2:

I was confused about this for a long time. First, you need to save the fragment you are replacing by pushing it onto the back stack. The tag you supply is put on the fragment you are adding, not the one you are pushing onto the back stack. Later, when you do push it onto the back stack, that tag goes with it. Here's code with objects broken out to make it easier to trace. You must call 'addToBackStack' before 'commit'.

GraphFragment grFrag = new GraphFragment();
FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
tr.replace(R.id.fragment_container, grFrag, "GRAPH_FRAGMENT");
// grFrag is about to become the current fragment, with the tag "GRAPH_FRAGMENT"
tr.addToBackStack(null);
// 'addToBackStack' also takes a string, which can be null, but this is not the tag
tr.commit();
// any previous fragment has now been pushed to the back stack, with it's tag

ListFragment liFrag = new ListFragment();
FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
tr.replace(R.id.fragment_container, liFrag, "LIST_FRAGMENT");
// liFrag is is about to become the current fragment, with the tag "LIST_FRAGMENT"
tr.addToBackStack(null);
tr.commit();
// 'grFrag' has now been pushed to the back stack, with it's tag being "GRAPH_FRAGMENT"


回答3:

You can use

fragmentTransaction.addToBackStack(yourFragmentTag);

After that you can reuse it with

getSupportFragmentManager().findFragmentByTag(yourFragmentTag);


回答4:

Call getFragmentManager().executePendingTransactions() after fragment transaction.

getFragmentManager()
    .beginTransaction()
    .replace(R.id.container, new ExampleFragment(), "YOUR TAG HERE");
    .commit();

//after transaction you must call the executePendingTransaction
getFragmentManager().executePendingTransactions();

//now you can get fragment which is added with tag
ExampleFragment exampleFragment = getFragmentManager().findFragmentByTag("YOUR TAG HERE");


回答5:

Answered here, just need to call getSupportFragmentManager().executePendingTransactions(); after your findByTag or findById



回答6:

In my case I had to create a class level FragmentManager object and then use it instead of using getSupportFragmentManager() directly.

public class Main extends BaseActivity {
   FragmentManager fragmentManager;

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragmain);
    fragmentManager = getSupportFragmentManager();
    initFrag1();
  }

  private void initFrag1() {
    String name = Frag1.class.getSimpleName();
    if (fragmentManager.findFragmentByTag(name) == null) {
      fragmentManager.beginTransaction()
          .add(R.id.frag_container, new Frag1(), name)
          .addToBackStack(name)
          .commit();
    }
  }
}