Жодне із запропонованих тут рішень для мене не здавалося. У моєму випадку, у мене є 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);
}