不知道各位童鞋们在开发的过程中有没有感兴趣过ListView是如何实现的呢?其实本身ListView的父类AbsListView才是关键,但是如果大家看过源码的话,会发现AbsListView将近7000多行代码,是不是头大啊,呵呵,没事,下面咱们就一起来看看吧。

我们先从类中的常量开始分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static final int TRANSCRIPT_MODE_DISABLED = 0;
public static final int TRANSCRIPT_MODE_NORMAL = 1;
public static final int TRANSCRIPT_MODE_ALWAYS_SCROLL = 2;
static final int TOUCH_MODE_REST = -1;
static final int TOUCH_MODE_DOWN = 0;
static final int TOUCH_MODE_TAP = 1;
static final int TOUCH_MODE_DONE_WAITING = 2;
static final int TOUCH_MODE_SCROLL = 3;
static final int TOUCH_MODE_FLING = 4;
static final int TOUCH_MODE_OVERSCROLL = 5;
static final int TOUCH_MODE_OVERFLING = 6;
static final int LAYOUT_NORMAL = 0;
static final int LAYOUT_FORCE_TOP = 1;
static final int LAYOUT_SET_SELECTION = 2;
static final int LAYOUT_FORCE_BOTTOM = 3;
static final int LAYOUT_SPECIFIC = 4;
static final int LAYOUT_SYNC = 5;
static final int LAYOUT_MOVE_SELECTION = 6;
public static final int CHOICE_MODE_NONE = 0;
public static final int CHOICE_MODE_SINGLE = 1;
public static final int CHOICE_MODE_MULTIPLE = 2;
public static final int CHOICE_MODE_MULTIPLE_MODAL = 3;

上面的含义分别如下:

1、禁止副本模式

2、当数据集合发生变化的通知被接受到,列表将会自动的滚向底部。但条件必须是最后一条数据已经出现在屏幕上

3、列表将会自动的滚动到底部,不论当前的数据是否可见。

4、猜测我们并不是在触摸的手势中间。

5、假设我们接收到一个touch的触摸的事件,我们等待去看到它是否是一个滑动的手势。

6、预测到当前的touch事件是一个tap事件,我们正在等待这是否是一个长按的事件。

7、其余的常量与此类此,在此省略了。

接下来我们来看一一批与视图绘制相关的变量:

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
32
33
34
35
36
37
38
39
40
Drawable mSelector;
int mSelectorPosition = INVALID_POSITION;
Rect mSelectorRect = new Rect();
final RecycleBin mRecycler = new RecycleBin();
int mSelectionLeftPadding = 0;
int mSelectionTopPadding = 0;
int mSelectionRightPadding = 0;
 
int mSelectionBottomPadding = 0;
Rect mListPadding = new Rect();
int mWidthMeasureSpec = 0;
View mScrollUp;
View mScrollDown;
boolean mCachingStarted;
boolean mCachingActive;
int mMotionPosition;
int mMotionViewOriginalTop;
int mMotionViewNewTop;
 
int mMotionX;
 
int mMotionY;
 
int mTouchMode = TOUCH_MODE_REST;
int mLastY;
 
int mMotionCorrection;
private VelocityTracker mVelocityTracker;
 
private FlingRunnable mFlingRunnable;
AbsPositionScroller mPositionScroller;
 
int mSelectedTop = 0;
 
boolean mStackFromBottom;
boolean mScrollingCacheEnabled;
 
boolean mFastScrollEnabled;
boolean mFastScrollAlwaysVisible;
private OnScrollListener mOnScrollListener;

上面的含义分别如下:

1、用来绘制选中项的图片

2、列表中当前被选中的位置

3、在绘制的时刻定义选中的location与对应的尺寸

4、这个数据被设置,存储未使用的视图,它们将会被重用,在接下来的布局中,避免重用。

5、选中的padding的位置

6、向上滚动的标志与向下滚动的标志的视图

7、当这个视图在滚动的时候,这个标志位被设置为true,预示着绘制缓存的子类在其子类上将会是能够的。

8、获取向下的移动的位置

9、其余的变量的注解省略。

接下来,我们看几个接口的定义

1、OnScrollListener

这个接口定义的是当列表或者是九宫格滚动的时候的回调。

在这个接口中存在下面的几个常量

1
2
3
public static int SCROLL_STATE_IDLE = 0;
public static int SCROLL_STATE_TOUCH_SCROLL = 1;
public static int SCROLL_STATE_FLING = 2;

分别指代的是当前的列表处于静止、手指处于触摸状态的滑动以及手指离开的减速滑动并趋向于静止。

其中接口中还定义了两个函数:

1、onScrollStateChanged

2、onScroll

第一个视图是当视图滚动正准备进行时候的回调

第二个视图是当视图的滚动已经结束的回调

2、SelectionBoundsAdjuster

这个接口的含义是允许当前列表项的顶级视图实现这个接口去修改它的展示的边界区域。

接下来的代码选取几个Api来看一下:

1、setFastScrollerEnabledUiThread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void setFastScrollerEnabledUiThread(boolean enabled) {
        if (mFastScroll != null) {
            mFastScroll.setEnabled(enabled);
        } else if (enabled) {
            mFastScroll = new FastScroller(this, mFastScrollStyle);
            mFastScroll.setEnabled(true);
        }
 
        resolvePadding();
 
        if (mFastScroll != null) {
            mFastScroll.updateLayout();
        }
    }

这个方法的功能是显而易见的,操纵的对象是FastScroller,设置是否支持快速的滑动,然后再进行重新绘制视图。

