转自http://blog.csdn.net/manoel/article/details/39183025


通常,app中的数据都是以ListView的形式展示的。默认地,把“新”数据添加到数据列表的尾部。

但是,如果是IM类型的app,比如查看历史消息这个模块。新数据并不是插到数据列表的尾部,而是插到数据列表的头部。

要实现比较好的用户体验,需要保持当前的ListView的位置。换句话说,如果我们能够随心所欲地指定ListView滚动的位置,那么这个问题就迎刃而解。

在ListView中,有一个setSelectionFromTop()方法,下面是一个使用范例。代码如下:


[java] view plain copy 

  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()的具体实现,代码如下:


[java] view plain copy 

  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()的具体实现,代码如下:


[java] view plain copy 

  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()有了更深刻的认识了。


让ListView回到Header位置或者Footer位置,还有第一项元素位置,这个要是使用

ListView.setSelection(pos);

 

ListView.setSelectionFromTop(0, 0);//回到ListView的header
ListView.setSelectionFromTop(1, 0);//回到第一项元素

回到footer根据具体情况而定,因为header会占一个索引值。

 

 

int postion=ListView.getAdapter().getCount();//有header的情况下
ListView.setSelectionFromTop(postion,0);