findFragmentById() 和 findFragmentByTag()

Posted

技术标签:

【中文标题】findFragmentById() 和 findFragmentByTag()【英文标题】:findFragmentById() and findFragmentByTag() 【发布时间】:2017-09-17 03:45:17 【问题描述】:

我创建了一个片段来显示我的回收站视图。所以我使用 findFragmentById() 方法来查找我的 xml 文件。问题是每次我旋转屏幕时,它都会在另一个之上创建一个更多的回收器视图堆栈。 这是我的代码:

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ListFragment savedFragment = (ListFragment) getSupportFragmentManager().findFragmentById(R.id.list_recyclerview);

    if(savedFragment == null)
    
        ListFragment fragment  = new ListFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.place_holder,fragment);
        fragmentTransaction.commit();

    

但是当我使用方法 findFragmentByTag() 时,并没有发生。

谁能解释一下这两种方法有什么区别?

【问题讨论】:

您正在将片段添加到 ID 为 place_holder 的视图中,因此您应该使用 getSupportFragmentManager().findFragmentById(R.id.place_holder); 查找它。这种不匹配解释了为什么 findFragmentById 永远找不到您现有的片段。 这是我的大错。非常感谢您的帮助。 【参考方案1】:

此方法允许您检索先前添加的片段实例,而无需保留对该片段实例的引用。两者之间的区别在于它们跟踪它的方式,如果它具有给定的 TAG,您之前在添加片段事务时分配给片段事务,或者只是通过检索给定容器中最后添加的片段。让我们来看看这两种方法:

findFragmentByTag

此方法允许您检索具有给定标记的先前添加的片段的实例,而不管它被添加到的容器。这是通过以下方式完成的:

让我们先添加一个带有 TAG 的片段:

MyFragment fragment  = new MyFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.place_holder,fragment,"myFragmentTag");
fragmentTransaction.commit();

然后检索片段的实例:

fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag("myFragmentTag");
if(fragment != null)
    // ok, we got the fragment instance, but should we manipulate its view?

如果fragment 不为null,则表示您获得了引用该片段TAG 的实例。请记住,使用此方法,即使您获得了实例,也不意味着该片段是可见的或已添加到容器中,这意味着您应该进行额外的检查,如果您要处理它的视图中的某些内容,请使用:

if(fragment != null && fragment.isAdded())
    // you are good to go, do your logic

findFragmentById

在此方法中,您将获得最后添加片段的实例到给定容器。所以让我们假设我们在没有标签的容器中添加了一个片段(请注意,您也可以给它一个标签并以这种方式检索它):

MyFragment fragment  = new MyFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container,fragment);
fragmentTransaction.commit();

然后使用容器 ID 检索它的实例:

fragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if(fragment != null)
    // you are good to go, do your logic

此时,由于我们使用了findFragmentById,因此我们知道它是给定容器的可见片段,因此您无需检查它是否已添加到容器中。

【讨论】:

很高兴为您提供帮助。如果它解决了您的问题,请将答案标记为正确 如果我使用逐个标签查找片段将创建在该片段上调用的视图?一次检索? 不,你只是得到片段实例。如果将其添加到容器中,则会调用 onCreateView

以上是关于findFragmentById() 和 findFragmentByTag()的主要内容,如果未能解决你的问题,请参考以下文章

findFragmentById 返回 null

迁移到 AndroidX 后,findFragmentById 为片段返回 null

Mapfragment findFragmentById 始终为空

Fragment使用findFragmentById返回null

SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null

Android findFragmentById 返回 null