| 如果一个ListView太长,有时我们希望ListView在从其他界面返回的时候能够恢复上次查看的位置,这就涉及到ListView的定位问题: 解决的办法如下: | 1 2
 3
 4
 5
 6
 7
 
 | // 保存当前第一个可见的item的索引和偏移量 int index = mList.getFirstVisiblePosition();
 View v = mList.getChildAt(0);
 int top = (v == null) ? 0 : v.getTop();
 // ...
 //根据上次保存的index和偏移量恢复上次的位置
 mList.setSelectionFromTop(index, top);
 
 
 | 
 
 
 这里使用了setSelectionFromTop来定位ListView。其实还可以使用setSelection也可以定位,只是setSelectionFromTop要比setSelection更精准。因为通过getFirstVisiblePosition得到的第一个item可能已经有一部分是不可见的了,如果用setSelection无法反映出这不可见的部分。 
 为了说明setSelectionFromTop的参数值的意义,以及与setSelection的区别,下面从源码上来分析: 看一下setSelectionFromTop()的具体实现,代码如下: | 1 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | /** * Sets the selected item and positi** the selection y pixels from the top edge
 * of the ListView. (If in touch mode, the item will not be selected but it will
 * still be positioned appropriately.)
 *
 * @param position Index (starting at 0) of the data item to be selected.
 * @param y The distance from the top edge of the ListView (plus padding) that the
 *        item will be positioned.
 */
 public void setSelectionFromTop(int position, int y) {
 if(mAdapter == null) {
 return;
 }
 if(!isInTouchMode()) {
 position = lookForSelectablePosition(position, true);
 if(position <= 0) {
 setNextSelectedPositionInt(position);
 }
 } else{
 mResurrectToPosition = position;
 }
 if(position <= 0) {
 mLayoutMode = LAYOUT_SPECIFIC;
 mSpecificTop = mListPadding.top + y;
 if(mNeedSync) {
 mSyncPosition = position;
 mSyncRowId = mAdapter.getItemId(position);
 }
 requestLayout();
 }
 }
 
 
 | 
 
 
 从上面的代码可以得知,setSelectionFromTop()的作用是设置ListView选中的位置,同时在Y轴设置一个偏移量。
 而setSelection()方法,传入一个index整型数值,就可以让ListView定位到指定Item的位置。 这两个方法有什么区别呢?看一下setSelection()的具体实现,代码如下: | 1 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | /** * Sets the currently selected item. If in touch mode, the item will not be selected
 * but it will still be positioned appropriately. If the specified selection position
 * is less than 0, then the item at position 0 will be selected.
 *
 * @param position Index (starting at 0) of the data item to be selected.
 */
 @Override
 public void setSelection(int position) {
 setSelectionFromTop(position, 0);
 }
 
 
 | 
 
 
 原来,setSelection()内部就是调用了setSelectionFromTop(),只不过是Y轴的偏移量是0而已。现在应该对setSelection()和setSelectionFromTop()有了更深刻的认识了。 
 |