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 null
on findFragmentById
, if you call findFragmentById
immediately 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 findFragmentById
immediately, 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.xml
in 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. :)
希望这可以帮助任何和我有同样问题的人。:)