【问题标题】:android-calling findFragmentByTag immediately after committing transactionandroid-在提交事务后立即调用 findFragmentByTag
【发布时间】:2021-02-09 14:52:18
【问题描述】:

将一个片段替换为另一个片段的常见做法是:

getActivity().getSupportFragmentManager()
.beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragment_holder, ItemFragment.newInstance(bundle),"tag")
.addToBackStack(null)
.commit();

commit() 方法的文档说:

安排此事务的提交。 提交不会立即发生;它将被安排在主线程上的工作,以便在该线程下一次准备好时完成。

现在想象一下我在上面提到的提交方法之后立即调用getActivity.getSupportFragmentManager.findFragmentByTag("tag");。由于提交不会立即发生,是否有可能返回 null?

【问题讨论】:

  • 更新:我测试了越来越多,终于可以体验到nullPointerException。所以我的问题的简单答案是:是的,有可能!

标签: android android-fragments fragmenttransaction


【解决方案1】:

如果documentation for findFragmentByTag("tag") 会这样说,我认为它不会返回 null。

该方法也来自FragmentManager类,所以它只关心是否包含在片段管理器中commit()函数来自FragmentTransaction类一个片段可以在片段管理器的后堆栈中,即使它没有被提交,这就是为什么函数findFragmentByTag("tag") 将返回片段并且只有当带有该标签的片段从未添加到片段管理器时才会返回 null

getSupportFragmentManager()
   .beginTransaction()
   .setReorderingAllowed(true)
   .replace(R.id.fragment_holder, fragmentB, "tag")
   .addToBackStack(null)

上面的代码将片段添加到宿主活动片段管理器的后台堆栈中,您可以这样做并在片段管理器中找到该片段,不需要提交。

【讨论】:

    【解决方案2】:

    我会说这是可能的,但我觉得这里真正的问题是您使用的设计。如果 Fragment A 需要引入/替换 Fragment B,那么正确的设计是让 Activity 来处理 Fragment 管理。片段不应直接添加/替换其他片段。

    如果这一切都在 Activity 中处理,您可以轻松地保留对新 Fragment 的引用,这意味着您不需要 findFragmentByTag("tag") 因为您在创建/替换时已经有了对它的引用.

               Activity
               /      \
       Fragment A     Fragment B
    

    Fragment A 和 Fragment B 不应直接相互影响。

    // In Activity ...
    public replaceFragment() {
       Fragment fragmentB = ItemFragment.newInstance(bundle);
        
        getSupportFragmentManager()
           .beginTransaction()
           .setReorderingAllowed(true)
           .replace(R.id.fragment_holder, fragmentB, "tag")
           .addToBackStack(null)
           .commit();
    
        // You now have fragmentB no need to getSupportFragmentManager.findFragmentByTag("tag")
        fragmentB.doSomething();
    

    【讨论】:

    • 当然我可以保留对新创建的片段的引用,但我想避免它。碎片已经由系统(SupportFragmentManager)管理和保存,因此对它们进行强引用是浪费内存。
    猜你喜欢
    • 1970-01-01
    • 2015-01-14
    • 2015-12-28
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    相关资源
    最近更新 更多