在更改其适配器数据时,我在保留列表视图的滚动位置时遇到了一些麻烦。
我目前正在做的是在ListFragment的onCreate
中创建一个自定义ArrayAdapter(带有重写的getView方法),然后将其分配给它的列表:
mListAdapter = new CustomListAdapter(getActivity());
mListAdapter.setNotifyOnChange(false);
setListAdapter(mListAdapter);
然后,当我从一个定期获取所有内容的加载器接收到新数据时,我会在其onLoadFinished
回调中执行此操作:
mListAdapter.clear();
mListAdapter.addAll(data.items);
mListAdapter.notifyDataSetChanged();
问题是,调用clear()
会重置listview的滚动位置。删除该调用会保留该位置,但显然会将旧项留在列表中。
这样做的正确方法是什么?
答案 0 :(得分:34)
正如你自己指出的那样,对'clear()'的调用导致该位置被重置为顶部。
摆弄滚动位置等是让这个工作变得有点蠢蠢的。
如果您的CustomListAdapter是ArrayAdapter的子类,则可能是问题:
对clear()的调用,调用'notifyDataSetChanged()'。你可以阻止这个:
mListAdapter.setNotifyOnChange(false); // Prevents 'clear()' from clearing/resetting the listview
mListAdapter.clear();
mListAdapter.addAll(data.items);
// note that a call to notifyDataSetChanged() implicitly sets the setNotifyOnChange back to 'true'!
// That's why the call 'setNotifyOnChange(false) should be called first every time (see call before 'clear()').
mListAdapter.notifyDataSetChanged();
我自己没试过,但试试吧:)。
答案 1 :(得分:6)
退房:Maintain/Save/Restore scroll position when returning to a ListView
在调用.clear(),. addAll()和之前,使用此命令保存ListView中的位置。 notifyDataSetChanged()。
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
更新ListView适配器后,Listview的项目将被更改,然后设置新位置:
mList.setSelectionFromTop(index, top);
基本上,您可以保存位置并向后滚动,保存ListView状态或整个应用程序状态。
其他有用的链接:
保存位置: How to save and restore ListView position in Android
保存状态: Android ListView y position
此致
请告诉我这是否有帮助!
答案 2 :(得分:0)
我最近遇到了另一个用例(Android 8.1)-由Android代码中的错误引起。如果我使用滚轮滚动列表视图-连续的adapter.notifyDataSetChanged()
会将滚动位置重置为零。使用此替代方法,直到在Android中修复错误为止
listView.onTouchModeChanged(true); // workaround
adapter.notifyDataSetChanged();
更多详细信息在这里:https://issuetracker.google.com/u/1/issues/130103876
答案 3 :(得分:-1)
在您的可扩充/列表适配器中,输入此方法
public void refresh(List<MyDataClass> dataList) {
mDataList.clear();
mDataList.addAll(events);
notifyDataSetChanged();
}
根据您要更新列表的活动,请输入此代码
if (mDataListView.getAdapter() == null) {
MyDataAdapter myDataAdapter = new MyDataAdapter(mContext, dataList);
mDataListView.setAdapter(myDataAdapter);
} else {
((MyDataAdapter)mDataListView.getAdapter()).refresh(dataList);
}
如果是可扩展列表视图,您将使用 mDataListView.getExpandableListAdapter()而不是 的 mDataListView.getAdapter()强>