当我用我的片段的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);
时,我得到了空,但当我打电话给fm.findFragmentById(R.id.main_fragment);
时,我得到了片段。
答案 0 :(得分:82)
答案Kar0t完全没问题,但这可能有助于某人。在我的情况下,我在片段内部有一个片段,我得到了错误的FragmentManager。我只需要打电话:
getChildFragmentManager()
然后像往常一样找到片段:
fm.findFragmentById(R.id.fragment)
答案 1 :(得分:33)
刚刚发现我的错误。
在我的MainActivity.java中,我导入了android.support.v4.app.Fragment;
,在我的LoginFragment.java中导入了android.app.Fragment;
。我把它改成了同样的东西,fm.findFragmentById(R.id.login_fragment)
现在返回正确的片段。
答案 2 :(得分:4)
与特定问题并不完全相关,但与在null
上接收findFragmentById
有关,如果在提交后立即调用findFragmentById
,它将返回null或最后一个片段(在提交之前),原因是因为commit会执行异步请求。
来自文档:
计划此事务的提交。提交不会发生 立即;它将被安排为主线程上的工作 下次线程准备就绪时完成。
如果您需要立即findFragmentById
,例如在添加片段后更改状态栏文本颜色,请在executePendingTransactions()
之后调用commit()
getSupportFragmentManager().executePendingTransactions();
//call findFragmentById
答案 3 :(得分:1)
我遇到了此问题,因为我的项目具有两个具有相同文件名的布局。例如。就您而言,我在不同的模块中有两个activity_main.xml
。
所以以某种方式编译它以及在您运行时
fm.findFragmentById(R.id.login_fragment)
然后它正在另一个activity_main.xml
中查找该片段,该片段为空。
在这种情况下,只需检查布局的文件名,确保它们是唯一的即可。
希望这对与我有相同问题的所有人有所帮助。 :)
答案 4 :(得分:0)
我也遇到了问题,因为我身处儿童碎片中。我可以使用:
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 :(得分:0)
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");