Nenhuma das soluções oferecidas aqui parecia funcionar para mim. No meu caso, eu tenho um ListView
em um Fragment
que estou substituindo em um FragmentTransaction
, portanto, uma nova Fragment
instância é criada cada vez que o fragmento é mostrado, o que significa que o ListView
estado não pode ser armazenado como um membro doFragment
.
Em vez disso, acabei armazenando o estado no meu costume Application
classe . O código abaixo deve lhe dar uma idéia de como isso funciona:
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 ... */
}
A ideia básica é que você armazene o estado fora da instância do fragmento. Se você não gosta da ideia de ter um campo estático em sua classe de aplicativo, acho que você poderia fazê-lo implementando uma interface de fragmento e armazenando o estado em sua atividade.
Outra solução seria armazená-lo SharedPreferences
, mas fica um pouco mais complicado, e você deve limpá-lo no início do aplicativo, a menos que queira que o estado persista durante o lançamento de aplicativos.
Além disso, para evitar a "posição de rolagem não salva quando o primeiro item estiver visível", você pode exibir um primeiro item fictício com 0px
altura. Isso pode ser conseguido substituindo getView()
seu adaptador, desta forma:
@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);
}