下面的几个方法是计算滚动区域与展示的效果的方法,我们选取几个来看一下:

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
@Override
   protected int computeVerticalScrollExtent() {
       final int count = getChildCount();
       if (count > 0) {
           if (mSmoothScrollbarEnabled) {
               int extent = count * 100;
 
               View view = getChildAt(0);
               final int top = view.getTop();
               int height = view.getHeight();
               if (height > 0) {
                   extent += (top * 100) / height;
               }
 
               view = getChildAt(count - 1);
               final int bottom = view.getBottom();
               height = view.getHeight();
               if (height > 0) {
                   extent -= ((bottom - getHeight()) * 100) / height;
               }
 
               return extent;
           } else {
               return 1;
           }
       }
       return 0;
   }

这个是计算垂直方向上的滚动的区域。

这个算法我们可以看一下

1、

1
extent += (top * 100) / height;

这里面的100我们可以理解为系统假设单个的列表的选项的高度是100,本着多退少补的原则,不论height是大于100还是小于100, 100 / height,得到的数值可以理解为是缩放因子 scaleFactor, top * scaleFactor 计算得到的是最终需要多加的边距。

结伴旅游,一个免费的交友网站:www.jieberu.com

推推族,免费得门票,游景区:www.tuituizu.com

详细讲解Android中的AbsListView的源码的更多相关文章

  1. 详细讲解Android中的Message的源码

    相信大家对于Android中的Handler是在为熟悉不过了,但是要知道,Handler就其本身而言只是一个壳子,真正在内部起到作用的是Message这个类,对于Message这个类,相信大家也不会陌 ...

  2. android中使用afinal一行源码显示网络图片

    下面代码是关于android中使用afinal一行显示网络图片的代码. public class DemoActivity extends FinalActivity { @Override publ ...

  3. 详细讲解Android的网络通信(HttpUrlConnection和HttpClient)

    前言,Android的网络通信的方式有两种:使用Socket或者HTTP,今天这一篇我们详细讲解使用HTTP实现的网络通信,HTTP又包括两种方式编程方式: (1)HttpUrlConnection: ...

  4. 详细讲解Android对自己的应用代码进行混淆加密防止反编译

    1.查看项目中有没有proguard.cfg. 2.如果没有那就看看这个文件中写的什么吧,看完后将他复制到你的项目中. -optimizationpasses 5 -dontusemixedcasec ...

  5. 第五节:详细讲解Java中的接口与继承

    前言 大家好,给大家带来详细讲解Java中的接口与继承的概述,希望你们喜欢 什么是接口(interface) 接口中的方法都是抽象方法,public权限,全是抽象函数,不能生成对象 interface ...

  6. 第四节:详细讲解Java中的类和面向对象思想

    前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...

  7. 第九节:详细讲解Java中的泛型,多线程,网络编程

    前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...

  8. 第八节:详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架

    前言 大家好,给大家带来详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架的概述,希望你们喜欢 JAVA 异常 try...catch...finally结构的使用方法 class Tes ...

  9. 第七节:详细讲解Java中的日期,java.util.date

    前言 大家好,给大家带来详细讲解Java中的日期,java.util.date的概述,希望你们喜欢 类Date Java.lang.Object->java.util.Date public c ...

随机推荐

  1. 应用安全 - CMS - vBulletin漏洞汇总

    SSV-15384 Date: 2004.11 漏洞类别: SQL 注入 SSV-15476 Date: 2005.2 漏洞类别: RCE SSV-15482 Date: 2005.2 类型: RCE ...

  2. 第九周总结&第七次实验报告

    实验7 实验任务详情: 完成火车站售票程序的模拟. 要求: (1)总票数1000张: (2)10个窗口同时开始卖票: (3)卖票过程延时1秒钟: (4)不能出现一票多卖或卖出负数号票的情况. 实验过程 ...

  3. MySQL8 clone plugin

    安装MySQl8.0.17 下载 MySQL8.0.17 二进制版本 https://dev.mysql.com/downloads/mysql/ 解压,修改权限 -linux-glibc2.-x86 ...

  4. 深入IO 想学必看!受益匪浅哦~

    一:IO流概述 IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间的数据传输,Java对于数据的操作都是通过流实现,而Java用于操作流的对象都在IO包中. 分类: 按操作数据 ...

  5. Coding 地址

    Coding 连接 https://dev.tencent.com/u/leexi

  6. 1、Java语言概述与开发环境——编译和运行第一个程序HelloWorld.java

    编写一个Java程序到运行的步骤概述: 1.将Java代码编写到扩展名为.Java的文件中 2.通过Javac命令对该Java文件进行编译 3.通过Java命令对生成的class文件进行运行 一.编写 ...

  7. 结构体指针,C语言结构体指针详解

    结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过“结构体变量名.成员名”的方式引用结构体变量中的成员,除了这种方法之外还可以使用指针. 前面讲过,& ...

  8. java中访问修饰符public,private,protected,friendly的作用域

    在修饰的元素上没有写任何的访问修饰符,则表示friendly. 作用域 当前类 同一包中 子孙类 其他包中 public √ √ √ √ protected √ √ √ × private √ x x ...

  9. Kibana 基本操作

    es中的索引对应mysql的数据库.类型对应mysql的表.文档对应mysql的记录.映射对应mysql的索引索引:index类型:type映射:mappings 1.创建索引在kibana的Dev ...

  10. JavaScript如何处理JSON数据

    JSON (Javescript Object Notation)一种简单的数据格式,比xml更轻巧. JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON ...