1.listView复用缓存(gridView 这个是多行多列,机制和listView是一样的)
前瞻:
listView在使用的时候肯定会使用到adapter,adapter作用就是就是listView界面和数据之
间的桥梁,当表里的每项数据显示到页面的时候,都会调用adapter的getView()方法,返回一个
view,这样,listview有多少项就会调用多少次getView方法去绘制每一项的界面,如果项数比\
较多,他就会占用系统的极大的内存,所以必须采用性能优化的方法.
listView的工作原理:
listView开始绘制的时候,系统首先会调用getCount()方法,根据返回值得到listView的长度
,然后根据这个长度,调用getView一行一行的绘制listVIew的每一项
listView缓存机制:
1.如果有listVIew内容比较多的时候,其中只有课件的项存在于内存中,其他的都在recycle
中,recycle是Android中专门用来处理缓存的组件
2.listView先通过getView()方法请求一个View,然后请求其他可见的VIew,这时conertView
在getView中是空的
3,当列表的第一项滚出屏幕,这时候这个view会存在于缓存中,也就是convertview.此时一个
新的项从屏幕最低端上来时只,listview会重新请求一个view,这时候将缓存中view进行重使
用,不在创建新view
4.如果条目较多,或者条目的控件比较多,这时候每次创建一个view或者复用view都会
findViewById,因为Android的布局是二叉树的形式,所以每次都执行findViewById寻找控件
id的时候就会占用较大的内存,浪费资源,为解决这个问题,我们可以通过将view和控件的id绑
定在一起进行复用,如果findViewById比较多,将其放到盒子中,然后让盒子和View进行绑定
具体实现步骤
1.创建一个静态的内部类ViewHolder,然后声明所有控件的id到这个内部类中
2.在缓存对象convertView为空的时候,创建这个内部类的对象
3.然后将使用的到的findviewbyId放到这个内部类中(盒子)
4.将这个盒子和view通过标签的形式进行绑定 view.setTag(viewHolder)
5.当convertView缓存对象被复用的时候,将和view绑定的内部类(盒子)获取出来.
6.使用复用的findViewById进行操作展示数据
View view;
if (convertView==null) {
view = View.inflate(ContactActivity.this, R.layout.contact_item, null);
//2.创建一个盒子
mViewHolder = new ViewHolder();
//3.将findViewById放到盒子里面
mViewHolder.ic_contact = (ImageView) view.findViewById(R.id.iv_setup_contact);
mViewHolder.tv_contact_name = (TextView) view.findViewById(R.id.tv_contact_name);
mViewHolder.tv_contact_number = (TextView) view.findViewById(R.id.tv_contact_number);
//4.将盒子和view对象进行绑定
view.setTag(mViewHolder);
}else{
view = convertView;
//5.当convertview缓存被复用的时候,将和view绑定的盒子获取出来
mViewHolder = (ViewHolder) view.getTag();
}
//6.使用复用的findviewbyid进行操作展示数据
//通过position的值找到集合中的contact对象
ContactBean contactBean = contactInfo.get(position);
//设置到view界面进行展示
mViewHolder.tv_contact_name.setText(contactBean.name);
mViewHolder.tv_contact_number.setText(contactBean.number);
//获得联系人的id
Bitmap bitmap = ContactEngine.getContactPhoto(ContactActivity.this, contactBean.id);
if (bitmap!=null) {
mViewHolder.ic_contact.setImageBitmap(bitmap);
}else{
mViewHolder.ic_contact.setImageResource(R.drawable.ic_contact);
}
return view;
}
}
//1.创建存放findViwBYid的盒子
static class ViewHolder{
ImageView ic_contact;
TextView tv_contact_name ;
TextView tv_contact_number;
listView的优化机制
1.如果item中有图片一定要采用异步加载,而且图片尽量要使用缩略图或者小图
2.判断手势,快速滑动时不加载里面的图片
3.要对数据进行分页加载
4.item的布局层级要越少越好
listView的检查
可以使用hierarchview工具查看其优化。
什么是hierarchview?为什么要用它呢?
不合理的布局会使我们的应用程序UI性能变慢,HierarchyViewer能够可视化的角度直观地获得UI布局设计结构
和各种属性的信息,帮助我们优化布局设计。HierarchyViewer是我们优化程序的工具之一,它是Android自带的非常
有用的工具,可以帮助我们更好地检视和设计用户界面(UI),绝对是UI检视的利器。
怎么用它呢?
Hierarchy Viewer是随Android SDK发布的工具,位于Android SDK/tools/hierarchyviewer.bat (Windows操作
系统,mac上显示的为hierarchyviewer),使用起来也是超级简单,通过此工具可以详细的理解当前界面的控件布局以
及某个控件的属性(name、id、height等)。
1)连接设备真机或者模拟器。
2)启动你要观察的应用。
3)打开Hierarchyviewer,点击hierarchyviewer文件即可。
ListView滚动后内容重复的问题
1.当我们获得数据进行展示的时候,一般都会进行一个非null的判断,这样可以保证第一屏在展示的时候防止出现空指针的异常,在第二屏
展示的时候,由于我们复用了第一屏的findViewById,而又遇到这时候获得数据为null,这时候,就会将第一屏的数据展示在第二屏,从而
出现内容重复的情况,为了解决这个问题,我们在做if判断的时候,需要加上else,这样就不会出现内容重复的现象
//获得联系人的id
Bitmap bitmap = ContactEngine.getContactPhoto(ContactActivity.this, contactBean.id);
if (bitmap!=null) {
mViewHolder.ic_contact.setImageBitmap(bitmap);
}else{
mViewHolder.ic_contact.setImageResource(R.drawable.ic_contact);
}