listView中多个listItem布局时,convertView缓存及使用

来源:互联网 发布:淘宝旺旺打不开 编辑:程序博客网 时间:2024/06/04 17:44

最近在项目中需要对listview中的数据进行分组,我构思的基本原理就是,在适配器Adapter的getView()方法中,根据当前item类型,分别加载不同的布局,这样是很容易实现的,想必大家都很清楚这个小东西。但是问题是,这样的代码写下来listview在数据很多时,上下滑动会很卡,于是乎就想到了用viewHolder来进行缓存, 难度就在对不同的item进行不同的缓存。

下面是我实现的效果:



第1、 2,3 、 4,5,6 、7、 8,9、  10,11,12......如此循环下去,下面是我实现的代码:


public class listViewTest extends Activity {    /** Called when the activity is first created. */ListView listView;MyAdapter listAdapter;ArrayList<String> listString;     @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        listView = (ListView)this.findViewById(R.id.listview);        listString = new ArrayList<String>();        for(int i = 0 ; i < 100 ; i++)        {        listString.add(Integer.toString(i));        }        listAdapter = new MyAdapter(this);        listView.setAdapter(listAdapter);    }class MyAdapter extends BaseAdapter{Context mContext;LinearLayout linearLayout = null;LayoutInflater inflater;TextView tex;final int VIEW_TYPE = 3;final int TYPE_1 = 0;final int TYPE_2 = 1;final int TYPE_3 = 2;public MyAdapter(Context context) {// TODO Auto-generated constructor stubmContext = context;inflater = LayoutInflater.from(mContext);}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn listString.size();}//每个convert view都会调用此方法,获得当前所需要的view样式@Overridepublic int getItemViewType(int position) {// TODO Auto-generated method stubint p = position%6;if(p == 0)return TYPE_1;else if(p < 3)return TYPE_2;else if(p < 6)return TYPE_3;elsereturn TYPE_1;}@Overridepublic int getViewTypeCount() {// TODO Auto-generated method stubreturn 3;}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn listString.get(arg0);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubviewHolder1 holder1 = null;viewHolder2 holder2 = null;viewHolder3 holder3 = null;int type = getItemViewType(position);//无convertView,需要new出各个控件if(convertView == null){Log.e("convertView = ", " NULL");//按当前所需的样式,确定new的布局switch(type){case TYPE_1:convertView = inflater.inflate(R.layout.listitem1, parent, false);holder1 = new viewHolder1();holder1.textView = (TextView)convertView.findViewById(R.id.textview1);holder1.checkBox = (CheckBox)convertView.findViewById(R.id.checkbox);Log.e("convertView = ", "NULL TYPE_1");convertView.setTag(holder1);break;case TYPE_2:convertView = inflater.inflate(R.layout.listitem2, parent, false);holder2 = new viewHolder2();holder2.textView = (TextView)convertView.findViewById(R.id.textview2);Log.e("convertView = ", "NULL TYPE_2");convertView.setTag(holder2);break;case TYPE_3:convertView = inflater.inflate(R.layout.listitem3, parent, false);holder3 = new viewHolder3();holder3.textView = (TextView)convertView.findViewById(R.id.textview3);holder3.imageView = (ImageView)convertView.findViewById(R.id.imageview);Log.e("convertView = ", "NULL TYPE_3");convertView.setTag(holder3);break;}}else{//有convertView,按样式,取得不用的布局switch(type){case TYPE_1:holder1 = (viewHolder1) convertView.getTag();Log.e("convertView !!!!!!= ", "NULL TYPE_1");break;case TYPE_2:holder2 = (viewHolder2) convertView.getTag();Log.e("convertView !!!!!!= ", "NULL TYPE_2");break;case TYPE_3:holder3 = (viewHolder3) convertView.getTag();Log.e("convertView !!!!!!= ", "NULL TYPE_3");break;}}//设置资源switch(type){case TYPE_1:holder1.textView.setText(Integer.toString(position));holder1.checkBox.setChecked(true);break;case TYPE_2:holder2.textView.setText(Integer.toString(position));break;case TYPE_3:holder3.textView.setText(Integer.toString(position));holder3.imageView.setBackgroundResource(R.drawable.icon);break;}return convertView;}}//各个布局的控件资源class viewHolder1{CheckBox checkBox;TextView textView;}class viewHolder2{TextView textView;}class viewHolder3{ImageView imageView;TextView textView;}}


getViewTypeCoun
在看了AbsListView.java的源代码发现,在ObtainView()方法中,它会来判断当前litview中的type个数,也就是我复写getViewTypeCount()的原因,我们这里有三个不同的item布局,他们都被缓存了起来,所以在getview()方法中,当上下滑动时,就没有必要再重新做inflate和findViewById()的工作,直接使用回收来的viewHolder对象,大大的提高了listview滑动的流畅性。