ListView直接继承自的AbsListView,而AbsListView有两个子实现类,一个是ListView,另一个就是GridView,

因此我们从这一点就可以猜出来,ListView和GridView在工作原理和实现上都是有很多共同点的。然后AbsListView

又继承自AdapterView,AdapterView继承自ViewGroup,后面就是我们所熟知的了。

Adapter

说道ListView就会想到adapter,经常看到它们配套使用,为什么要使用adapter呢?

1、适配多种类型数据

控件就是为了交互和展示数据,ListView控件,它比较特殊,可以展示多种类型的数据交互和显示,比如array,list,Cursor,

或者Object,各种自定义类型,要实现多类型数据交互,要是都在View中处理,就不太灵活,adapter就充当了数据转换的桥梁。

2、重用机制RecycleBin

不管你有千条万条,ListView通过重用机制,减少了内存开销,及读xml的次数,可以说这才是ListView的精髓。

如上图所示:频幕中可显示6个activit的Item,向上滑动,Item1滑出屏幕,这时Item1被缓存起来,当Item7要出

现在屏幕时,就去缓存中,找到已经缓存好的view,刷新数据。这样不管你有多少条数据,也只是对这第一次

建立的6个Item View重用。

既然这么强大,我们就来分析下RecycleBin

比较重要的几个成员变量

mActiveViews          // View[ ]  存放当前可见View,也就是上图6个可见的Item

mCurrentScrap       // ArrayList<View> 存放废弃的View,也就是当Item1滑出屏幕后,就被添加到这个list中了

mScrapViews        // ArrayList<View>[ ]  存放废弃的Views,这个数组是在多类型布局中用到,与它有关的变

量ViewTypeCount,在adapter使用了getViewTypeCount() 后,会把View缓存到这个数组中

