通常,app中的数据都是以ListView的形式展示的。默认地,把“新”数据添加到数据列表的尾部。
但是,如果是IM类型的app,比如查看历史消息这个模块。新数据并不是插到数据列表的尾部,而是插到数据列表的头部。
要实现比较好的用户体验,需要保持当前的ListView的位置。换句话说,如果我们能够随心所欲地指定ListView滚动的位置,那么这个问题就迎刃而解。
在ListView中,有一个setSelectionFromTop()方法,下面是一个使用范例。代码如下:
1 @Override 2 public void loaded(Long loadTime, int thisPageNumber, boolean isFromZero, boolean isHasMoreToLoad, List data) { 3 refreshComplete(); 4 checkIfHasMoreToLoad(isHasMoreToLoad); 5 6 if (thisPageNumber != 1) {// 不是第一页 7 mListView.setSelectionFromTop(5+2, mIMPullToRefreshListView.getHeaderHeight()); 8 mIMPullToRefreshListView.getHeaderView().setVisibility(View.GONE); 9 } 10 }
看一下setSelectionFromTop()的具体实现,代码如下:
1 /** 2 * Sets the selected item and positions the selection y pixels from the top edge 3 * of the ListView. (If in touch mode, the item will not be selected but it will 4 * still be positioned appropriately.) 5 * 6 * @param position Index (starting at 0) of the data item to be selected. 7 * @param y The distance from the top edge of the ListView (plus padding) that the 8 * item will be positioned. 9 */ 10 public void setSelectionFromTop(int position, int y) { 11 if (mAdapter == null) { 12 return; 13 } 14 15 if (!isInTouchMode()) { 16 position = lookForSelectablePosition(position, true); 17 if (position >= 0) { 18 setNextSelectedPositionInt(position); 19 } 20 } else { 21 mResurrectToPosition = position; 22 } 23 24 if (position >= 0) { 25 mLayoutMode = LAYOUT_SPECIFIC; 26 mSpecificTop = mListPadding.top + y; 27 28 if (mNeedSync) { 29 mSyncPosition = position; 30 mSyncRowId = mAdapter.getItemId(position); 31 } 32 33 requestLayout(); 34 } 35 }
从上面的代码可以得知,setSelectionFromTop()的作用是设置ListView选中的位置,同时在Y轴设置一个偏移量(padding值)。
ListView还有一个方法叫setSelection(),传入一个index整型数值,就可以让ListView定位到指定Item的位置。
这两个方法有什么区别呢?看一下setSelection()的具体实现,代码如下:
1 /** 2 * Sets the currently selected item. If in touch mode, the item will not be selected 3 * but it will still be positioned appropriately. If the specified selection position 4 * is less than 0, then the item at position 0 will be selected. 5 * 6 * @param position Index (starting at 0) of the data item to be selected. 7 */ 8 @Override 9 public void setSelection(int position) { 10 setSelectionFromTop(position, 0); 11 }
原来,setSelection()内部就是调用了setSelectionFromTop(),只不过是Y轴的偏移量是0而已。现在应该对setSelection()和setSelectionFromTop()有了更深刻的认识了。
转载于:https://www.cnblogs.com/wangying222/p/5293403.html
