如果一个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
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
@Override
public
void setSelection(int position) {
setSelectionFromTop(position,
0);
}
原来,setSelection()内部就是调用了setSelectionFromTop(),只不过是Y轴的偏移量是0而已。现在应该对setSelection()和setSelectionFromTop()有了更深刻的认识了。