Android findFragmentById 返回 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23353344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
findFragmentById return null
提问by simperreault
When i call findFragmentById() with the id of my fragment, it return null. Let me show you the code.
当我用我的片段的 id 调用 findFragmentById() 时,它返回 null。让我向您展示代码。
The activity_main.xml
活动_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.madduck.test.app.fragment.MainFragment"
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="com.madduck.test.app.fragment.LoginFragment"
android:id="@+id/login_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
The MainActivity.java
MainActivity.java
private static final int LOGIN = 0;
private static final int MAIN = 1;
private static final int FRAGMENT_COUNT = MAIN +1;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
fragments[LOGIN] = fm.findFragmentById(R.id.login_fragment);
fragments[MAIN] = fm.findFragmentById(R.id.main_fragment);
FragmentTransaction transaction = fm.beginTransaction();
for (Fragment f : fragments) {
if (f != null)
transaction.hide(f);
else
Log.e(TAG, "???");
}
transaction.commit();
}
The thing is that when i call fm.findFragmentById(R.id.login_fragment);I get null but when I call fm.findFragmentById(R.id.main_fragment);I get the fragment.
问题是,当我打电话时,fm.findFragmentById(R.id.login_fragment);我得到了空值,但是当我打电话时,fm.findFragmentById(R.id.main_fragment);我得到了片段。
回答by codeskraps
The answer Kar0tis perfectly fine but this may help somebody. On my case I had a fragment inside of a fragment and I was getting the wrong FragmentManager. I just had to call:
答案Kar0t非常好,但这可能对某人有所帮助。在我的情况下,我在一个片段中有一个片段,我得到了错误的 FragmentManager。我只需要打电话:
getChildFragmentManager()
getChildFragmentManager()
and then just find the Fragment as usual:
然后像往常一样找到片段:
fm.findFragmentById(R.id.fragment)
回答by simperreault
just found out my mistake.
刚刚发现我的错误。
In my MainActivity.java i was importing android.support.v4.app.Fragment;and in my LoginFragment.java i was importing android.app.Fragment;. I changed it to the same thing and fm.findFragmentById(R.id.login_fragment)now return the right fragment.
在我的 MainActivity.java 中,我正在导入,android.support.v4.app.Fragment;而在我的 LoginFragment.java 中,我正在导入android.app.Fragment;. 我把它改成同样的东西,fm.findFragmentById(R.id.login_fragment)现在返回正确的片段。
回答by Pavel Poley
Not really related to the specific question but related to receiving nullon findFragmentById, if you call findFragmentByIdimmediately after commit it will return null or the last fragment(before commit), the reason because commit do async request.
与特定问题无关,但与接收null有关findFragmentById,如果您findFragmentById在提交后立即调用,它将返回 null 或最后一个片段(提交前),原因是提交执行异步请求。
From docs:
从文档:
Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.
安排此事务的提交。提交不会立即发生;它将被安排为主线程上的工作,以便在该线程准备好时完成。
If you need to findFragmentByIdimmediately, for example change status bar text color after adding fragment, call executePendingTransactions()after commit()
如果您需要findFragmentById立即,例如更改状态栏文字颜色添加片段,通话后executePendingTransactions()后commit()
getSupportFragmentManager().executePendingTransactions();
//call findFragmentById
回答by Barbara K
Kotlin
科特林
I also had problem because I was in a child fragment. I could use:
我也有问题,因为我在一个儿童片段中。我可以使用:
supportFragmentManager.fragments.forEach {
it.childFragmentManager.fragments.forEach { fragment ->
if (fragment is HomeFragment) {
//do something
}
}
but one coworker optimized it with :
但是一位同事使用以下方法对其进行了优化:
if( findNavController(R.id.nav_host_fragment).currentDestination?.id == R.id.homeFragment) {
// do something
}
回答by ShengX
I encountered this problem because my project has two layout with the same file name. eg. In your case, I have two activity_main.xmlin different modules.
我遇到这个问题是因为我的项目有两个文件名相同的布局。例如。在你的情况下,我有两个activity_main.xml在不同的模块中。
So somehow it get compiled and when you run
所以它以某种方式被编译,当你运行时
fm.findFragmentById(R.id.login_fragment)
fm.findFragmentById(R.id.login_fragment)
then it is looking for the fragment in the other activity_main.xml, which is null.
然后它正在寻找 other 中的片段,该片段activity_main.xml为空。
If this is the case, just check your file names of layouts, make sure they are unique.
如果是这种情况,只需检查布局的文件名,确保它们是唯一的。
Hope this help anyone with the same issue as mine. :)
希望这可以帮助任何和我有同样问题的人。:)

