android中ListView的定位:使用setSelectionFromTop

若是一個ListView太長,有時咱們但願ListView在從其餘界面返回的時候可以恢復上次查看的位置,這就涉及到ListView的定位問題: app

解決的辦法以下: less

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沒法反映出這不可見的部分。 ide


爲了說明setSelectionFromTop的參數值的意義,以及與setSelection的區別,下面從源碼上來分析: spa

看一下setSelectionFromTop()的具體實現,代碼以下: .net

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 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的位置。 ci

這兩個方法有什麼區別呢?看一下setSelection()的具體實現,代碼以下: get

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()有了更深入的認識了。 源碼

相關文章
相關標籤/搜索