GetFragmentManager.findFragmentByTag() 返回 null。

27
        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);

我已经提供了一个标签,所以我不确定为什么findFragmentByTag()返回null

我尝试过以下方法:

  1. 在两个fragmentsoncreate中都设置this.setRetainInstance(true)

  2. 两个fragment构造函数都是空的public fragmentName(){}

  3. 添加fragments后尝试执行executePendingTransactions

  4. 尝试将fragments替换为add(编辑过)


你解决了你的问题吗?我也有相关的问题:http://stackoverflow.com/questions/24833912/refresh-fragment-ui-from-fragmentactivity - Dr.jacky
6个回答

27

我对这个问题困惑了很长时间。首先,您需要通过将其推送到后退堆栈中保存要替换的片段。您提供的标记放在您正在添加而不是推送到后退堆栈的片段上。稍后,当您将其推送到后退堆栈时,该标记也会随之移动。以下是使用对象拆分的代码,使其更易于跟踪。您必须在'commit'之前调用'addToBackStack'。

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"

谢谢。在替换中提供的字符串标签和后退堆栈标签之间的区别是两个不同的事情。这让我困惑了一段时间。 - u2tall
3
这是正确的答案,因为在替换/添加方法中需要添加TAG,而不是在addToBackStack(TAG)方法中添加,因为它与findFragmentByTag(TAG)没有任何关系。 - Chapz
1
很好的解释。帮了我大忙。 - Rakesh Yadav
@Chapz 不是针对我。我需要addToBackStack。 - Daniel Ryan
tr.replace(R.id.fragment_container, liFrag, "LIST_FRAGMENT"); 这个对我有用。我没有添加第三个参数,首先还要添加标签addToBackStack("LIST_FRAGMENT")。 - Kashinath

18

在片段事务之后调用getFragmentManager().executePendingTransactions()。

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
为使您的答案更有价值,您应该添加一些解释或背景信息(并将getSupport...放在反引号``中)。请注意不要改变原意。 - m02ph3u5
1
它对我在AndroidX方面没有帮助。 - Georgiy Chebotarev
1
这个可以运行,但是更好的解释会更受欢迎。有一天它可以不用这个,但是第二天就需要了。 - htafoya

16

我遇到了同样的问题,findFragmentByTag() 一直返回 null。

最终我发现,我在 Activity 中覆盖了 onSaveInstanceState() 方法,但没有调用其超类。当我修复了这个问题后,findFragmentByTag() 正常返回了所需的 Fragment。


3
对我没用。而且与 @Dmitry Dudá 的答案混合在一起也不起作用。我没有使用 addToBackStack - Ivan Black
2
没有帮助。我没有覆盖它。 - Azizjon Kholmatov

7

您可以使用

fragmentTransaction.addToBackStack(yourFragmentTag);

之后,您可以使用它进行重复使用

getSupportFragmentManager().findFragmentByTag(yourFragmentTag);

getSupportFragmentManager() 不能解决问题,因为在两个片段中,它可能没有继承自 android.support.v4.app.Fragment - ahmed hamdy
他可能也不需要将他的片段添加到返回栈中。 - ahmed hamdy
@ahmedhamdy 确定。这是一个快速的答案。如果他不使用支持库,他可以使用getFragmentManager();并添加所有要重用的片段,并找到它们以便以后重用。 - savepopulation
addtoBackStack 是我所缺少的东西 :-P - kenyee
3
我也遇到了同样的问题,我使用了addToBackStack(TAG),但问题实际上出在了add(container, fragment)上。我将其改成了add(container, fragment, TAG),问题就解决了。 - Alexey Osminin

2

已经在这里回答过了,只需要在findByTag或findById之后调用getSupportFragmentManager().executePendingTransactions();即可。


0
在我的情况下,我不得不创建一个类级别的FragmentManager对象,然后使用它来代替直接使用getSupportFragmentManager()。
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();
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接