android ListView定位
来源:互联网 发布:施乐2011设置网络打印 编辑:程序博客网 时间:2024/06/14 15:43
如果一个ListView太长,有时我们希望ListView在从其他界面返回的时候能够恢复上次查看的位置,这就涉及到ListView的定位问题:
smoothScrollToPosition需要2.2以上,smoothScrollByOffset需要3.0以上。smoothScrollToPosition可以实现平滑滚动
解决的办法如下:
// 保存当前第一个可见的item的索引和偏移量
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
// ...
注解:ListView.getChildAt(int position), 这个position指的是在可视的item中的索引,跟cursor里的位置是大不一样的。
可以看看ListView.getChildCount()函数得到个数是小于或等于Cursor里的个数的(不考虑header的话)。
虽然一共可能有20条数据,但是界面只能看到8条,那么这个ChildCount大约就是8了。
另一方面, FirstVisiblePosition取出的是在总的条数中的索引,再将会消失的header考虑进来,所以就是 FirstVisiblePosition为0时要设为1,大于0时又要设为0。
//根据上次保存的index和偏移量恢复上次的位置
mList.setSelectionFromTop(index, top);
为了说明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()有了更深刻的认识了。
其实还可以使用setSelection也可以定位,只是setSelectionFromTop要比setSelection更精准。
因为通过getFirstVisiblePosition得到的第一个item可能已经有一部分是不可见的了,如果用setSelection无法反映出这不可见的部分。
那么当Cursor更新时,原先第一条的索引便会发生变化。要想保持住它的位置。步骤如下:
(1)获取这一条在新Cursor中的位置(posiition)
(2)获取这一条在更换Cursor后ListView中的位置。
(4)由于ListView的可滚动的属性,我们需要记录更换Cursor前可视的第一条item的索引(ListView.getFirstVisiblePosition())
(3)区分FirstVisiblePosition是0和大于0的情况。由于header,也就是图中的Loading那一条在新数据出来后是会消失的。
(4)当FirstVisiblePosition为0时实际指向的是header,我们要保持位置不变的是header下面第一条(R)的位置。那么此时要设置FirstVisiblePosition为1
(5)当FirstVisiblePosition大于0时实际指向的就是item,但是我们需要设置FirstVisiblePosition为0。*
(6)我们根据FirstVisiblePosition用ListView.getChildAt(int position)函数获取对应的item的View,再根据View.getTop()函数获取到ListView顶部的距离Y。
这样ListView.setSelectionFromTop(int position, int y)所需的两个参数 position 和 y就都有了。
- android ListView定位
- Android中ListView的定位
- Android ListView上下选择,定位
- android ListView根据字母排序和定位
- Android UI ListView实现字母索引 定位
- Android ListView 上拉加载 定位问题
- android中ListView的定位:使用setSelectionFromTop
- Android listview 加载更多定位问题
- android中ListView的定位:使用setSelectionFromTop
- android ListView根据字母排序和定位
- android中ListView的定位:使用setSelectionFromTop
- Android ListView 之 Item 定位显示
- ListView定位
- Android入门 在ListView中如何进行精确的定位
- android ListView根据字母排序和定位----支持混合排序
- Android ListView中如何进行精确的定位
- android listview直接定位到某一行位置
- Android入门 在ListView中如何进行精确的定位
- USACO 1.4.2 Mother's Milk
- android ImageView之scaleType属性
- 处理json文件中的数组
- IOS 旋转重构视图的实现
- Sicily 4312. A + B
- android ListView定位
- php 批量去除bom头方法
- Sicily 3712. Matrix multiplication
- jquery的find和filter的区别
- JNI/NDK开发指南(六)——C/C++访问Java实例方法和静态方法
- Eclipse4.4 luna修改jsp中默认的html版本
- SVN更新时不能打开新文件svn-base系统找不到指定的文件
- Sicily 7144. Different Triangles
- 数据结构与算法大全 -- 目录