FindFragmentById возвращает null
Когда я вызываю 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);
, я получаю фрагмент.
Ответы
Ответ 1
только что узнал мою ошибку.
В моем MainActivity.java я импортировал android.support.v4.app.Fragment;
, а в моем LoginFragment.java я импортировал android.app.Fragment;
. Я изменил его на одно и то же, и fm.findFragmentById(R.id.login_fragment)
теперь вернет правый фрагмент.
Ответ 2
Ответ Kar0t отлично, но это может помочь кому-то. В моем случае у меня был фрагмент внутри фрагмента, и я получал неправильный FragmentManager. Мне просто нужно было позвонить:
getChildFragmentManager()
а затем просто найдите фрагмент, как обычно:
fm.findFragmentById(R.id.fragment)
Ответ 3
На самом деле не имеет отношения к конкретному вопросу, но относится к получению null
в findFragmentById
, если вы вызываете findFragmentById
сразу после коммита, он возвращает findFragmentById
или последний фрагмент (перед коммитом), причина в том, что при коммите выполняется асинхронный запрос.
Из документов:
Планирует фиксацию этой транзакции. Фиксация не происходит сразу; это будет запланировано как работа над основным потоком, которая будет сделана в следующий раз, когда поток будет готов.
Если вам нужно немедленно findFragmentById
, например, изменить цвет текста строки состояния после добавления фрагмента, вызовите executePendingTransactions()
после commit()
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
}