• 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(二)

  • 相关阅读:
    redis 数据迁移
    redis
    Redis集群的三种模式
    Golang 协程 (goroutine) 与通道 (channel)
    Python生成器next方法和send方法区别
    python 文件
    Tornado 异步以及非阻塞的I/O
    python 多进程和多线程3 —— asyncio
    利用CSS改变图片颜色的100种方法!
    jquery获取div的位置
  • 原文地址:https://www.cnblogs.com/vus520/p/2561932.html
Copyright © 2020-2023  润新知