Подтвердить что ты не робот

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);, я получаю фрагмент.

4b9b3361

Ответ 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
   }