精确定位ListView

AutoIT v3 Window Info工具详解:精准定位Windows控件坐标的5个技巧 本文详细解析了AutoIT v3 Window Info工具在Windows控件坐标定位中的5个高级技巧,包括动态元素定位、多标签页控制、高DPI环境修正等。通过实战代码示例和策略分析,帮助开发者提升自动化测试和Windows应用开发的精准度和效率,特别适合需要处理复杂UI场景的专业人士。 阅读详情

在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从下往上展示,也就是

[java]   view plain copy
  1. android:stackFromBottom="true"  
但是发现这一属性的设置不会影响索引的排序顺序,也就是item的索引都是从上往下递增的,不会变成从下往上递增。索引为0的item,都是在ListView的最上方的item(或header).

那么当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。

下面上代码:

调用的代码:

[java]   view plain copy
  1. int headerCount = mListContainer.getListView().getHeaderViewsCount();  
  2. int firstVisiblePos = mListContainer.getListView().getFirstVisiblePosition();  
  3. int newCursorPosition = getPositionInNewCursor(cursor.getCount(), firstVisiblePos);  
  4. int offsetY = getOffsetY(cursor, firstVisiblePos, newCursorPosition);  
  5.   
  6. mAdapter.changeCursor(cursor);  
  7.   
  8. mUpRefreshLayout.setVisibility(View.GONE);  
  9.         
  10. mListContainer.getListView().setSelectionFromTop(newCursorPosition + headerCount, offsetY);  
getPositionInNewCursor函数:
[java]   view plain copy
  1. private int getPositionInNewCursor(int newCursorCount, int firstVisiblePos){  
  2.     if(firstVisiblePos == 0){  
  3.         firstVisiblePos += 1;  
  4.     }  
  5.   
  6.     int headerCount = mListContainer.getListView().getHeaderViewsCount();  
  7.     int newCursorPos = newCursorCount - mAdapter.getCount() + firstVisiblePos - headerCount;  
  8.       
  9.     return newCursorPos;  
  10. }  
getOffsetY函数:
[java]   view plain copy
  1. private int getOffsetY(Cursor cursor, int firstVisiblePos, int newCursorPosition){  
  2.         int y;  
  3.           
  4.         View firstVisibleItem = null;  
  5.         if(firstVisiblePos == 0){  
  6.             firstVisibleItem = mListContainer.getListView().getChildAt(1);  
  7.         }else{  
  8.             firstVisibleItem = mListContainer.getListView().getChildAt(0);  
  9.         }  
  10.         y = firstVisibleItem.getTop();  
  11.   
  12.         View timeView = firstVisibleItem.findViewById(R.id.time_text_view);  
  13.         if(timeView != null && timeView.getVisibility() == View.VISIBLE){  
  14.   
  15.             Cursor curItem = (Cursor)mAdapter.getItem(newCursorPosition);  
  16.             Cursor preItem = (Cursor)mAdapter.getItem(newCursorPosition - 1);  
  17.             if(curItem != null || preItem != null){  
  18.                 long curTimeStamp = curItem.getLong(MessagesProjection.JEDI_CREATE_DATE_INDX);  
  19.                 long preTimeStamp = preItem.getLong(MessagesProjection.JEDI_CREATE_DATE_INDX);  
  20.                   
  21.                 if(Math.abs(curTimeStamp - preTimeStamp) <= SHOW_TIME_STAMP_TEN_MINS){  
  22.                     LayoutParams param = (LinearLayout.LayoutParams)mTimeView.getLayoutParams();  
  23.                     y += mTimeView.getHeight() + param.topMargin + param.bottomMargin;  
  24.                 }  
  25.             }  
  26.         }  
  27.           
  28.         return y;  
  29.     }  

