【问题标题】:findFragmentById return nullfindFragmentById 返回 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_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>

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 名声望,但明天会回答自己。我之前搜索了一下,没有发现与此相关的内容。
  • 我怀疑这可能是问题所在。无论如何你找到它。不错

标签: android android-fragments nullpointerexception


【解决方案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"); 
        

        【讨论】:

          猜你喜欢
          • 2013-06-27
          • 2023-03-03
          • 1970-01-01
          • 1970-01-01
          • 2012-06-05
          • 1970-01-01
          相关资源
          最近更新 更多