文章内容为本人手打,理论知识来自eclipse_xu大神在imooc上发布的视频
以下为视频地址:http://www.imooc.com/view/365
ListView是Android开发最常用到的控件之一,也是初学者刚开始接触Android学习会马上碰到的一个控件之一。
学习ListView的性能优化之前,我们首先要了解ListView的缓存机制,简单一句话解释就是----需要时才显示,显示
后就被回收到缓存区。
下面这张图很好的展示了ListView这种缓存机制
使用ListView我们需要一个数据适配器,什么是数据适配器?简单的说数据适配器就是将我们需要显示到ListView的数据传递给ListView,它起到一个沟通桥梁的作用,具体关系为: 数据---->适配器---->ListView
关于数据适配器在此我们就不做过多的解释,好了,进入今天文章的主题,如何对ListView性能进行优化?
对ListView进行性能优化,本质上是对数据适配器BaseAdapter(or other Adapters)进行优化,
我们先看看我没有对ListView进行优化之前的写法:
public class MyAdapter extends BaseAdapter {
private ArrayList<Person> mList;
private LayoutInflater mInflater;
public MyAdapter(Context context, ArrayList<Person> list) {
mList = list;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = mInflater.inflate(R.layout.list_item_subject, null);
Person person = (Person) getItem(position);
TextView tv_name = view.findViewById(R.id.tv_name);
TextView tv_age = view.findViewById(R.id.tv_age);
TextView tv_sex = view.findViewById(R.id.tv_sex);
tv_name.setText(person.getName());
tv_age.setText(person.getAge());
tv_sex.setText(person.getSex());
return view;
}
}
package com.nicholasyao.main;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.nicholasyao.models.QListItem;
import com.nicholasyao.models.Subject;
import com.nicholasyao.nijunshuati.R;
import com.nicholasyao.utils.ImageLoader;
public class MyAdapter extends BaseAdapter {
private ArrayList<Person> mList;
private LayoutInflater mInflater;
public MyAdapter(Context context, ArrayList<Person> list) {
mList = list;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item_subject, null);
viewHolder.tv_name = convertView.findViewById(R.id.tv_name);
viewHolder.tv_age = convertView.findViewById(R.id.tv_age);
viewHolder.tv_sex = convertView.findViewById(R.id.tv_sex);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
Person person = (Person) getItem(position);
viewHolder.tv_name.setText(person.getName());
viewHolder.tv_age.setText(person.getAge());
viewHolder.tv_sex.setText(person.getSex());
return convertView;
}
class ViewHolder {
public TextView tv_name;
public TextView tv_age;
public TextView tv_sex;
}
}
</pre><pre class="java" name="code">
</pre><pre class="java" name="code"><span style="font-family:Microsoft YaHei;"></span>
看看这种文艺式的写法,我们利用到另一个参数convertView,是不是进步了
首先说明一个point , convertView参数是可以被listVie缓存的,也就是说下一次调用getView()函数,convertView里
面该有的东西还存在,知道了这个point后我们来------>看代码
每次调用getView(),我们先判断convertView是不是空的,null的话我们再找item布局,再把3个TextView 通过
FindViewById找出来,然后把这次的结果绑定到convertView上面(通过setTag()),这样做是为了解决我们上面逗
比式写法存在的问题,每次getView()都要各种findViewById,我们现在把第一次findViewById的结果绑定到
convertView上,下次调用getView()判断convertView是不是为空,不是的话直接通过getTag()把我们绑定的东西拿
出来用,所以理论上来说,就算有1000个item,我们实际上只是在第一次getView()的时候findViewById一次,其
他时候都是通过从缓存getTag()拿出来用,比起逗比式写法,这种是不是文艺了很多?性能是不是提升了很多?
如果你问代码中的ViewHolder是什么鬼,请运用你面向对象编程的思维思考一下。