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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:02:39  来源:igfitidea点击:

findFragmentById return null

androidandroid-fragmentsnullpointerexception

提问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. :)

希望这可以帮助任何和我有同样问题的人。:)