Лучшая практика для обновления аргументов фрагмента?

Я знаю о «newInstance» -Pattern ( Лучшая практика для создания экземпляра нового Android-фрагмента ). Но как я могу обновить эти аргументы фрагмента, например, если другой фрагмент изменяет данные?

Я знаю о методах обратного вызова между Fragments / Activitys, но эти обратные вызовы не будут обновлять аргументы ?!

Например: при создании фрагмента я передаю ему URI с пакетом. Затем другой фрагмент изменяет этот URI посредством обратного вызова метода changeUri (Uri uri) для первого фрагмента. Если затем фрагмент будет восстановлен (например, из-за поворота экрана), он будет использовать первый URI из набора аргументов вместо более позднего обновления uri, правильно?

Какова наилучшая практика для решения этой проблемы? Должен ли я вручную сохранить его в файле savedInstanceState, а при использовании решить, использовать ли instanceState или arguments-bundle?

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

private Uri arg1; public static Fragment newInstance(Uri arg1) { create bundle create fragment instance set bundle to fragment return fragment } private void onCreate(Bundle savedInstance) { if(savedInstance != null) { arg1 = savedInstance.uri } } private Uri getUri() { if(arg1 == null) { arg1 = getArguments.uri } if(arg1 == null) { arg1 = defaultValue } } 

Поэтому у меня есть простой способ доступа к моим аргументам. И не нужно использовать if-else-hassle, каждый раз, когда мне нужен этот аргумент.

Что вы думаете об этом?

Solutions Collecting From Web of "Лучшая практика для обновления аргументов фрагмента?"

Вы не можете изменять аргументы, когда его набор и Fragment добавлены в Activity , я использовал аналогичный подход, который вы определили сами. Я сначала проверил Bundle переданный onCreate() если его не null, я его использую, но если его null, то я использую аргументы. И я сохраняю все новейшие данные в onSaveInstanceState() . Для более подробной информации: возможно ли передать аргументы фрагменту после его добавления в действие?

Вы сохраняете состояние так же, как и для операций в обратном вызове onSaveInstanceState в фрагменте. Если вы обновили URI с момента последнего onCreate() , вы сохранили бы обновленный URI в Bundle и получили бы это обратно в onCreate() . Сохранение состояния – это именно то, для чего это предназначено, и, изменив URI, все, что вы сделали, изменилось.

Я просто изменяю значение в пакете Пример:

 synchronized (fragment.getArguments()) { fragment.getArguments().putInt(KEY, new Value); } 

И обновить контент с помощью нового аргумента

Best practice for updating arguments of a fragment : зачем нам добавлять аргумент NewInstance() и почему это лучший метод для фрагмента?

Фрагмент можно рассматривать как модульный раздел активности. Это означает, что когда мы создаем фрагмент, нам нужно сделать его модульным и независимым.

Предположим, вам нужен фрагмент, которому нужен аргумент для работы. Мы также можем его написать

 MyFragmentClass mFrag = new MyFragmentClass(); Bundle bundle = new Bundle(); bundle.putString("key", value); mFrag.setArguments(bundle); 

Он также отлично работает, и вы можете получить аргумент метода onCreate . Вот в чем разница, что вы также можете сделать экземпляр фрагмента без аргумента и добавить его в диспетчер фрагментов, но ваш фрагмент нуждается в аргументе для работы. Добавление метода newInstance в фрагменте заставляет разработчика добавлять аргумент при создании. Вот почему в нем упоминаются лучшие практики.

В вашей проблеме вы можете использовать setRetainInstance(boolean retain) которые предотвращают уничтожение вашего фрагмента при уничтожении активности.

В зависимости от того, как вы используете свои фрагменты, вы можете определить, насколько эффективна эта стратегия.

Например, если у вас есть много фрагментов в общем шаблоне пэга tab / view и управляют ими с помощью FragmentStatePagerAdapter, может быть возможность для вашей активности или других фрагментов ссылаться на экземпляр фрагмента, который больше не существует, за исключением исключения с нулевым указателем.

Способ, которым вы могли бы обойти это, если вы не хотите писать обратные вызовы, заключается в использовании Intents и BroadcastReceivers (что может быть немного переборщиком и трудно справиться, но если все сделано правильно, вы можете сэкономить много головной боли в моем опыте) Отправлять и получать трансляции в родительскую деятельность и обратно.

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

Если вы хотите повторно использовать фрагмент, но вам нужно обновить аргументы, вам нужно использовать функцию frag.getArguments (). PutAll (bundle);

  private static void setInspireByDoArguments(DoOptionsFragment fragment, long doId) { Bundle bundle = new Bundle(); bundle.putLong(Constants.EXTRA_DO_ID, doId); bundle.putInt(Constants.EXTRA_DO_OPTIONS_DIALOG_MODE, MODE_GET_INSPIRE_BY_DO); if (fragment.getArguments() != null) { fragment.getArguments().putAll(bundle); } else fragment.setArguments(bundle); } //This is how I managed to Check if the fragment exist and update the arguments. public static void showDoInspireDialog(FragmentManager fragmentManager, long doId, DoOptionsFragment.DoOptionCallBack callBack) { DoOptionsFragment doOptionsFragment = (DoOptionsFragment) fragmentManager.findFragmentByTag("do_options_fragment"); if (doOptionsFragment == null) { doOptionsFragment = DoOptionsFragment.getInspiredByDoInstance(doId, callBack); fragmentManager.beginTransaction() .add(doOptionsFragment, "do_options_fragment") .commit(); } else { doOptionsFragment.setCallBack(callBack); setInspireByDoArguments(doOptionsFragment, doId); doOptionsFragment.showInspireByDoDialog(doId); } } public static DoOptionsFragment getInspiredByDoInstance(long doId, DoOptionsFragment.DoOptionCallBack callBack) { DoOptionsFragment doOptionsFragment = new DoOptionsFragment(); setInspireByDoArguments(doOptionsFragment, doId); doOptionsFragment.setCallBack(callBack); return doOptionsFragment; }