android-вызов findFragmentByTag сразу после совершения транзакции

#android #android-fragments #fragmenttransaction

#Android #android-фрагменты #fragmenttransaction

Вопрос:

обычная практика замены фрагмента другим фрагментом:

 getActivity().getSupportFragmentManager()
.beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragment_holder, ItemFragment.newInstance(bundle),"tag")
.addToBackStack(null)
.commit();
 

в документации к commit() методу говорится:

Запланируйте фиксацию этой транзакции. Фиксация происходит не сразу; она будет запланирована как работа над основным потоком, которая будет выполнена в следующий раз, когда этот поток будет готов.

теперь представьте, что я вызываю getActivity.getSupportFragmentManager.findFragmentByTag("tag"); сразу после метода фиксации, упомянутого выше. поскольку фиксация происходит не сразу, возможно ли, что она возвращает значение null?

Комментарии:

1. обновление: я тестировал все больше и больше и, наконец, смог испытать nullPointerException . итак, простой ответ на мой вопрос таков: да, это возможно!

Ответ №1:

Я не думаю, что он может возвращать значение null, если бы это было так, в документации для findFragmentByTag("tag") этого было бы указано.

Кроме того, метод из FragmentManager класса, поэтому все, что его волнует, содержится или нет в диспетчере фрагментов commit() , функция из FragmentTransaction класса, фрагмент может находиться в заднем стеке диспетчера фрагментов, даже если он не зафиксирован, поэтому функция findFragmentByTag("tag") вернет фрагмент и вернет null, только если фрагмент с этот тег никогда не добавлялся в менеджер фрагментов

 getSupportFragmentManager()
   .beginTransaction()
   .setReorderingAllowed(true)
   .replace(R.id.fragment_holder, fragmentB, "tag")
   .addToBackStack(null)
 

приведенный выше код добавляет фрагмент в задний стек диспетчера фрагментов активности хоста, вы можете сделать именно это и найти этот фрагмент в диспетчере фрагментов, фиксация не требуется.

Ответ №2:

Я бы сказал, что это возможно, однако я чувствую, что настоящая проблема здесь заключается в дизайне, который вы используете. Если Фрагменту A необходимо ввести / заменить фрагмент B, то правильная конструкция заключается в том, чтобы позволить Activity обрабатывать управление фрагментами. Фрагменты не должны напрямую добавлять / заменять другие Фрагменты.

Если все это обрабатывается в рамках действия, вы можете легко сохранить ссылку на новый фрагмент, что означает, что вам не нужно findFragmentByTag(«тег»), потому что у вас уже есть ссылка на него при создании / замене.

            Activity
           /      
   Fragment A     Fragment B
 

Фрагмент А и Фрагмент В не должны напрямую влиять друг на друга.

 // In Activity ...
public replaceFragment() {
   Fragment fragmentB = ItemFragment.newInstance(bundle);
    
    getSupportFragmentManager()
       .beginTransaction()
       .setReorderingAllowed(true)
       .replace(R.id.fragment_holder, fragmentB, "tag")
       .addToBackStack(null)
       .commit();

    // You now have fragmentB no need to getSupportFragmentManager.findFragmentByTag("tag")
    fragmentB.doSomething();
 

Комментарии:

1. конечно, я могу сохранить ссылку на вновь созданный фрагмент, но я хочу избежать этого. фрагменты уже управляются и хранятся системой (SupportFragmentManager), поэтому делать сильную ссылку на них — пустая трата памяти.