findFragmentById 返回 null

Posted

技术标签:

【中文标题】findFragmentById 返回 null【英文标题】:findFragmentById return null 【发布时间】:2014-06-14 17:21:02 【问题描述】:

当我使用片段的 id 调用 findFragmentById() 时,它会返回 null

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_>

        <fragment android:name="com.madduck.test.app.fragment.MainFragment"
                  android:id="@+id/main_fragment"
                  android:layout_
                  android:layout_ />

        <fragment android:name="com.madduck.test.app.fragment.LoginFragment"
                  android:id="@+id/login_fragment"
                  android:layout_
                  android:layout_ />
</LinearLayout>

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();

问题是,当我调用fm.findFragmentById(R.id.login_fragment); 时,我得到一个null,但是当我调用fm.findFragmentById(R.id.main_fragment); 时,我得到了片段。

【问题讨论】:

发布完整的崩溃日志和你的片段代码 感谢您的快速回答,我找到了解决方案(在一个片段中使用 support.v4,在另一个片段中使用普通类型)我现在无法发布解决方案,因为我没有t 有 10 名声望,但明天会回答自己。我之前搜索了一下,没有发现与此相关的内容。 我怀疑这可能是问题所在。无论如何你找到它。不错 【参考方案1】:

答案Kar0t 非常好,但这可能会对某人有所帮助。在我的情况下,我在片段中有一个片段,并且我得到了错误的 FragmentManager。我只需要打电话:

getChildFragmentManager()

然后像往常一样找到片段:

fm.findFragmentById(R.id.fragment)

【讨论】:

我也在这里挣扎。非常感谢! 工作!当我使用 标签在片段中添加片段时,getChildFragmentManager() 有效,而 getFragmentManager() 无效。如果我在父片段中使用 getFragmentManager() promatically 添加片段,则 getFragmentManager() 有效。然后如果我在片段中添加片段,我必须使用 getChildFragmentManager()? @inhogo 要添加Fragment 两者都可以,但是要查找Fragment,如果您在Fragmnet 内部,则必须使用getChildFragmentManager()【参考方案2】:

刚刚发现我的错误。

在我的 MainActivity.java 中,我正在导入 android.support.v4.app.Fragment;,在我的 LoginFragment.java 中,我正在导入 android.app.Fragment;。我将其更改为相同的内容,fm.findFragmentById(R.id.login_fragment) 现在返回正确的片段。

【讨论】:

我浪费了一整天的时间来寻找类似问题的答案,谢谢 感谢您的洞察力。在我的情况下,使用 getSupportFragmentManager() 而不是 getFragmentManager() 解决了这个问题,因为我的底层片段来自支持包。 天哪……太浪费时间了。 Think Jetbrains 对于导入它认为 正确的东西有点过分热心。我以前在 C# 中用 Rider 看到过这个。【参考方案3】:

与具体问题无关,但与在findFragmentById上接收null有关,如果您在提交后立即调用findFragmentById,它将返回null或最后一个片段(提交前),原因是提交做异步请求。

来自文档:

安排此事务的提交。提交没有发生 立即地;它将被安排在主线程上工作 下次该线程准备好时完成。

如果您需要立即findFragmentById,例如添加片段后更改状态栏文本颜色,请在commit()之后调用executePendingTransactions()

getSupportFragmentManager().executePendingTransactions();
//call findFragmentById 

【讨论】:

【参考方案4】:

科特林

我也有问题,因为我在一个子片段中。我可以使用:

    supportFragmentManager.fragments.forEach 
        it.childFragmentManager.fragments.forEach  fragment ->
            if (fragment is HomeFragment) 
                //do something
             
        

但一位同事对其进行了优化:

     if( findNavController(R.id.nav_host_fragment).currentDestination?.id == R.id.homeFragment) 
       // do something
   

【讨论】:

【参考方案5】:

我遇到这个问题是因为我的项目有两个具有相同文件名的布局。例如。就你而言,我在不同的模块中有两个 activity_main.xml

所以它以某种方式被编译并且当你运行时

fm.findFragmentById(R.id.login_fragment)

然后它正在寻找另一个activity_main.xml中的片段,它是空的。

如果是这种情况,只需检查布局的文件名,确保它们是唯一的。

希望这可以帮助遇到与我相同问题的任何人。 :)

【讨论】:

【参考方案6】:

这是 android 生活的日常东西,我们正在寻找样品和手册,但它们已经无法正常工作了)

我的问题在于混合“import android.app.Fragment;”使用现代的“androidx.fragment.app.Fragment”。下面是 androidx 的示例

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

            Fragment myFrag = getSupportFragmentManager().findFragmentById(R.id.frgmContainer);
            if(myFrag==null)
                return;
            ((TextView) myFrag.getView().findViewById(R.id.textView))
                    .setText("Access to Fragment 2 from Activity"); 

【讨论】:

以上是关于findFragmentById 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

迁移到 AndroidX 后,findFragmentById 为片段返回 null

Fragment使用findFragmentById返回null

Android findFragmentById 返回 null

SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null

getSupportFragmentManager().findFragmentById 为 android 片段中的谷歌地图返回 null?

Mapfragment findFragmentById 始终为空