Ни одно из предложенных здесь решений, похоже, не работает для меня. В моем случае у меня есть ListView
в Fragment
, который я заменяю в FragmentTransaction
, поэтому каждый раз при показе фрагмента создается новый экземпляр Fragment
, что означает состояние ListView
не может быть сохранен в качестве члена Fragment
.
Вместо этого я в конечном итоге сохранил состояние в своем пользовательском классе Application
. Код ниже должен дать вам представление о том, как это работает:
public class MyApplication extends Application {
public static HashMap<String, Parcelable> parcelableCache = new HashMap<>();
/* ... code omitted for brevity ... */
}
public class MyFragment extends Fragment{
private ListView mListView = null;
private MyAdapter mAdapter = null;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mAdapter = new MyAdapter(getActivity(), null, 0);
mListView = ((ListView) view.findViewById(R.id.myListView));
Parcelable listViewState = MyApplication.parcelableCache.get("my_listview_state");
if( listViewState != null )
mListView.onRestoreInstanceState(listViewState);
}
@Override
public void onPause() {
MyApplication.parcelableCache.put("my_listview_state", mListView.onSaveInstanceState());
super.onPause();
}
/* ... code omitted for brevity ... */
}
Основная идея заключается в том, что вы сохраняете состояние вне экземпляра фрагмента. Если вам не нравится идея иметь статическое поле в классе приложения, я думаю, вы могли бы сделать это, реализовав интерфейс фрагмента и сохранив состояние в вашей активности.
Другим решением было бы сохранить его в SharedPreferences
, но это становится немного сложнее, и вам нужно обязательно очистить его при запуске приложения, если только вы не хотите, чтобы состояние сохранялось при запуске приложения. *
Кроме того, чтобы избежать «позиции прокрутки, которая не сохраняется, когда виден первый элемент», вы можете отобразить фиктивный первый элемент с высотой 0px
. Это может быть достигнуто путем переопределения getView()
в вашем адаптере, например:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if( position == 0 ) {
View zeroHeightView = new View(parent.getContext());
zeroHeightView.setLayoutParams(new ViewGroup.LayoutParams(0, 0));
return zeroHeightView;
}
else
return super.getView(position, convertView, parent);
}