GetFragmentManager.findFragmentByTag() returns nul

2019-02-02 10:03发布

        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)

6条回答
Explosion°爆炸
2楼-- · 2019-02-02 10:08

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楼-- · 2019-02-02 10:19

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

查看更多
别忘想泡老子
4楼-- · 2019-02-02 10:21

You can use

fragmentTransaction.addToBackStack(yourFragmentTag);

After that you can reuse it with

getSupportFragmentManager().findFragmentByTag(yourFragmentTag);
查看更多
Juvenile、少年°
5楼-- · 2019-02-02 10:21

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");
查看更多
迷人小祖宗
6楼-- · 2019-02-02 10:28

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.

查看更多
贼婆χ
7楼-- · 2019-02-02 10:31

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();
    }
  }
}
查看更多
登录 后发表回答