android中ListView的定位:使用setSelectionFromTop

TZL818 9年前

 如果一个ListView太长,有时我们希望ListView在从其他界面返回的时候能够恢复上次查看的位置,这就涉及到ListView的定位问题:

解决的办法如下:

// 保存当前第一个可见的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()的具体实现,代码如下:

/**    * Sets the selected item and positions 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()的具体实现,代码如下:

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