几个重要的方法:

  • fillActiveViews() 这个方法接收两个参数,第一个参数表示要存储的view的数量,第二个参数表示ListView中第一个可见元素的position值。RecycleBin当中使用mActiveViews这个数组来存储View,调用这个方法后就会根据传入的参数来将ListView中的指定元素存储到mActiveViews数组当中。
  /*** Fill ActiveViews with all of the children of the AbsListView.** @param childCount The minimum number of views mActiveViews should hold* @param firstActivePosition The position of the first view that will be stored in*        mActiveViews*/void fillActiveViews(int childCount, int firstActivePosition) {if (mActiveViews.length < childCount) {mActiveViews = new View[childCount];}mFirstActivePosition = firstActivePosition;//noinspection MismatchedReadAndWriteOfArrayfinal View[] activeViews = mActiveViews;for (int i = 0; i < childCount; i++) {View child = getChildAt(i);AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();// Don't put header or footer views into the scrap heapif (lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {// Note:  We do place AdapterView.ITEM_VIEW_TYPE_IGNORE in active views.//        However, we will NOT place them into scrap views.activeViews[i] = child;}}}
  • getActiveView() 这个方法和fillActiveViews()是对应的,用于从mActiveViews数组当中获取数据。该方法接收一个position参数,表示元素在ListView当中的位置,方法内部会自动将position值转换成mActiveViews数组对应的下标值。需要注意的是,mActiveViews当中所存储的View,一旦被获取了之后就会从mActiveViews当中移除,下次获取同样位置的View将会返回null,也就是说mActiveViews不能被重复利用。
  View getActiveView(int position) {int index = position - mFirstActivePosition;final View[] activeViews = mActiveViews;if (index >=0 && index < activeViews.length) {final View match = activeViews[index];<span style="color:#3333FF;"> activeViews[index] = null;</span>return match;}return null;}
  • addScrapView() 用于将一个废弃的View进行缓存,该方法接收一个View参数,当有某个View确定要废弃掉的时候(比如滚动出了屏幕),就应该调用这个方法来对View进行缓存,RecycleBin当中使用mScrapViews和mCurrentScrap这两个List来存储废弃View。
   if (scrapHasTransientState) {// 快速滑动过渡状态处理,这里不分析
} else {if (mViewTypeCount == 1) {mCurrentScrap.add(scrap);} else {mScrapViews[viewType].add(scrap);}if (mRecyclerListener != null) {mRecyclerListener.onMovedToScrapHeap(scrap);}}
  • getScrapView 用于从废弃缓存中取出一个View,这些废弃缓存中的View是没有顺序可言的,因此getScrapView()方法中的算法也非常简单,就是直接从mCurrentScrap当中获取尾部的一个scrap view进行返回。
    View getScrapView(int position) {if (mViewTypeCount == 1) {return retrieveFromScrap(mCurrentScrap, position);} else {final int whichScrap = mAdapter.getItemViewType(position);if (whichScrap >= 0 && whichScrap < mScrapViews.length) {return retrieveFromScrap(mScrapViews[whichScrap], position);}}return null;}
  • setViewTypeCount() 我们都知道Adapter当中可以重写一个getViewTypeCount()来表示ListView中有几种类型的数据项,而setViewTypeCount()方法的作用就是为每种类型的数据项都单独启用一个RecycleBin缓存机制。实际上,getViewTypeCount()方法通常情况下使用的并不是很多,所以我们只要知道RecycleBin当中有这样一个功能就行了。
  public void setViewTypeCount(int viewTypeCount) {if (viewTypeCount < 1) {throw new IllegalArgumentException("Can't have a viewTypeCount < 1");}//noinspection uncheckedArrayList<View>[] scrapViews = new ArrayList[viewTypeCount];for (int i = 0; i < viewTypeCount; i++) {scrapViews[i] = new ArrayList<View>();}mViewTypeCount = viewTypeCount;mCurrentScrap = scrapViews[0];mScrapViews = scrapViews;}

setViewTypeCount()赋值实在adapter中调用getViewTypeCount()后得到ViewTypeCount。

说道这,都了解了listView是怎么缓存的了吧,具体怎么绘制就不多说了,都是onMeasure()用于测量View的大小,onLayout()用于确定View的布局,

onDraw()用于将View绘制到界面上。onMeasure,onDraw没什么特别的,需要进一步分析的可以看看ListView的父类AbsListView中实现的onLayout

ListView原理分析之重要方法介绍相关推荐

  1. 计算机故障的分析原理,蓝屏含义、原理分析、处理方法 电脑计算机故障系统安全...

    目录 1含义2原理分析3处理方法4代码含义和解决 5原因分析6预防电脑蓝屏的 含义 引蓝屏解释 1.故障检查信息 ***STOP 0x0000001E(0xC0000005,0xFDE38AF9,0x ...

  2. ChatGPT原理解析以及使用方法介绍

    一.背景 这里我就直接贴上跟ChatGPT的对话作为背景输入,说真的,它的回答比我写的还要专业,具体见如下截图: 二.原理 从官网介绍可以看到,ChatGPT与InstructGPT是同源的模型.那么 ...

  3. C++游戏分析与破解方法介绍

    1.C++游戏简介 目前手机游戏直接用C++开发的已经不多,使用C++开发的多是早期的基于cocos2dx的游戏,因此我们这里就以cocos2d-x为例讲解C++游戏的分析与破解方法. Cocos2d ...

  4. 转载 OAuth认证协议原理分析及使用方法

    本文系转载 原文地址http://kejibo.com/oauth/ 感谢原作者 新:oauth第二代  oauth2开放认证协议原理及案例分析 写于 2011-8-4 twitter或豆瓣用户一定会 ...

  5. OAuth认证协议原理分析及使用方法

    twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转回原网站,你会发现你已经登录此网站了, 这种网站就是这个效果.其实这都是拜 OAuth所赐. OAuth ...

  6. java token认证机制,OAuth认证协议原理分析及使用方法

    twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到twitter登录,之后转回原网络 twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转 ...

  7. U盘病毒原理分析和解决方法

    由于现在U盘相当普及,导致了U盘病毒的泛滥.很多人对U盘病毒非常痛恨,但是却找不到一种较好的解决方案.特别是比如有的时候新安装的系统,一不小心插个U盘,努力全部白费了,真是让人欲哭无泪啊. U盘病毒, ...

  8. 计算机空调维护与维修,空调电脑板的原理分析与维修方法和技巧

    近几年生产的新型空调机均采用电脑板控制,它通过接收到的各种电信号,用微处理器(CPU)进行处理,然后发出相应的控制指令对执行器件进行控制,使空调机根据人的操作指令实行制冷或制热,同时在室内机液晶屏上作 ...

  9. PHP文件包含漏洞原理分析和利用方法

    本文章简单摘要:一.涉及到的危险函数[include(),require()和include_once(),require_once()]include()&&require()语句: ...

  10. 计算机启动硬盘响,电脑开机时硬盘响个不停是什么原因?原因分析与解决方法介绍...

    本文主要和广大电脑用户分享开机硬盘响个不停是怎么回事?在日常使用电脑当中,大家应该能意识到一般硬盘在开机的时候都会发出正常明显的声音,这是由于硬盘在通电以后,音圈马达会带动硬盘磁头从止动器(硬盘断电后 ...

最新文章

  1. Matlab内置的矩阵反转函数
  2. linux 开启新端口号,linux 查看端口,开启新端口
  3. html5 网页弹幕,Damoo
  4. 小鱼易连电脑版_电脑?不,它是随时就绪的专业电话会议解决方案
  5. Oracle入门(十三A2)之单行函数
  6. PrimeFaces Mobile入门
  7. 三次握手 四次握手 与socket函数的关系
  8. vscode使用sass_推荐7 个 极好用的VS Code 插件
  9. scala 函数中嵌套函数_Scala中的嵌套函数 用法和示例
  10. h5端呼起摄像头扫描二维码并解析
  11. php 快速找到php.ini位置
  12. ctf-web-sql注入
  13. mysql的填充因子_SQL SERVER中,什么是填充因子?
  14. 学习delphi FMX 的一些资料
  15. 模拟信号隔离转换模块0-10V0-5V转4-20mA0-20mA直流转换
  16. 四川托普计算机学校官网,四川中等职业技术学院
  17. 【linux测试必背| tcpdump】命令行抓包神器 | tcpdump抓取post请求并显示详细参数
  18. JavaScript中逻辑运算符(、||、!)的优先级和运算顺序
  19. 好用app开屏广告组件XHLaunchAd -支持静态/动态图片广告/mp4视频广告
  20. Unity 休闲游戏体力值恢复

热门文章

  1. 指针 是否相同_【变电小课堂】MF47指针式万用表操作指南
  2. 简单的springBoot集成jedis
  3. 常用软件版本查看Windows下
  4. 攻防世界 ics-05 write up
  5. 关于python 输出中文
  6. 2 Linux基本命令复习2
  7. 框架的配置文件的映射机制
  8. Python3 函数参数
  9. HDU-1150 Machine Schedule 二分图匹配
  10. 如何实现:GridView 控件中显示的文本不自动换行,隐藏超出宽度部分wj-wangjun