在快递查中有一个历史记录的列表,针对这个列表有同步跟踪记录、修改、删除等操作,那就避免不了这对这个列表的数据刷新。
每次重新获得数据后,就setAdapter(),这样,列表就回到了顶端,用户体验极差,理想状态是,列表位置不动,只更新数据。解决方案是利用Adapter的notifyDataSetChanged,通知Adapter数据已经更改,然后Adapter会调用getView()方法,重新显示界面。
注意的一点是如果Adapter是自定义的,那么数据要是全局的或者是在自定义Adapter中不能是私有的,因为要重新设置数据,
public class HistoryListViewAdapter extends BaseAdapter {
private List<QueryRecord> mItemList;
private LayoutInflater mInflater;
private Context mContext;
public HistoryListViewAdapter(Context c,List<QueryRecord> itemList) {
mItemList = itemList;
mContext = c;
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setItemList(List list) {
mItemList = list;
}
@Override
public int getCount() {
//
}
@Override
public Object getItem(int position) {
//
}
@Override
public long getItemId(int position) {
//
}
public void removeItem(int position) {
//
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//
}
}
再在数据重新获取后
listitemAdapter.setItemList(list); //重新设置数据
listitemAdapter.notifyDataSetChanged();
这样数据重新刷新,界面刷新。
下面是我走的弯路,因为思维偏了。
一开始我就Google搜索“ListView 滚动 指定位置”,这样整体解决思路是记忆滚动位置,恢复位置,而是有了下面的解决方法:
监听ListView的OnScrollListener
lvHistory.setOnScrollListener(listHistoryScroll);
在onScrollStateChanged中通过getFirstVisiblePosition获取当前可见ListView顶端一行的位置
public int listHistoryPos = 0; //listHistoryPos记录当前可见的List顶端一行的位置
private OnScrollListener listHistoryScroll = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//scrollState有三种状态,分别是开始滚动(SCROLL_STATE_FLING),正在滚动(SCROLL_STATE_TOUCH_SCROLL ), 已经停止(SCROLL_STATE_IDLE )
if(scrollState == OnScrollListener.SCROLL_STATE_IDLE){
listHistoryPos = lvHistory.getFirstVisiblePosition();
}
}
@Override
public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
};
数据重新绑定后通过ListView的setSelection()方法,设回原位
lvHistory.setSelection(listHistoryPos);
这样虽然比每次重回顶端好,但用户体验还不理想,因为不可能要求用户每次都拖动得那么准确。
后来发现ListView还有一个方法是setSelectionFromTop(index,y),而是开始想尽各种方法记录y的值,都不理想,大部分时候都有偏差。setSelection(index)效果等于setSelectionFromTop(index,0),也就是上面为什么说不可能每次拖动都那么准确。
最终还真有“伊人在灯火阑珊处”的感觉。该修正将在快递查2.4版本中更新。