Android开发之ListView中Adapter的优化
ListView是Android开发最常用的控件,适配器adapter是将要显示的数据映射到View中并添加到ListView中显示在实现ListView时,我们需要定义适配器如BaseAdapter、ArrayAdapter、CursorAdapter、SimpleAdapter等,并且重写其一下四个方法: 1 public int getCount(); 2 public Object getItem(int position) 3 public long getItemId(int position) 4 public View getView(int position, View convertView, ViewGroup parent)
我们需要定义一个View,用来显示每条信息,最后添加到ListView中。
其优化的原则是:空间和时间的相互转换或者自身转换,比如时间换时间,时间换空间,空间换空间,空间换时间。
比如我们定义了一个view文件:list_item_callsms.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content" ><TextViewandroid:layout_marginTop="3dip"android:layout_marginLeft="10dip"android:id="@+id/tv_black_number"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="黑名单号码"android:textColor="#88000000"android:textSize="20sp" /><TextViewandroid:layout_marginTop="3dip"android:layout_marginLeft="10dip"android:id="@+id/tv_black_mode"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/tv_black_number"android:text="拦截模式"android:textColor="#88000000"android:textSize="15sp" /></RelativeLayout>
我们在实现Adapter时,假设我们这样操作:
private List<BlackNumberInfo> infos;private class CallSMSSafeAdapter extends BaseAdapter {@Overridepublic int getCount() {// 返回多少条return infos.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}//有多少个条目 这个方法就会被调用多少次@Overridepublic View getView(int position, View convertView, ViewGroup parent) {//把一个布局文件转换成一个 view对象 每次都要调用 非常占用内存空间View view = View.inflate(getApplicationContext(),R.layout.list_item_callsms, null);TextView tv_black_number = (TextView) view.findViewById(R.id.tv_black_number);TextView tv_black_mode = (TextView) view.findViewById(R.id.tv_black_mode);tv_black_number.setText(infos.get(position).getNumber());String mode = "全部拦截";if (infos.get(position).getMode().equals("1")) {mode = "电话拦截";} else if (infos.get(position).getMode().equals("2")) {mode = "短信拦截";}tv_black_mode.setText(mode);return view;}}
上面会出现一个问题,当要显示的数据集合超过100多条时(infos),当我们快速的滑动ListView时,界面会显示程序无响应,而LogCat中则不停的打印DVM虚拟机GC垃圾回收数据(实际是每次定义的View对象);这样别然严重的影响程序的性能和用户体验;
所以针对上述,可以对ListView使用的Adapter做两方面的优化:
1、 减少内存中View对象的创建次数个数。
ListView中的View在第一个可见的列表里是创建的(converView是为null的),当再次加载滑动时,会converView会复用之间创建的view,之后循环这个可见的View对象列表。
getViewTypeCount()
andgetItemViewType(int)
).
2、减小view中对应控件查找的次数。
每次查找view中的控件都是相当耗时的,相当于遍历了一遍view对应的xml树,所以我们只需在第一个遍历,以后直接复用。
因此我们可以创建一个View缓存,然后使用view的Tag存放的控件在内存中的地址。所以我们最多创建ViewList可见的长度个View,查找一次View中控件的id。
这样就能很大的提升程序的性能。
3、使用分批加载数据。
4、使用分页加载数据。
优化后的代码如下:
private class CallSMSSafeAdapter extends BaseAdapter {@Overridepublic int getCount() {// 返回多少条return infos.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}//有多少个条目 这个方法就会被调用多少次@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;//把一个布局文件转换成一个 view对象 每次都要调用 非常占用内存空间//1. 减小内存中View对象创建的个数if(convertView == null){//converView 为空时 才创建convertView = View.inflate(getApplicationContext(),R.layout.list_item_callsms, null);holder = new ViewHolder();//2. 减小View中控件查询的次数 holder.tv_number = (TextView) convertView.findViewById(R.id.tv_black_number);holder.tv_mode = (TextView) convertView.findViewById(R.id.tv_black_mode);//把ViewHolder保存在View的tag中convertView.setTag(holder);}else {//获取View的Tag中的ViewHolderholder = (ViewHolder) convertView.getTag();}holder.tv_number.setText(infos.get(position).getNumber());String mode = "全部拦截";if (infos.get(position).getMode().equals("1")) {mode = "电话拦截";} else if (infos.get(position).getMode().equals("2")) {mode = "短信拦截";}holder.tv_mode.setText(mode);return convertView;}}/*** 记录View中控件的内存地址 相当于一个记事本* @author zty**/static class ViewHolder{TextView tv_number;TextView tv_mode;}
Android开发之ListView中Adapter的优化相关推荐
- Android开发之ListView异步加载图片
ListView这个控件对于大家肯定不会陌生,即使你是初学者相信也会用ListView.因为ListView这个控件实在是太常用,可以说基本上每一个项目开发都会用到它,今天这篇博客主要讲解,ListV ...
- android listview edittext 焦点冲突,Android开发之ListView+EditText-要命的焦点和软键盘问题解决办法...
//这个是设置EditText添加到行的Layout时需要的属性,高度无所谓,宽度要填满父容器,别手动设置宽度dp private LayoutParams fillParentLayoutParam ...
- android listview 开发,android开发之ListView实现
今天又初步学习了一下ListView控件,看看效果如下: LisViewActivity.java源码: package com.jinhoward.UI_listview; import java. ...
- Android开发之ListView的全选和全不选
看图: 我这是两个全选页面,所以一般这种是两个fragment进行嵌套实现.来看下我主页布局 <?xml version="1.0" encoding="utf-8 ...
- Android开发之listview添加头布局(header)和脚布局(footer)的方法
我们先说下添加的方法 方法一:正常添加lvCouponList.addHeaderView(headerView);lvCouponList.addFooterView(footerView); 方法 ...
- Android开发之ListView子布局item高度的问题
当你设置了子item为具体高度的时候可能会出现子布局里面的子条目产生设置高度无效的问题,那应该怎么解决呢? 很简单需要设置一个属性在xml中 minHeight的最小高度为子item的高度即可解决此b ...
- android之json解析优化,Android开发之json解析
目前正在尝试着写app,发现看懂代码和能写出来差距很大,最关键的是java基础比较的差,因为只会python,java基础只学习了一个礼拜就过了.感觉java写出来的代码不如python简单明了. 上 ...
- android中oncreate方法,android开发之onCreate( )方法详解
这里我们只关注一句话:This is where you should do all of your normal static set up.其中我们只关注normal static, normal ...
- Android记录15--关于ListView中adapter调用notifyDataSetChanged无效的原因
Android记录15--关于ListView中adapter调用notifyDataSetChanged无效的原因 2014年1月16日 开发记录 话说这个问题已经困扰我很久了,一直找不到原因,我以 ...
- Flutter开发之ListView下拉刷新上拉加载更多(35)
在Flutter开发之ListView组件(21) 文章中,我们了解了ListView组件的基本使用.但是数据比较少,没有涉及分页加载.而实际开发中,下拉刷新和分页加载几乎是所有APP的标配.在iOS ...
最新文章
- linux ftp 命令集合
- Linux之chattr命令详解
- 【Android 应用开发】BluetoothSocket详解
- 学习Javascript的书籍(转)
- oracle定时关闭job,Oracle job定时操作
- 查看DB2实际数据存储类型
- Goldengate实现在线数据迁移
- 15款优雅的 WordPress 电子商务网站主题
- java连接mysql数据库增删改查操作记录
- 用微软makecert.exe生成一个自签名的证书
- 合并txt文件的几个方法
- cad卸载工具_Adobe软件卸载与常见问题解决方案
- matlab 全局变量(global)数据类型报错问题
- 影响RAID 0性能的因素
- 南京大学计算机系统实验报告,南京大学 计算机系统基础 课程实验 2018(PA3)
- 电脑需要装杀毒软件吗?两个理由看完你做决定
- js正则表达式判断非负数和是否为网址
- 利用高德地图 API 显示地图信息
- 解决python -m spacy download en_core_web_sm连接不上服务器的方案
- html八边形怎么显示,如何用几何画板自定义工具画正八边形