Android 分析监听器上的参数position和id(一)

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单击事件,参见下面源码:

Java代码:

复制代码
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;
 
}
 

 Android 分析监听器上的参数position和id(二)

 

posted on   vus520  阅读(971)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架

导航

< 2011年8月 >
31 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 1 2 3
4 5 6 7 8 9 10
点击右上角即可分享
微信分享提示