Android性能优化 (一)- ListView
2015-03-31 11:33
302 查看
一、概述
这里对ListView进行性能的优化,是指在对adapter进行重写的时候,需要注意影响ListView性能的地方。ListView包含的三要素:
1.ListView : 用于显示列表的view;
2.adapter: 用于将数据映射到listview的容器;
3.data: 具体需要被映射的数据(包括 字符串、图片或其他的控件等)
二、优化原理
由此,优化Listview的性能,就围绕这三要素:优化1:只创建必要的view对象;
这个是从加载数据的方式上进行的优化:
在未做优化前,大概的过程是:首先调用getCount()函数,返回值即为listView的数据长度,然后根据这个长度,再调用getView(int position, View convertView, ViewGroup parent)的方法获取每个Item所对应的view,在getView(int position, View convertView, ViewGroup parent)函数中,会对每个Item都创建一个对象,这样必然会占用很多的内存,影响效率了。
优化2:尽可能减少Layout的inflate的操作;
inflate操作是利用xml文件实例化从而生成相应的View对象的,因为涉及到XML文件的读取,属于IO操作,每次创建item的view时,都会涉及读取一次,影响效率了。
优化3:尽可能较少findViewById();
通过findViewById()方法可以在一个xml文件中找到相应的view,但是这个方法本质上会递归整个view树,以寻找与id相匹配的view,当每个item中的布局比较复杂时,频繁地调用findViewById()肯定也是会影响效率了。
三、优化机制
1.Recycler (针对优化1 和优化2)当ListView中item离开当前视图时,对应的view则会被缓存在Recycler中。此时,相应地从下方生成一个item,此时调用getView(int position, View convertView, ViewGroup parent)函数时,其中传入的convertView便是缓存在Recycler中的view。所以,针对这方面的优化关键在于如何重用convertView!
这样优化,可以避免重复根据xml创建view对象,有效减少xml文件的IO和view的频繁创建。
2.viewHolder静态类(针对优化3)
将item中元素的对象封装成一个自定义的类,然后通过convertView的setTag(Object object)函数将其中成员和xml中的控件绑定在一起,只要对应的convertView还在,那么其相应的Tag就还在,从而通过取viewHoler类成员的方式获取控件,避免每次的findViewById(),另外,因为viewHolder与外部类之间并没有需求相互访问变量或者其他实体,所以最好声明成static静态类。
四、具体实现:
最初的写法:public View getView(int position, View convertView, ViewGroup parent) { View view = LayoutInflater.from(mContext).inflate(R.layout.listview_item, null); ImageView imageView1 = (ImageView)view.findViewById(R.id.imageView1); TextView textView2 = (TextView)view.findViewById(R.id.text2); imageView1.setImageResource(R.drawable.ic_launcher); textView2.setText(mData.get(position)); return view; }
修改后的写法:
static class ViewHolder{ //静态类,并将其对象设置进convertView中,避免每次findViewById() ImageView imageView1; TextView textView1; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView == null){//重用convertView,避免每次都给item创建View holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item, null); holder.imageView1 = (ImageView)convertView.findViewById(R.id.imageView1); holder.textView1 = (TextView)convertView.findViewById(R.id.text1); convertView.setTag(holder); }else{ //只要convertView还在Recycler中,那么其对应的Tag,也即viewHolder对象就在 holder = (ViewHolder)convertView.getTag(); } holder.imageView1.setImageResource(R.drawable.ic_launcher); holder.textView1.setText(mData.get(position)); return convertView; }
最后,其实也可以通过注入框架来精简代码:
static class ViewHolder{ @InjectView(R.id.imageView1) ImageView imageView1; @InjectView (R.id.text1) TextView textView1; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView == null){ holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item, null); convertView.setTag(holder); }else{ holder = (ViewHolder)convertView.getTag(); } holder.imageView1.setImageResource(R.drawable.ic_launcher); holder.textView1.setText(mData.get(position)); return convertView; }
其实到这里,还不算完,需要特别注意,在item中包含大量图片的时候,就需要针对图片做优化了,这个嘛,在另外的博客里继续说道。
相关文章推荐
- android性能优化学习笔记-listview优化
- [Android]ListView性能优化之视图缓存
- Android进阶:ListView性能优化异步加载图片 使滑动效果流畅
- android ListView 性能优化
- Android利用convertView优化ListView性能
- [Android 界面]ListView性能优化之视图缓存
- [Android]ListView性能优化之视图缓存 解决listView显示重复问题
- [Android]ListView性能优化之视图缓存
- Android ListView性能优化
- android TraceView使用以及listview 的性能优化测试(一)
- [Android]ListView性能优化之视图缓存
- [Android]ListView性能优化之视图缓存
- [Android]ListView性能优化之视图缓存
- [Android]ListView性能优化之视图缓存(续) 推荐
- android TraceView使用以及listview 的性能优化测试(二)
- android TraceView使用以及listview 的性能优化测试(一) .
- Android进阶:ListView性能优化异步加载图片 使滑动效果流畅
- [Android]ListView性能优化之视图缓存
- android TraceView使用以及listview 的性能优化测试(一)
- [Android]ListView性能优化之视图缓存