Android入门 在ListView中如何进行精确的定位
来源:互联网 发布:linux安装intel驱动 编辑:程序博客网 时间:2024/06/05 04:46
在android的开发中,经常会遇到需要主动去设定某条ListItem的位置的需求。设置位置的函数有
ListView.setSelection(int position)
ListView.setSelectionFromTop(int position, int y);
其中
position指的是指定的item的在ListView中的索引,注意如果有Header存在的情况下,索引是从Header就开始算的。
y指的是到ListView可见范围内最上边边缘的距离。
函数有了,现在就是根据自身需求来进行设置。
这次遇到的需求,ListView要求是从下往上展示的,并且当Cursor更新时,要保持住原先的最上方的item(不包括header)的位置不变,然后新的历史数据在原先那条item上方继续向上展示。如图:
ListView从下往上展示,也就是
- android:stackFromBottom="true"
那么当Cursor更新时,原先第一条的索引便会发生变化。要想保持住它(图中的 R)的位置。步骤如下:
(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就都有了。
*注解:ListView.getChildAt(int position), 这个position指的是在可视的item中的索引,跟cursor里的位置是大不一样的。可以看看ListView.getChildCount()函数得到个数是小于或等于Cursor里的个数的(不考虑header的话)。虽然一共可能有20条数据,但是界面只能看到8条,那么这个ChildCount大约就是8了。另一方面, FirstVisiblePosition取出的是在总的条数中的索引,再将会消失的header考虑进来,所以就是 FirstVisiblePosition为0时要设为1,大于0时又要设为0。
下面上代码:
调用的代码:
- int headerCount = mListContainer.getListView().getHeaderViewsCount();
- int firstVisiblePos = mListContainer.getListView().getFirstVisiblePosition();
- int newCursorPosition = getPositionInNewCursor(cursor.getCount(), firstVisiblePos);
- int offsetY = getOffsetY(cursor, firstVisiblePos, newCursorPosition);
- mAdapter.changeCursor(cursor);
- mUpRefreshLayout.setVisibility(View.GONE);
- mListContainer.getListView().setSelectionFromTop(newCursorPosition + headerCount, offsetY);
- private int getPositionInNewCursor(int newCursorCount, int firstVisiblePos){
- if(firstVisiblePos == 0){
- firstVisiblePos += 1;
- }
- int headerCount = mListContainer.getListView().getHeaderViewsCount();
- int newCursorPos = newCursorCount - mAdapter.getCount() + firstVisiblePos - headerCount;
- return newCursorPos;
- }
- private int getOffsetY(Cursor cursor, int firstVisiblePos, int newCursorPosition){
- int y;
- View firstVisibleItem = null;
- if(firstVisiblePos == 0){
- firstVisibleItem = mListContainer.getListView().getChildAt(1);
- }else{
- firstVisibleItem = mListContainer.getListView().getChildAt(0);
- }
- y = firstVisibleItem.getTop();
- View timeView = firstVisibleItem.findViewById(R.id.time_text_view);
- if(timeView != null && timeView.getVisibility() == View.VISIBLE){
- Cursor curItem = (Cursor)mAdapter.getItem(newCursorPosition);
- Cursor preItem = (Cursor)mAdapter.getItem(newCursorPosition - 1);
- if(curItem != null || preItem != null){
- long curTimeStamp = curItem.getLong(MessagesProjection.JEDI_CREATE_DATE_INDX);
- long preTimeStamp = preItem.getLong(MessagesProjection.JEDI_CREATE_DATE_INDX);
- if(Math.abs(curTimeStamp - preTimeStamp) <= SHOW_TIME_STAMP_TEN_MINS){
- LayoutParams param = (LinearLayout.LayoutParams)mTimeView.getLayoutParams();
- y += mTimeView.getHeight() + param.topMargin + param.bottomMargin;
- }
- }
- }
- return y;
- }
getOffsetY中有一段计算图中TimeStamp的高度的代码,不关心的可以自己跳过一下。因为查询出历史数据后可能会造成原先有TimeStamp的那一条在刷新后不再显示TimeStamp(与上一条合并到一个时间段了),所以要把它的高度也计算进去。
- Android入门 在ListView中如何进行精确的定位
- Android入门 在ListView中如何进行精确的定位
- Android入门 在ListView中如何进行精确的定位
- Android入门 在ListView中如何进行精确的定位
- Android入门 在ListView中如何进行精确的定位
- Android 在ListView中如何进行精确的定位
- 001_ Android入门 在ListView中如何进行精确的定位
- 在ListView中如何进行精确的定位
- Android ListView中如何进行精确的定位
- Android入门 在ListView中如何进行精确的位置设定
- Android中ListView的定位
- 如何在ArcGIS Engine的Globe中进行三维定位
- iOS 如何在 VPN 中进行定位
- 精确定位及恢复ListView的位置
- 精确定位ListView
- listview 精确定位
- Android如何在ListView中嵌套ListView
- Android如何在ListView中嵌套ListView
- Java程序员应该常思考的问题
- 机器学习&数据挖掘(常见面试之机器学习算法思想简单梳理
- SWT,Swing,AWT及最小公分母问题(LCD)
- Django Web项目代码规范参考
- android手机保持亮的状态
- Android入门 在ListView中如何进行精确的定位
- marquee图片/文字无缝滚动
- OpenGL--双缓冲
- 面试问答—软实时和硬实时操作系统的区别
- Android二维码功能实现,在程序内嵌入ZXing项目
- Python 使用nltk对序列元素(eg. 列表)的频谱计算小结
- 豪情-CSS解构系列之-新浪页面解构-01
- ListView的setSelection()和setSelectionFromTop()联系
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path