详细讲解Android中的AbsListView的源码
不知道各位童鞋们在开发的过程中有没有感兴趣过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的源码的更多相关文章
- 详细讲解Android中的Message的源码
相信大家对于Android中的Handler是在为熟悉不过了,但是要知道,Handler就其本身而言只是一个壳子,真正在内部起到作用的是Message这个类,对于Message这个类,相信大家也不会陌 ...
- android中使用afinal一行源码显示网络图片
下面代码是关于android中使用afinal一行显示网络图片的代码. public class DemoActivity extends FinalActivity { @Override publ ...
- 详细讲解Android的网络通信(HttpUrlConnection和HttpClient)
前言,Android的网络通信的方式有两种:使用Socket或者HTTP,今天这一篇我们详细讲解使用HTTP实现的网络通信,HTTP又包括两种方式编程方式: (1)HttpUrlConnection: ...
- 详细讲解Android对自己的应用代码进行混淆加密防止反编译
1.查看项目中有没有proguard.cfg. 2.如果没有那就看看这个文件中写的什么吧,看完后将他复制到你的项目中. -optimizationpasses 5 -dontusemixedcasec ...
- 第五节:详细讲解Java中的接口与继承
前言 大家好,给大家带来详细讲解Java中的接口与继承的概述,希望你们喜欢 什么是接口(interface) 接口中的方法都是抽象方法,public权限,全是抽象函数,不能生成对象 interface ...
- 第四节:详细讲解Java中的类和面向对象思想
前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...
- 第九节:详细讲解Java中的泛型,多线程,网络编程
前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...
- 第八节:详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架
前言 大家好,给大家带来详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架的概述,希望你们喜欢 JAVA 异常 try...catch...finally结构的使用方法 class Tes ...
- 第七节:详细讲解Java中的日期,java.util.date
前言 大家好,给大家带来详细讲解Java中的日期,java.util.date的概述,希望你们喜欢 类Date Java.lang.Object->java.util.Date public c ...
随机推荐
- 应用安全 - CMS - vBulletin漏洞汇总
SSV-15384 Date: 2004.11 漏洞类别: SQL 注入 SSV-15476 Date: 2005.2 漏洞类别: RCE SSV-15482 Date: 2005.2 类型: RCE ...
- 避免浏览器缓存JS
有时候更改了JS代码,但是浏览器内容不变,这样<script src="Scripts/myjs/Master.js?v"></script>引入JS就可以 ...
- Redis进阶:Redis的哨兵模式搭建
Redis进阶:Redis的哨兵模式搭建 哨兵机制介绍 单机版的Redis存在性能瓶颈,Redis通过提高主从复制实现读写分离,提高了了Redis的可用性,另一方便也能实现数据在多个Redis直接的备 ...
- 单词数 HDU 2072 字符串输入控制
单词数 HDU 2072 字符串输入控制 题意 lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词的总数.下面你的任务是帮助xiaoou333解决这个 ...
- Centos7防火墙开启3306端口
CentOS7的默认防火墙为firewall,且默认是不打开的. systemctl start firewalld # 启动friewall systemctl status firewalld # ...
- 五、JVM — 类加载器
回顾一下类加载过程 类加载器总结 双亲委派模型 双亲委派模型介绍 双亲委派模型实现源码分析 双亲委派模型的好处 如果我们不想要双亲委派模型怎么办? 自定义类加载器 推荐 回顾一下类加载过程 类加载过程 ...
- ☆☆☆☆☆Placeholder兼容各大浏览器的例子☆☆☆☆☆
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Neo4j清空所有数据
两种方法: 一.用下列 Cypher 语句: match (n) detach delete n 二. 1.停掉服务: 2.删除 graph.db 目录: 3.重启服务. 原文地址:http://ne ...
- activemq热备与消息丢失
1. 解压 tar -zxvf apache-activemq-5.12.0-bin.tar.gz2. 改名 mv apache-activemq-5.12.0 activemq3. cd activ ...
- md5sum - 计算检验MD5效验码
总览 (SYNOPSIS) ../src/md5sum [OPTION] [FILE]... ../src/md5sum [OPTION] --check [FILE] 描述 (DESCRIPTION ...