博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android性能优化之ListView缓存机制
阅读量:7010 次
发布时间:2019-06-28

本文共 3109 字,大约阅读时间需要 10 分钟。

要想优化ListView首先要了解它的工作原理,列表的显示须要三个元素:ListView、Adapter、显示的数据。

这里的Adapter就是用到了适配器模式,无论传入的是什么View在ListView中都能显示出来。

以下简单说下上图的原理:

1、假设你有几千几万甚至很多其它的选项(item)时。当中仅仅有可见的项目(满屏显示的Item数目)存在内存(说的优化就是说在内存中的优化!)中,其它的在Recycler中

2、ListView先请求一个type1视图(getView)然后请求其它可见的项目。convertView在getView中是空(null)的。第一次都是为空的。仅仅要显示过了convertView都不为空,会保存在Recycler中

3、当item1滚出屏幕。而且一个新的项目从屏幕低端上来时。ListView再请求一个type1视图。

convertView此时不是空值了,它的值是item1。你仅仅需设定新的数据然后返回convertView,不必又一次创建一个视图,省去了inflate和findViewById的时间,性能就得到了优化。

了解了它的工作原理后,我们就能够反复利用convertView,仅仅要不为空就直接使用。改变它的内容即可了。

使用ListView的时候都会搭配一个Adapter,为了使得性能更优。ListView会缓存行item(某行相应的View)。ListView通过Adapter的getView函数获得每行的item。

package com.dzt.listviewdemo;import java.util.ArrayList;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity {	private ListAdapter adapter;	private ListView lv = null;	private ArrayList
list = new ArrayList
(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView) findViewById(R.id.lv_list); adapter = new ListAdapter(); for (int i = 0; i < 100; i++) { list.add("item " + i); } lv.setAdapter(adapter); } private class ListAdapter extends BaseAdapter { private LayoutInflater mInflater; ListAdapter() { mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub System.out.println("getView " + position + " " + convertView); viewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.item, null); holder = new viewHolder(); holder.text = (TextView) convertView.findViewById(R.id.tv_text); holder.image = (ImageView) convertView .findViewById(R.id.iv_img); convertView.setTag(holder); } else { holder = (viewHolder) convertView.getTag(); } holder.text.setText(list.get(position)); if (position % 2 == 0) { holder.image.setImageResource(R.drawable.ic_launcher); } else { holder.image.setImageResource(R.drawable.icon); } return convertView; } } /** * 使用一个类来保存Item中的元素 * * @author Administrator * */ public static class viewHolder { public TextView text; public ImageView image; }}
执行效果

第一次打印的结果convertView都是为null

滑动ListView后的打印

从上面的打印消息能够看出,Recycler中会保存七个convertView对象用来显示Item。无论你有上千个Item,也仅仅会创建显示满屏的convertView。这就大大节省了内存,对viewHolder的Tag的使用也大大节省了性能开销

相关代码下载:

你可能感兴趣的文章
ASP.NET如何调用MySQL的存储过程
查看>>
Visual Studio 进行Excel相关开发,Microsoft.Office.Interop.Excel.dll库
查看>>
swfdump——从内存中提取swf的工具
查看>>
【Javascript Demo】JS获取当前对象大小以及屏幕分辨率等
查看>>
Android去掉顶部的阴影
查看>>
卡尔曼滤波的原理说明
查看>>
C#对二进制文件的特定位置进行读写小结
查看>>
唯一不变的就是一直在变”--“数据”的华丽“变身术”
查看>>
编译器定义的C/C++语言各种基本数据类型的取值范围
查看>>
matlab 程序发布
查看>>
《Effective C#》读书笔记——条目24:用委托实现回调<使用C#表达设计>
查看>>
.Net中DataAdapter批量插入和更新数据总结
查看>>
DNS通道检测 国外学术界研究情况——研究方法:基于流量,使用机器学习分类算法居多,也有使用聚类算法的;此外使用域名zif low也有...
查看>>
Visual Studio 11 Beta新特性(一):安装VS11
查看>>
SQL Server-触发器(Trigger)之 After 触发器
查看>>
理解逐次逼近寄存器型ADC:与其它类型ADC的架构对比【转】
查看>>
页面大小和页表项之间有必然的联系么?【转】
查看>>
Android -- 使用主题配置文件,去掉程序启动界面的短暂黑屏
查看>>
Oracle 常用操作【02】数据库特性
查看>>
linux下C语言实现的内存池【转】
查看>>