2012-05-31 125 views
49

我定义我的XML布局片段的ID:findFragmentById始终返回null

<?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是这样做的?我错过了什么吗?

+0

尝试'(MyFragment)getFragmentManager()。findFragmentById(R.id.container);' – offset

回答

37

R.id.test_fragment在片段定义id是不是你片段的ID,但你的LinearLayout

调用add(int containerViewId, Fragment fragment)将增加的id没有标签的片段。 所以,或者你使用add(int containerViewId, Fragment fragment, String tag),并使用您的标记(作为ID)

+15

这是一种有效的解决方法,但未回答问题。仔细阅读文档以获取正确的描述。该文档说,ID是要么从XML分配的片段时分配,要么是使用事务添加时的容器ID ... http://developer.android.com/reference/android/app/FragmentManager.html#findFragmentById(int ) – speedynomads

+0

查看此答案以获取有关以编程方式分配id的较好说明:http://stackoverflow.com/a/13241629/857681 – speedynomads

+5

如果添加了没有id的片段,是不是可以使用容器的id找到它放在?我很确定那是一件事。 –

3
<?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" /> 
+0

那么我需要改变什么?我无法用作为顶层节点来定义我的布局。我不能在活动的xml布局中添加片段,因为之后我必须将其删除。 – Viper

+1

看到编辑... – Blackbelt

+0

好吧,你不能在布局中定义片段。如果您需要检索linerarlayout,则必须使用onCreateView中的inflater参数 – Blackbelt

1

或者你拿回你的片段,你应该改用:

(MyFragment) getFragmentManager().findFragmentById(R.id.fragment_container); 
9

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

<FrameLayout 
      android:id="@+id/test_fragment" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 
+0

为我工作! –

-1

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可以是 是其容器视图。

3

我在我的布局中使用android.support.v4.app.Fragment,同时调用getFragmentManager()其实际搜索android.app.Fragment子类,我得到null。 所以修正是改为拨打getSupportFragmentManager()

一般情况下,确保您在布局中进行子类化和使用的片段的包装与执行搜索的相应FragmentManager返回的相同。

0
FragmentB fragmentB = 
(FragmentB) getSupportFragmentManager().findFragmentById(R.id.containerb); 

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

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