Обновление для постоянных фрагментов

avatar
Mohamed Nagy Mostafa
8 апреля 2018 в 09:16
54
1
0

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

Теперь, когда я попытался сделать свой планшет с поддержкой приложений, я заставил одновременно отображаться 3 фрагмента, но произошло что-то странное.

Скажите, что фрагмент A содержит список элементов, а фрагмент B показывает детали выбранного элемента. и во фрагменте B есть объект. Этот объект содержит идентификатор выбранного элемента [Все фрагменты отображаются одновременно в одном действии, как я упоминал ранее], этот объект сохраняет текущее значение идентификатора элемента при создании фрагмента B и сохраняет новый выбранный идентификатор элемента, когда метод onDestroyView() вызывается во фрагменте B.

Теперь, когда я запускаю свое приложение, я добавляю фрагмент A, а когда я выбираю элемент из списка, добавляется фрагмент B, и его объект содержит выбранное значение. на данный момент все в порядке. когда я выбираю другой элемент, мне просто нужно обновить фрагмент B, так как внутренний объект будет содержать новый выбранный идентификатор, поэтому я сделал эту строку

 Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
 mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();

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

Я пытался протестировать внутренний объект перед обновлением фрагмента

 Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
 Log.e("my object","value" + String.valueOf(fragment.getValue));
 mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();

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

 Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
 mFragmentManager.beginTransaction().detach(fragment).attach(FRAGMENT).commit();

Так что же случилось?? По логике должно работать так, как я думаю.

pic для исходного кода и это результат журнала (Примечание: 2 — следующий элемент, который я выбрал) и это следующий результат журнала после обновления фрагмента B (обратите внимание, что этот журнал находится внутри фрагмента B, а идентификатор 3 — это первый элемент, который я выбрал) ожидаемый результат равен 2

Источник

Ответы (1)

avatar
Mohamed Nagy Mostafa
10 апреля 2018 в 00:15
0

Наконец-то я понял поведение транзакции фрагмента и то, как она работает...

После того, как вы добавите/замените новый фрагмент в Fragment Transaction, ваш объект будет сохранен как начальное состояние в пределах Fragment Manager, и когда вы попытаетесь отсоединить фрагмент и повторно присоединить [тот же объект], Fragment Manager получит состояние объекта, которое вы передали его ранее функции add()/replace(). Вот почему я получил результат.

Чтобы упростить его.

  • Предположим, что у вас есть класс A, наследуемый от класса Fragment, и этот класс содержит объект Integer, не имеющий значения и имеющий методы Set()/Get().Get().Get()

  • Теперь создайте экземпляр этого класса A, вызовите функцию Set() и передайте ей значение 1. Затем передайте этот экземпляр в Manager Transaction методом add()/replace()`.

  • Теперь попробуйте вызвать функцию Set() и изменить объект Integer на другое значение.

  • Отсоедините класс A, снова присоедините его и проверьте значение этого объекта, вы получите, что значение объекта возвращается к исходному значению, которое вы присвоили перед передачей объекта Manger Transaction

Кроме того, есть важное примечание... Fragment Transaction Такие действия, как add(), replace(), remove() ..., не работают в основном потоке, и по этой причине используется метод <8962701005>415> и <18062415> .. потому что, когда вы используете commit(), ваше действие будет добавлено в очередь Fragment Transaction, поэтому оно будет выполнено через некоторое время, но не сейчас, по его порядку внутри очереди, и поэтому у вас есть другой метод с именем commitNow() чтобы ваше действие выполнялось немедленно.