Żadne z zaproponowanych tutaj rozwiązań nie działało dla mnie. W moim przypadku mam ListView
w a, Fragment
które zastępuję w FragmentTransaction
, więc nowa Fragment
instancja jest tworzona za każdym razem, gdy fragment jest wyświetlany, co oznacza, że ListView
stanu nie można zapisać jako członkaFragment
.
Zamiast tego zapisałem stan w mojej Application
klasie niestandardowej . Poniższy kod powinien dać ci wyobrażenie o tym, jak to działa:
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 ... */
}
Podstawową ideą jest przechowywanie stanu poza instancją fragmentu. Jeśli nie podoba ci się pomysł posiadania pola statycznego w klasie aplikacji, myślę, że możesz to zrobić, implementując interfejs fragmentu i zapisując stan w swojej aktywności.
Innym rozwiązaniem byłoby przechowywanie go SharedPreferences
, ale staje się to nieco bardziej skomplikowane i musisz upewnić się, że wyczyściłeś go podczas uruchamiania aplikacji, chyba że chcesz, aby stan był utrzymywany podczas uruchamiania aplikacji.
Ponadto, aby uniknąć „pozycji przewijania, która nie została zapisana, gdy widoczny jest pierwszy element”, można wyświetlić atrapę pierwszego elementu o 0px
wysokości. Można to osiągnąć, zastępując getView()
adapter w następujący sposób:
@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);
}