- 浏览: 138235 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
python135:
...
Android自学笔记:分析onXXX事件监听器中的两个参数position和id -
gsp100:
不错,讲得真详细,谢谢了。
Android自学笔记:组件生命周期 -
r8HZGEmq:
LZ,刚开始学的时候就想到看源码了,大牛啊
Android自学笔记:Android2.3源码下载(针对Windows环境) -
YJ198910:
分析得不错,有图有真相呀
Android自学笔记:Tab控件源码剖析 -
zhongyuanceshi:
对象在使用前一定要先定义
Android自学笔记:开发常见问题总结
Android API中有部分事件监听器的方法中都会有参数position和id,它们是用来描述一个视图当中的某一项(item,当然你也可以理解成其它的意思)的属性。position描述该项在视图中所处的位置;而id描述的是该项的id,确切点说是该项在视图中所在的行位置。
这就造成了一种困惑,我们在实际开发中,到底怎么去理解去这两个参数?我们又该怎么去使用?两者又何区别?
下面以ListView中的onItemClickListener事件监听器为例,分析一下两者的区别及其如何使用。
一、区别
貌似有点复杂,分两种场景来讨论:
1.ListView用SimpleAdapter展示数据
position:表示该项在视图中的位置,起始为0。
id:同上。
2.ListView用CursorAdapter展示数据
position: 同上。
id:表示该项在视图中实际位置,说白了就是起始为1。在视图上是第几行,就是第几行。举例:某个ListView共有5行数据,我选中了第3行,那么onItemClickListener()中的id就为3。
3.源码分析
上面简短的总结了两种场景下的含义,说再多也顶不上来自源码的分析:
同样也分两种场景,我们先来分析CursorAdapter场景:
是谁给参数position和id赋的值?
android.widget.AbsListView里面定义了一个私有内部类,用来处理ListView单击事件,参见下面源码:
CursorAdapter场景中的id是怎样实现的?
android.database.CursorWindow定义并实现了getLong(),参见下面源码:
SimpleAdapter场景中的id是怎样实现的?
了解了CursorAdapter场景的id实现方式,那么SimpleAdapter的实现方式就更容易了解了,非常简单,参见下面源码:
二、使用方式
分两种场景,以代码的形式来展示使用方式,以下均选中第2行:
1.SimpleAdapter
2. CursorAdapter
四、总结
目前还是要重点使用positon为上策,更复合程序员的编程习惯(下标以0开始);而id存在一定的变数,也许还未领会其实际用途吧,并且不太理解为什么id要是long类型的。
onItemClickListener()中的position和id就是这样实现的,那与之相类似的监听器也是如此。毕竟监听器是实际开发中经常用到的,所以弄懂细枝末节还是有必要的。
这就造成了一种困惑,我们在实际开发中,到底怎么去理解去这两个参数?我们又该怎么去使用?两者又何区别?
下面以ListView中的onItemClickListener事件监听器为例,分析一下两者的区别及其如何使用。
一、区别
貌似有点复杂,分两种场景来讨论:
1.ListView用SimpleAdapter展示数据
position:表示该项在视图中的位置,起始为0。
id:同上。
2.ListView用CursorAdapter展示数据
position: 同上。
id:表示该项在视图中实际位置,说白了就是起始为1。在视图上是第几行,就是第几行。举例:某个ListView共有5行数据,我选中了第3行,那么onItemClickListener()中的id就为3。
3.源码分析
上面简短的总结了两种场景下的含义,说再多也顶不上来自源码的分析:
同样也分两种场景,我们先来分析CursorAdapter场景:
是谁给参数position和id赋的值?
android.widget.AbsListView里面定义了一个私有内部类,用来处理ListView单击事件,参见下面源码:
private class PerformClick extends WindowRunnnable implements Runnable { View mChild;//子视图 int mClickMotionPosition;//单击事件的所在位置(该位置应理解为某集合中的位置。) //执行主方法 public void run() { if (mDataChanged) return; //这个是告知Android我们用哪个场景来展示数据。 //SimpleAdapter还是CursorAdapter? //阐述策略模式的一个真实场景。 final ListAdapter adapter = mAdapter; //这个就是我们经常看到的position。 final int motionPosition = mClickMotionPosition; if (adapter != null && mItemCount > 0 && motionPosition != INVALID_POSITION && motionPosition < adapter.getCount() && sameWindow()) { //positon还是原来的position,但id就不一样了,它是依靠position来计算得出的值。 //adapter getItemId(motionPosition)也说明了两种场景下的实现方式也是不一样的。 performItemClick(mChild, motionPosition, adapter.getItemId(motionPosition)); } } }
CursorAdapter场景中的id是怎样实现的?
public long getItemId(int position) { if (mDataValid && mCursor != null) { //游标挪到了position的位置上。 if (mCursor.moveToPosition(position)) { //参数mRowIDColumn就是主键ID位置,也就是上文所说的带有”_id”的字段的位置。 return mCursor.getLong(mRowIDColumn); } else { return 0; } } else { return 0; } }
android.database.CursorWindow定义并实现了getLong(),参见下面源码:
public long getLong(int row, int col) { acquireReference(); try { // getLong_native是本地方法,底层计算得出视图中我们单击的那个实际行位置 //参数col就是上面提到的那个mRowIDColumn。 return getLong_native(row - mStartPos, col); } finally { releaseReference(); } }
SimpleAdapter场景中的id是怎样实现的?
了解了CursorAdapter场景的id实现方式,那么SimpleAdapter的实现方式就更容易了解了,非常简单,参见下面源码:
public long getItemId(int position) { //返回的就是position return position; }
二、使用方式
分两种场景,以代码的形式来展示使用方式,以下均选中第2行:
1.SimpleAdapter
//模拟数据,其中_id类似于数据库中的主键,主键名一定要带有”_id”,Android好这口。虽然不是从数据库获取的数据,但最好也要遵从这种习惯。 ArrayList<HashMap<String, String>> classic = new ArrayList<HashMap<String, String>>(); HashMap<String, String> englishMap = new HashMap<String, String>(); englishMap.put(“classic_id”,1l); englishMap.put(“name”,lileilei); englishMap.put(“gender”,male); englishMap.put(“classic _id”,2l); englishMap.put(“name”,hanmeimei); englishMap.put(“gender”,female); englishMap.put(“classic _id”,3l); englishMap.put(“name”,poly); englishMap.put(“gender”,male); //创建SimpleAdater SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.classic,new String[] { " classic _id", "name", "age" }, new int[] {R.id.id_text, R.id.name_text, R.id.age_text }); //设置监听器 ListView lv = this.findViewById(R.id.listview); lv.setAdapter(simpleAdapter); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.i(LOG_TAG, "position:" + position);//输出1 Log.i(LOG_TAG, "id:" + id);//输出1 Log.i(LOG_TAG, "item class : "+ ((ListView) parent).getItemAtPosition(position).getClass().getSimpleName());//输出item class : HashMap //由于上面第三条日志信息输出的类型为HashMap,所以采用HashMap的方式获取数据。 HashMap<String, String> englishMap = (HashMap<String, String>) ((ListView) parent).getItemAtPosition(position); if (englishMap!= null && englishMap.size()> 0) { //做其他操作 } } });
2. CursorAdapter
//从数据库中获取数据,同样,返回的Cursor中必须含有”_id”的字段。 Cursor cursor = .....;//写一个查询数据的方法并返回一个Cursor对象; //创建SimpleCursorAdapter SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this,R.layout.person, cursor, new String[] { " classic _id ", "name", "age" },new int[] { R.id.id_text, R.id.name_text, R.id.age_text }); //设置监听器 ListView lv = this.findViewById(R.id.listview); lv.setAdapter(simpleCursorAdapter); lv.setOnItemClickListener(newOnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view,int position, long id) { Log.i(LOG_TAG, "position:" + position);//输出1 Log.i(LOG_TAG, "id:" + id);//输出2 Log.i(LOG_TAG, "item class : "+ ((ListView) parent).getItemAtPosition(position).getClass().getSimpleName());//输出item class : SQLiteCursor //由于上面第三条日志信息输出的类型为SQLiteCursor,所以采用Cursor的方式获取数据。 Cursor cursor = (Cursor) ((ListView) parent).getItemAtPosition(position); if (cursor != null && cursor.moveToPosition(position)) { //做其他操作 } } });
四、总结
目前还是要重点使用positon为上策,更复合程序员的编程习惯(下标以0开始);而id存在一定的变数,也许还未领会其实际用途吧,并且不太理解为什么id要是long类型的。
onItemClickListener()中的position和id就是这样实现的,那与之相类似的监听器也是如此。毕竟监听器是实际开发中经常用到的,所以弄懂细枝末节还是有必要的。
发表评论
-
Android自学笔记:Tasks and Back Stack原理
2011-04-05 23:50 7951一、参考文章 原文地址:Tasks and B ... -
Android自学笔记(番外篇):全面搭建Linux环境(八)——AOSP参与者工作流程图说明
2011-03-31 23:23 3873------------------------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(七)——JDK的安装与配置(手动版)
2011-03-30 23:18 3256------------------------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(六)——Android的安装与配置及2.3源码下载
2011-03-25 20:05 4418------------------------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(五)——Eclipse Helios(3.6.2)的安装与配置(零配置版)
2011-03-23 22:39 4828------------------------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(四)——JDK的安装与卸载(零配置版)
2011-03-21 10:58 3722------------------------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(三)——Ubuntu10.04(LTS)的安装与配置
2011-03-20 11:00 3448---------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(二)——VMware Workstation7.1.3的安装
2011-03-19 14:42 3466------------------------------- ... -
Android自学笔记(番外篇):全面搭建Linux环境(一)——前期准备工作
2011-03-19 12:41 2523本系列教程 ... -
Android自学笔记:Tab控件源码剖析
2011-03-03 11:36 6361此篇主要以 ... -
Android自学笔记:开发常见问题总结
2011-02-22 08:31 13851.获取界面元件值时,不要忘了是要在事件监听器里面获取的。 原 ... -
Android自学笔记:Android2.3源码下载(针对Windows环境)
2011-01-27 08:36 10275我最近在自学Android,当遇到问题时也只能 ... -
Android学习笔记:怎样去测试?
2011-01-20 11:41 1365我们作为Android程序员,知道怎样去测试与 ... -
Android自学笔记:组件生命周期
2011-01-19 11:45 4217Android应用程序组件中有一个生命周期,贯 ... -
Android自学笔记:进程和线程
2011-01-18 11:39 1347一、进程(Processes) ... -
Android自学笔记:应用程序组件
2011-01-17 08:45 1506一、四个组件类型 Android中有四个重要的 ... -
Android自学笔记:架构体系
2011-01-14 17:18 21431.Android本身是一套软件堆栈(或称为软 ... -
Android自学笔记:应用程序基本原理
2011-01-14 08:58 22671.Android应用程序是要用Java来开发 ...
相关推荐
这篇自学笔记将深入解析Tab控件的源码,帮助开发者更好地理解和使用这一功能。通过源码剖析,我们可以了解到Tab控件的工作原理,从而优化自定义实现,提升用户体验。 1. **TabLayout与ViewPager的配合** TabLayout...
这篇自学笔记详细介绍了在Windows环境下下载Android 2.3源码的步骤,这对于初学者尤其有用。首先,我们需要进行一些准备工作: 1. **下载Msysgit工具**:这是Windows系统下的Git客户端,可以从Google Code项目页面...
《ARM-CORTEX-M4自学笔记:基于K60》这本书深入浅出地探讨了飞思卡尔(现为恩智浦半导体)Kinetis系列中的K60微处理器,为读者提供了一条全面掌握该处理器及其开发技术的道路。ARM Cortex-M4是ARM公司设计的一种高...
本自学笔记将重点讲解如何在Android项目中创建并使用ListView,包括基本的设置、数据绑定和适配器的使用。 首先,我们需要在布局文件中添加ListView元素。在XML布局文件中,通过`<ListView>`标签定义ListView,可以...
【Android自学笔记】 Android 应用开发是移动设备软件开发的重要领域,主要针对谷歌的Android操作系统。本笔记将概述Android应用开发的基础知识,包括环境搭建、应用构成、apk解析、Activity管理和生命周期等。 ...
STM32是一款基于ARM Cortex-M内核的微控制器,由意法半导体(STMicroelectronics)生产,广泛应用在嵌入式系统开发中。STM32系列提供了丰富的外设接口和高性能计算能力,使得它成为电子爱好者和专业工程师进行单片机...
本自学笔记将深入探讨Android的任务栈机制,以帮助开发者更好地理解和利用这一特性来优化用户体验。 一、任务与任务栈 在Android中,一个任务(Task)是一个应用程序执行的上下文,它可以包含多个活动(Activity)...
此方法有两个参数,一个是boolean类型,表示是否是系统主动触发的改变;另一个是Uri对象,表示发生改变的具体Uri。 3. **自定义ContentObserver**: - 继承ContentObserver类,并重写onChange()方法,自定义处理...
- **功能描述**:支持多种流程节点、事件监听器、任务分配等功能,并提供基于流程设计器的界面化定制和部署流程实例的操作。 - **关键特性**:灵活的工作流配置、可视化流程设计器、事件驱动的设计模式。 5. **...
[STM32自学笔记].蒙博宇
同时,会教授如何在代码中动态添加和操作控件,以及使用布局管理器如LinearLayout、RelativeLayout和ConstraintLayout进行界面布局。 第4章:Android布局管理综述 本章进一步探讨Android的布局管理,包括如何使用...
通过这份自学笔记,读者不仅可以学习STM32的基本用法,还能了解到实际项目开发中的问题解决策略和技巧,为成为一名熟练的STM32开发者奠定坚实基础。在学习过程中,结合实际的开发板和实验,理论与实践相结合,将更...
本自学笔记将深入探讨如何使用Pull解析器(PullParser)来处理XML,这是一种高效且内存友好的方式。 一、XML与Android XML(eXtensible Markup Language)是一种用于标记数据的语言,它定义了数据的结构和样式。在...
这篇自学笔记将引导你逐步完成Linux环境的前期准备工作。首先,我们需要理解为何要选择Linux,尤其是在Android开发中。 Linux是一个开源、免费的操作系统,它提供了强大的命令行工具和灵活的环境配置,对于开发者来...
当需要在两个不同的Android进程之间交换数据或调用方法时,就需要使用AIDL。通过定义接口,AIDL能自动生成必要的代码来处理进程间的通信。理解AIDL并学会使用它可以解决多进程协作的问题,但需要注意的是,IPC操作相...
计算机网络自学笔记: 一、计算机网络基础 1. 计算机网络的定义 计算机网络是由多台计算机及相关设备组成,通过通信介质实现资源共享和信息交换的系统。网络中的设备可以通过特定的网络协议进行通信,而Internet...
《AVR单片机自学笔记》以ATmega128单片机为核心,结合作者多年教学和指导大学生电子设计竞赛的经验编写而成。 《AVR单片机自学笔记》继续保持《51单片机自学笔记》一书的写作风格。以任务为中心,并在书中配有多幅...
Android逆向自学笔记
6. **分频器与多路复用器**:这两个常见电路设计示例,有助于初学者理解FPGA的实际应用。 7. **FPGA内部结构**:笔记可能涉及CLB(Configurable Logic Block)、IOB(Input/Output Block)和布线资源等,帮助理解...