Как сохранить фрагмент данных после backstack транзакций?
у меня есть действие, содержащее фрагмент "list", который при нажатии на один из его элементов заменит себя на фрагмент "content". Когда пользователь использует кнопку "назад", он снова возвращается к фрагменту "список".
Проблема в том, что фрагмент находится в состоянии по умолчанию, независимо от того, что я пытаюсь сохранить данные.
факты:
- оба фрагмента создаются через
public static TheFragment newInstance(Bundle args)
,setArguments(args)
иBundle args = getArguments()
- оба фрагмента находятся на же уровне, который находится непосредственно внутри
FrameLayout
из родительского действия (то есть не вложенных фрагментов) - я не хочу называть
setRetainInstance
, потому что моя деятельность-это поток master/detail, который имеет макет панели 2 на больших экранах. 7 " таблетки имеют 1 панель в портрете и 2 панели в ландшафте. Если я сохраню экземпляр фрагмента "list", он (я думаю) испортит все с вращениями экрана - когда пользователи щелкают элемент во фрагменте "список", фрагмент " содержимое отображается через
FragmentTransaction#replace(int, Fragment, String)
, С тем же идентификатором, но с другим тегом - я переопределил
onSaveInstanceState(Bundle)
, но это не всегда вызывается фреймворком, как в формате doc: " есть много ситуаций, когда фрагмент может быть в основном снесен (например, когда он помещен в задний стек без отображения пользовательского интерфейса), но его состояние не будет сохранено до тех пор, пока его собственная активность фактически не должна сохранить свое состояние." - я использую поддержку библиотека
из пули 5 выше, я думаю, что устройства низкого класса, которые должны восстановить память после транзакции фрагмента, могут вызвать Fragment#onSaveInstanceState(Bundle)
. Однако на моих тестовых устройствах (Galaxy Nexus и Nexus 7) платформа не вызывает этот метод. Так что это недопустимый вариант.
Итак, как я могу сохранить некоторые данные фрагмент? пакет передан Fragment#onCreate
, Fragment#onActivityCreated
, etc. всегда null
.
следовательно, я не могу сделать разницу с новым запуск фрагмента для восстановления заднего стека.
Примечание: возможно обзоры/дублирую вопрос
1 ответов
это не кажется правильным, но вот как я делал:
public class MyActivity extends FragmentActivity {
private Bundle mMainFragmentArgs;
public void saveMainFragmentState(Bundle args) {
mMainFragmentArgs = args;
}
public Bundle getSavedMainFragmentState() {
return mMainFragmentArgs;
}
// ...
}
и в главном фрагмент:
public class MainFragment extends Fragment {
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = ((MyActivity) getActivity()).getSavedMainFragmentState();
if (args != null) {
// Restore from backstack
} else if (savedInstanceState != null) {
// Restore from saved instance state
} else {
// Create from fragment arguments
args = getArguments();
}
// ...
}
// ...
@Override
public void onDestroyView() {
super.onDestroyView();
Bundle args = new Bundle();
saveInstance(args);
((MyActivity) getActivity()).saveMainFragmentState(args);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveInstance(outState);
}
private void saveInstance(Bundle data) {
// put data into bundle
}
}
это работает!
- если вернуться из backstack, фрагмент использует параметры, сохраненные в
onDestroyView
- если вернуться из другого приложения / процесса / из памяти, фрагмент восстанавливается из
onSaveInstanceState
- при первом создании фрагмент использует параметры, заданные в
setArguments
все события освещаются, и самая свежая информация всегда хранится.
это на самом деле сложнее, это interface
- на основе, слушатель не зарегистрирован из onAttach
/onDetach
. Но принципы те же.