android中ListView的定位:使用setSelectionFromTop

如果一个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 <span id="4_nwp" style="width: auto; height: auto; float: none;"><a id="4_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0924%2F1709%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=item&k0=%B6%A8%CE%BB&kdi0=8&k1=%D4%B4%C2%EB&kdi1=8&k2=touch&kdi2=8&k3=%D5%FB%D0%CD&kdi3=8&k4=top&kdi4=8&k5=item&kdi5=8&sid=d58c89a715216433&ch=0&tu=u1921070&jk=40713c5299f4b88d&cf=29&rb=0&fv=11&stid=9&urlid=0&luki=6&seller_id=1&di=128" target="_blank" mpid="4" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">item</span></a></span> and positions the selection y pixels from the <span id="5_nwp" style="width: auto; height: auto; float: none;"><a id="5_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0924%2F1709%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=top&k0=%B6%A8%CE%BB&kdi0=8&k1=%D4%B4%C2%EB&kdi1=8&k2=touch&kdi2=8&k3=%D5%FB%D0%CD&kdi3=8&k4=top&kdi4=8&k5=item&kdi5=8&sid=d58c89a715216433&ch=0&tu=u1921070&jk=40713c5299f4b88d&cf=29&rb=0&fv=11&stid=9&urlid=0&luki=5&seller_id=1&di=128" target="_blank" mpid="5" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">top</span></a></span> edge
   * of the ListView. (If in <span id="6_nwp" style="width: auto; height: auto; float: none;"><a id="6_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0924%2F1709%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=touch&k0=%B6%A8%CE%BB&kdi0=8&k1=%D4%B4%C2%EB&kdi1=8&k2=touch&kdi2=8&k3=%D5%FB%D0%CD&kdi3=8&k4=top&kdi4=8&k5=item&kdi5=8&sid=d58c89a715216433&ch=0&tu=u1921070&jk=40713c5299f4b88d&cf=29&rb=0&fv=11&stid=9&urlid=0&luki=3&seller_id=1&di=128" target="_blank" mpid="6" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">touch</span></a></span> 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.<span id= "7_nwp" style= "width: auto; height: auto; float: none;" ><a id= "7_nwl" href= "http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0924%2F1709%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=top&k0=%B6%A8%CE%BB&kdi0=8&k1=%D4%B4%C2%EB&kdi1=8&k2=touch&kdi2=8&k3=%D5%FB%D0%CD&kdi3=8&k4=top&kdi4=8&k5=item&kdi5=8&sid=d58c89a715216433&ch=0&tu=u1921070&jk=40713c5299f4b88d&cf=29&rb=0&fv=11&stid=9&urlid=0&luki=5&seller_id=1&di=128" target= "_blank" mpid= "7" style= "text-decoration: none;" ><span style= "color:#0000ff;font-size:14px;width:auto;height:auto;float:none;" >top</span></a></span> + 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 <span id="0_nwp" style="width: auto; height: auto; float: none;"><a id="0_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0924%2F1709%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=item&k0=%B6%A8%CE%BB&kdi0=8&k1=%D4%B4%C2%EB&kdi1=8&k2=touch&kdi2=8&k3=%D5%FB%D0%CD&kdi3=8&k4=top&kdi4=8&k5=item&kdi5=8&sid=d58c89a715216433&ch=0&tu=u1921070&jk=40713c5299f4b88d&cf=29&rb=0&fv=11&stid=9&urlid=0&luki=6&seller_id=1&di=128" target="_blank" mpid="0" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">item</span></a></span>. If in <span id="1_nwp" style="width: auto; height: auto; float: none;"><a id="1_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0924%2F1709%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=touch&k0=%B6%A8%CE%BB&kdi0=8&k1=%D4%B4%C2%EB&kdi1=8&k2=touch&kdi2=8&k3=%D5%FB%D0%CD&kdi3=8&k4=top&kdi4=8&k5=item&kdi5=8&sid=d58c89a715216433&ch=0&tu=u1921070&jk=40713c5299f4b88d&cf=29&rb=0&fv=11&stid=9&urlid=0&luki=3&seller_id=1&di=128" target="_blank" mpid="1" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">touch</span></a></span> 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()有了更深刻的认识了。

你可能感兴趣的:(android中ListView的定位:使用setSelectionFromTop)