#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), поэтому делать сильную ссылку на них — пустая трата памяти.