getOffsetY中有一段计算图中TimeStamp的高度的代码,不关心的可以自己跳过一下。因为查询出历史数据后可能会造成原先有TimeStamp的那一条在刷新后不再显示TimeStamp(与上一条合并到一个时间段了),所以要把它的高度也计算进去。
Flutter自定义时间线的艺术与实现 本文介绍了如何在Flutter中创建自定义时间线组件。时间线常用于展示事件流程,但标准组件可能无法满足设计需求。文章首先分析初始实现使用IntrinsicHeight的性能问题,然后提出优化方案:采用Stack和ListView重构布局,将垂直线与时间节点分离,通过Positioned精确定位垂直线,ListView.builder动态生成节点内容。优化后的方案不仅提升了性能,还增强了UI灵活性,展示了Flutter强大的自定义能力。该实现方法为开发复杂UI组件提供了实用参考。 阅读详情

相关推荐

ControlGetText

从控件中读取文本。

李家小院 50

Android入门 在ListView中如何进行精确的定位

在android的开发中,经常会遇到需要主动去设定某条ListItem的位置的需求。设置位置的函数有 ListView.setSelection(int position) ListView.setSelectionFromTop(int position, int y); 其中 position指的是指定的item的在ListView中的索引,注意如果有Header存在的情况下,索引是从

lilybaobei的专栏 3万+

Android应用开发从零到一:基于Kotlin与Jetpack Compose的完整实践指南

移动应用开发的核心在于构建一个架构清晰、可维护且可扩展的应用基础。理解应用架构的原理,如关注点分离和数据驱动UI,是实现高质量应用的关键技术价值。在现代Android开发中,Kotlin语言凭借其空安全特性和协程,能有效提升代码的健壮性与开发效率。Jetpack Compose作为声明式UI框架,代表了UI开发的未来方向,与Kotlin协程深度集成,简化了复杂交互界面的构建。这些技术共同服务于个人任务管理、企业工具等多种应用场景。本文以构建一个完整的个人任务管理应用为例,系统阐述从环境搭建、UI构建、数据持

weixin_32667955的博客 313

商品搜索跳转显示引出的setSelection()和setSelectionFromTop()的区别

