listView多个viewType,listView多个类型的item

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

下面是我实现的效果:

listView多个viewType,listView多个类型的item_第1张图片


第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 listString;
 	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listView = (ListView)this.findViewById(R.id.listview);
        listString = new ArrayList();
        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 stub
		mContext = context;
		inflater = LayoutInflater.from(mContext);
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return listString.size();
	}

	//每个convert view都会调用此方法,获得当前所需要的view样式
	@Override
	public int getItemViewType(int position) {
		// TODO Auto-generated method stub
		int p = position%6;
		if(p == 0)
			return TYPE_1;
		else if(p < 3)
			return TYPE_2;
		else if(p < 6)
			return TYPE_3;
		else
			return TYPE_1;
		
	}

	@Override
	public int getViewTypeCount() {
		// TODO Auto-generated method stub
		return 3;
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return listString.get(arg0);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		viewHolder1 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滑动的流畅性。

你可能感兴趣的:(小项目,Android)