59

我在 xml 布局中为我的片段定义了一个 ID:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/test_fragment"
...

然后我在活动的 onCreate 方法中添加这个片段:

MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, myFragment);
fragmentTransaction.commit();

这一切都很好。更换碎片,也正在工作。

稍后,我尝试在活动的一种方法中通过其 ID 检索此片段:

MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentById(R.id.test_fragment);

这样做会导致 myFragment 成为null. 总是。

当我尝试对标签而不是 ID 执行相同操作时,我可以通过其标签检索片段而不会出现任何问题:

MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, myFragment, "testfragment");
fragmentTransaction.commit();

...

MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentByTag("testfragment");

为什么 findFragmentById 找不到片段,而 findFragmentByTag 却找到了?我错过了什么吗?

4

9 回答 9

44

R.id.test_fragment不是您的片段的 ID,而是您的 LinearLayout 的 ID

调用add(int containerViewId, Fragment fragment)将添加一个没有标签的片段。因此,或者您使用add(int containerViewId, Fragment fragment, String tag)并使用您的标签(作为 ID)取回您的片段

于 2012-05-31T12:37:21.717 回答
9

<FrameLayout>标签用作布局文件中的容器。稍后要动态替换活动中的片段,您可以使用<FrameLayout>容器的 ID 替换活动中的片段。

<FrameLayout
            android:id="@+id/test_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
于 2013-06-20T07:26:46.923 回答
4
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/test_fragment"

它应该是一个fragment而不是一个LinearLayout

<fragment android:name="com.example.yourfragment"
            android:id="@+id/test_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
于 2012-05-31T12:32:11.043 回答
4

我在调用实际搜索子类android.support.v4.app.Fragment时在布局中使用了. 所以解决方法是打电话。getFragmentManager()android.app.FragmentnullgetSupportFragmentManager()

通常,请确保您正在子类化并在布局中使用的片段包与FragmentManager执行搜索的相应片段返回的包相同。

于 2015-10-12T23:13:42.960 回答
2

R.id.test_fragment是你的LinearLayoutID 不是你的 Fragment。

当片段从 xml 膨胀时,您可以在片段上定义和标识,如本示例http://developer.android.com/guide/topics/fundamentals/fragments.html#Adding

于 2012-05-31T12:34:16.300 回答
2

或者,您应该改用:

(MyFragment) getFragmentManager().findFragmentById(R.id.fragment_container);
于 2013-03-14T03:14:04.207 回答
2

上面提到的原因是有效的,但另一个可能的原因是您试图在片段中搜索片段,这也会导致fragmentManager.findFragmentById返回 null。我们应该使用childFragmentManager.findFragmentById在片段中查找片段。根据官方文档。

public final androidx.fragment.app.FragmentManager getChildFragmentManager()

返回一个私有的 FragmentManager 用于在这个 Fragment 中放置和管理 Fragment。

于 2019-11-12T04:26:46.523 回答
1
FragmentB fragmentB = 
(FragmentB) getSupportFragmentManager().findFragmentById(R.id.containerb);

if(fragmentB != null)
{
   fragmentB.showuserResponse(msg);
}

使用容器 ID 作为片段 ID。然后检查空引用。

于 2017-03-31T06:53:19.723 回答
0

fragmentTransaction.add(R.id.fragment_container, myFragment);

MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentById(R.id.test_fragment);

请注意区别。

您应该将 R.id.fragment_container 作为参数传递给findFragmentById,因为您将它传递给 add 函数,而不是R.id.test_fragment

顺便说一下,根据这两个函数的内部实现,id可以是它的容器视图的id应该是对的。

于 2013-11-22T12:19:17.817 回答