项目有一个需求,搜索页面搜索商品进入商品界面,对所搜商品的类别和商品都要做一个标示,一开始是用setSelection()直接来定位ListView的,但是因为商品顶部会有一个类别,往往会导致商品显示不全,所以就用到了setSelectionFromTop();看一下setSelectionFromTop()的具体实现,代码如下:public void setSelectionFromTop(int

qingdaohaoyunpeng的专栏 1549

PyCharm配置WSL开发环境保姆级教程:从安装Conda到项目依赖一键搞定

本文提供PyCharm配置WSL开发环境的完整教程,涵盖从安装Conda到项目依赖管理的全流程。详细介绍了WSL2环境准备、Conda环境配置、PyCharm远程解释器设置等关键步骤,并包含实用技巧和常见问题解决方案,帮助开发者高效搭建Python开发环境。

weixin_42620202的博客 309

Stable-Baselines3性能优化:多环境训练对比指南(DummyVecEnv vs SubprocVecEnv)

本文深入对比了Stable-Baselines3中DummyVecEnv与SubprocVecEnv两种向量化环境的性能差异与应用场景。DummyVecEnv适用于轻量级、步进快的环境,调试友好且开销低;而SubprocVecEnv则通过真正的多进程并行,能显著加速计算密集型环境的训练。文章通过基准测试与决策树,指导开发者根据环境计算成本、CPU核心数等关键因素做出最优选择,以实现训练效率最大化。

weixin_29063979的博客 148

Android基础--ListView中的setSelection方法

ListView中的setSelection方法 setSelection使用场景 public void setSelection(int position) 当聊天软件中出现很多消息的时候,会如下图顶端显示还有26条新消息,点击会跳转到最早的未读新消息的位置,这就是setSelection的使用场景 setSelectionFromTop 与setSelection类似 public voi...

yanwenyuan0304的专栏 2401

大疆OcuSync vs 传统2.4GHz:深度拆解无人机图传射频模块的硬件差异

本文深度对比了大疆OcuSync与传统2.4GHz无人机图传射频模块的硬件差异,涵盖芯片组、天线系统、PCB设计、散热方案及生产测试等核心环节。重点解析OcuSync的全定制SoC芯片、智能MIMO天线阵列及精密PCB布局如何实现革命性性能提升,为无人机图传技术发展提供专业参考。

u5v6w7的博客 807

ListView.getChildCount() 详解

ListView.getCount() 返回的所包含的item总个数 ListView.getChildCount() (ViewGroup.getChildCount()) 返回的是现实层面上所包含的子View个数。 二者的区别: 当listView 中 item 比较少,不需要滚动就可以现实全部 二者是等价的。 当item个数多 要滚动时 ...

weixin_30436101的博客 365

AI 生成 CAN 通信测试用例实战

本文分享了AI辅助汽车电子测试用例编写的实战经验。通过某车企CAN网络测试项目案例,对比传统方式(需27天)与AI辅助方式(仅5天)的效率差异,展示81%的效率提升。文章详细介绍了从DBC文件提取信号信息的方法,包括DBC文件结构解析、信号定义说明,并提供了完整的Python解析脚本代码,可将信号信息导出为JSON或Excel格式,为后续AI批量生成测试用例奠定基础。

小明的博客 695

零基础 ABAP 学习教程系列文章的目录

曾几何时,ABAP 就是 SAP 的代名词。ABAP 这门编程语言造就了 SAP 名噪一时的 R/3 产品,同时也是如今 SAP 旗舰级产品,SAP S/4HANA 底层的实现语言。 ABAP 不仅代表着 SAP 这家公司在企业级管理软件市场辉煌的过去,ABAP 自身也在不断地进化着。SAP 不仅在本地部署(On-Premise)领域继续保持着自己绝对的统治地位,而且在云应用领域(Software-as-a-Service, 简称 SaaS), 也推出了自己的解决方案,比如 SAP S/4HANA Clo

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2万+

android中listview下拉刷新,上拉载入更多示例,Android中Listview下拉刷新和上拉加载更多的多种实现方案...

listview经常结合下来刷新和上拉加载更多使用,本文总结了三种常用到的方案分别作出说明。方案一:添加头布局和脚布局android系统为listview提供了addfootview和addheadview两个API。这样可以直接自定义一个View,以添加视图的形式实现下来刷新和上拉加载。实现步骤1、创建一个类继承ListView:class PullToRefreshListView exten...

weixin_34748612的博客 789

MTK Meta ISP 工具使用技巧与参数读取路径全解析

在联发科(MediaTek, MTK)平台上进行相机图像调试时,Meta ISP 工具是连接 PC 与设备进行参数调整、寄存器读取和图像输出的重要工具。本文以实战角度出发,系统梳理 Meta ISP 的使用流程、关键模块功能、典型调试技巧与参数读取路径,结合最新版平台(如MTK Genio/Dimensity 系列)架构,帮助工程师掌握联发科图像调优的核心流程。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1153

listview 精确定位

工作中遇到一个需求,对ListView某一项操作后刷新ListView,但是如果直接刷新,界面上ListView从第一列开始显示,用户体验不好,于是在网上搜了一些恢复LIstView滑动位置的方法。解决办法如下:     List> list; private int scrollPos;     private int scrollTop;     private void

langwang2的专栏 435

C++面试八股文

和静态多态(又称编译期多态,即在系统编译期间就可以确定程序将要执行哪个函数),其中动态多态是通过虚函数实现的,虚函数是类的成员函数,存在存储虚函数指针的表叫做虚函数表,虚函数表是一个存储类成员虚函数的指针,每个指针都指向调用它的地方,当子类调用虚函数时,就会去虚表里面找自己对应的函数指针,从而实现“谁调用、实现谁”从而实现多态。而C++符号表中的符号不是以函数名命名的,称为函数名修饰规则,虽然函数名相同,但是函数参数等其他属性不同,取的符号也不同,所以不会产生查询歧义的问题,使得函数可以重载。

qq_46676829的博客 906

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

精确定位及恢复ListView的位置

工作中遇到一个需求,对ListView某一项操作后刷新ListView,但是如果直接刷新,界面上ListView从第一列开始显示,用户体验不好,于是在网上搜了一些恢复LIstView滑动位置的方法。解决办法如下:     List> list; private int scrollPos;     private int scrollTop;     private void sh

gwpJava的专栏 1394

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ListView的精确定位 和 自下而上展示的ListView

在android的开发中,经常会遇到需要主动去设定某条ListItem的位置的需求。设置位置的函数有 ListView.setSelection(int position) ListView.setSelectionFromTop(int position, int y); 其中 position指的是指定的item的在ListView中的索引,注意如果有Header存在的情

若彬的成长笔记 756

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

关于ListView、GridView滚动条定位到选中的那一条内容

在上一篇关于ScrollViewer的文章中,讲到了怎么进行ScrollViewer的定位问题,这里来介绍ListView、 ScrollViewer的定位问题:       以ListView为例:       我们在做开发中,通常会有这么一个需求:       场景一:从A页面跳转到B(有一个ListView绑定了一组数据)页面,A页面传入了某一参数,B页面根据传入的参数,ListVi

hyr83960944的专栏 7772

ListView的定位

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33935777的博客 159

Android面试题---ListView

Android开发中ListView定位技巧与ScrollView嵌套问题解决方案:通过setSelection()和smoothScrollToPosition()可实现列表定位,需注意数据加载时机和性能优化;ScrollView内嵌ListView会导致显示不全,可通过自定义ListView重写onMeasure()解决,同时需处理图片错位问题,采用"可见则显示"策略。

xingfuyisheng的专栏 606

在listview中实现一个可以悬浮在listview顶部且可以被下一个titleBar推动并取代顶部titleBar

1.实现带首字母Title的ListView 重点在MyAdapter的注释 MainActivity.java public class MainActivity extends Activity { private MyAdapter mAdapter; private ListView mListView; private List mList; @Over

XDLinAtS的专栏 2650

android ListView 单条刷新方法实践及原理解析

对于使用listView配合adapter进行刷新的方法大家都不陌生,先刷新adapter里的数据,然后调用notifydatasetchange通知listView刷新界面。 方法虽然简单,但这里面涉及到一个效率的问题,调用notifydatasetchange其实会导致adpter的getView方法被多次调用(画面上能显示多少就会被调用多少次),如果是很明确的知道只更新了list中的某

h_025的博客 300

【android】ListView 单条刷新方法实践及原理解析

对于使用listView配合adapter进行刷新的方法大家都不陌生,先刷新adapter里的数据,然后调用notifydatasetchange通知listView刷新界面。 方法虽然简单,但这里面涉及到一个效率的问题,调用notifydatasetchange其实会导致adpter的getView方法被多次调用(画面上能显示多少就会被调用多少次),如果是很明确的知道只更新了list中的某

u011494050的专栏 1048

Android入门第七篇之ListView (二)

Android入门第六篇之ListView (一) ,讲的是如何制作一个具有两行文本的 自定义控件 ,作为ListView的Item的使用方法。这篇接下来也是围绕ListView和Item,更加深入地介绍它们的用法。        首先,先来看看本文代码运行的结果,本文的Item比上一篇中的Item多出左边的图标:         main.xml的源代码,跟上一篇的一样,

get123的专栏 587

Android滚动选取金额

UI效果图: 最终的效果是可以滑动刻度来选取金额,并且滑动停止后必须定位到某个金额上,不能停留在中间。          分析:决定用listview来实现上述效果                     分析UI图,发现有三种类型的item,短的,长的,还有长的带文字的。 1.listview所用的adapter的实现。 ListAdaptera.java文件 packa

huohacker的专栏 5179
上一篇: 精确定位及恢复ListView的位置
下一篇: Android ImageButton的使用 及长按Button的实现
gwpJava
博客等级 码龄14年 11粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值