不知道各位童鞋们在开发的过程中有没有感兴趣过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. 使用bat脚本进行开机启动批处理

    @echo off//关闭提示信息 start /b "F:\newProject\project\Kinect\Kinect\bin\Debug\" /min Kinect.ex ...

  2. ascx

    aspx是页面文件ascx是用户控件,用户控件必须嵌入到aspx中才能使用. ascx是用户控件,相当于模板 其实ascx你可以理解为Html里的一部分代码,只是嵌到aspx里而已,因为aspx内容多 ...

  3. Rocketmq-概念

    一.Rcoketmq Rocketmq是一个消息中间件,简单来说就是传递消息用的. 二.Rocketmq构成 1.Rocketmq组件不是单个的软件,它是由四个组件构成的: (1)Producer 消 ...

  4. Springboot2.x集成Redis集群模式

    Springboot2.x集成Redis集群模式 说明 Redis集群模式是Redis高可用方案的一种实现方式,通过集群模式可以实现Redis数据多处存储,以及自动的故障转移.如果想了解更多集群模式的 ...

  5. 把对像生成json并存储到文件

    1.创建实体对像json import com.alibaba.fastjson.annotation.JSONField; import java.util.Date; public class S ...

  6. ajax的contentType和dataType

    1.contentType,明确告诉服务器我的请求的编码类型是json(严格来说是application/json),不设置的话,有默认值application/x-www-form-urlencod ...

  7. 2019 CSP-S初赛游记

    2019-10-19 ——这个注定要被载入史册的日子 作为一名初中生,和lpy大佬一同参加提高组的比赛,而今年普及组和提高组的时间竟然不一样,于是——凌晨六点半,来到了pdyz和高中生一起坐车去. 高 ...

  8. honpeyhonepy

    2019.09.15 简历编辑功能: 2019.09.23 爬虫功能(智联招聘) 2.1 AI同步功能 2019.10.08 登录功能(包括普通用户登录.管理员.招聘人员) 2019.11.10 鉴权 ...

  9. 通过编写串口助手工具学习MFC过程——(九)自动识别串口的方法

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  10. Enlarge GCD(素数筛)

    题意 删去最少的数,使gcd变大 题解 只要保留相同素数因子最多的数即可. 素数筛. C++代码 #include<bits/stdc++.h> using namespace std; ...