如何在返回ListView时恢复跳转至其他Activity前的滚动位置?
解决ListView跳转Activity返回后回到顶部的问题
我之前也碰到过完全一样的坑!你的思路方向是对的,但问题出在保存和恢复滚动状态的时机、方式不对,我来给你理清楚:
为什么你原来的方法没用?
你在onCreate里直接调用mListView.getFirstVisiblePosition()的时候,ListView还没完成数据绑定和绘制,拿到的position其实是默认的0,自然setSelection(0)会回到顶部。而且只保存firstVisiblePosition也不够——如果某个列表项只显示了一半,恢复时没法还原这个偏移量,体验也不好。
正确的解决方案:用系统自带的状态保存/恢复方法
Android的AbsListView(ListView的父类)已经封装了完整的滚动状态保存逻辑,不用我们手动去存position和偏移量,直接用下面的步骤:
- 保存滚动状态
在你的Activity里重写onSaveInstanceState,把ListView的状态存进Bundle:
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存ListView的完整滚动状态 outState.putParcelable("listViewScrollState", mListView.onSaveInstanceState()); }
- 恢复滚动状态
要确保在设置适配器并且数据加载完成后再恢复状态,不然ListView没有数据,恢复操作无效。推荐在onCreate里处理:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); mListView = findViewById(R.id.your_list_view); mAdapter = new YourCustomAdapter(this, yourDataList); mListView.setAdapter(mAdapter); // 只有当savedInstanceState不为空(即之前保存过状态)时才恢复 if (savedInstanceState != null) { Parcelable scrollState = savedInstanceState.getParcelable("listViewScrollState"); mListView.onRestoreInstanceState(scrollState); } }
额外注意:异步加载数据的情况
如果你的列表数据是异步获取的(比如从网络拉取),那要等数据加载完成、适配器更新后再恢复状态,不然会因为ListView没有数据而失效。比如在数据回调里处理:
// 假设这是你的数据加载完成回调方法 private void onDataLoaded(List<YourDataModel> loadedData) { mAdapter.updateData(loadedData); // 更新适配器数据 mAdapter.notifyDataSetChanged(); // 数据就绪后恢复滚动状态 if (savedInstanceState != null) { Parcelable scrollState = savedInstanceState.getParcelable("listViewScrollState"); mListView.onRestoreInstanceState(scrollState); } }
这样操作后,你跳转Activity再返回,ListView就会精准回到之前浏览的位置啦!
内容的提问来源于stack exchange,提问作者Gastón Saillán
相关产品推荐
相关产品推荐

