Как сохранить состояние фрагмента, имеющего listview
Вот ситуация. Я хочу перейти от фрагмента A- > B- > C.
В B Fragment есть listview. При щелчке элемента открываем подробный фрагмент C Fragment.
Конечно, я использовал метод замены и добавил addtoBackStack (null), в то время как transactiong от B до C, чтобы в Back нажать его, чтобы вернуться в B.
Все идет хорошо. Но когда я возвращаюсь к B из C, представление обновляется, и, следовательно, веб-сервис снова вызывается. Я не хочу этого делать. Я хочу сохранить состояние фрагмента B со списком.
Я получил сообщение о сохранении экземпляра, но это не помогло.
Любая помощь очень ценится.
Спасибо.
Ответы
Ответ 1
Как описано здесь, вы можете использовать onSaveInstanceState() для сохранения данных в Bundle и получения этих данных в методе onRestoreInstanceState().
Часто setRetainState (true) упоминается как способ сохранить состояние ui в фрагменте, но он не работает для вас, потому что вы используете backstack.
Таким образом, для вас может быть полезным сохранить прокрутку в onSaveInstanceState() и восстановить его в onRestoreInstanceState() следующим образом:
public class MyListFragment extends ListFragment {
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
int index = this.getListView().getFirstVisiblePosition();
View v = this.getListView().getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
outState.putInt("index", index);
outState.putInt("top", top);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
[...]
if (savedInstanceState != null) {
// Restore last state for checked position.
index = savedInstanceState.getInt("index", -1);
top = savedInstanceState.getInt("top", 0);
}
if(index!=-1){
this.getListView().setSelectionFromTop(index, top);
}
}
Далее вы можете найти более подробный аналогичный пример здесь.
Ответ 2
Я решил эту проблему, создав свой Adapter on onCreate() вместо onCreateView().
Это потому, что (я думаю) фрагмент, который добавлен в backstack, потерял свой вид, а затем он должен воссоздать представление. onCreateView() вызывается и, кстати, воссоздает ваш адаптер.
Ответ 3
вы можете сохранить свой ui в oncreate.
когда в onCreateView добавьте только макет.
так что состояние представления может сохранить идеальное.
это мой sv:
в oncreate
LayoutInflater inflater = (LayoutInflater)
ctx.getSystemService(ctx.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.pulltorefreshgridview, null);
mPullRefreshGridView = (PullToRefreshGridView) view
.findViewById(R.id.listcate_pullrefresh_gridview);
сильный текст
в onCreateView
if (rootView != null) ((LinearLayout)rootView).removeAllViews();
View v = inflater.inflate(R.layout.listcate_fragment, container, false);
rootView = v;
((LinearLayout) v).addView(mPullRefreshGridView,
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));
Ответ 4
Я думаю, что вы можете сохранить свою позицию ListView непосредственно перед тем, как покинуть фрагмент B.
Возможно, сделайте это в фрагменте B onStop(). И когда вы вернетесь, вы можете получить эту позицию и восстановить ее в ListView, сделайте это, например, в фрагменте B onStart().
Данные позиции могут быть сохранены в Activity, поэтому он не будет потерян даже отделяемым фрагментом.
Следует отметить, что (я был в ловушке этого), если сохраненные данные о местоположении обновлены фоновым сервисом, вы должны избегать восстановления его в ListView до этапа жизненного цикла onStart() фрагмента B, потому что на самом деле структура сохранит состояние представления перед тем, как покинуть фрагмент и восстановить его при возврате. Поэтому, если вы восстановите свою позицию до того, как инфраструктура сделает это, данные восстановления структуры будут переопределять ваши.