Android之ListView包含多种类型的Item

一般情况下,ListView中的Item的类型的都是相同的,即每个Item的布局都调用的同一个XML。但是我们现在的需求需要ListView包含多种类型,需要如何实现呢?

是的,就是覆写Adapter的getItemViewType(int position)和get ViewTypeCount()方法。

getItemViewType(int position)代表第position个Item的类型是什么,返回值为 int值。并且在getView中调用这个方法,并且根据返回值值的类型加载不同的布局。

get ViewTypeCount()表示Item类型种类的个数。


这里我们实现3中类型的Item。

首先构建3个ViewHolder类型,然后根据getItemViewType的返回值,在getView中加载不同ViewHolder。

这里不知道ViewHolder的同学,请看Android之ListView性能优化 里面讲解了通过convertView以及ViewHolder来优化ListView性能


package com.example.listviewbaseadapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class BaseAdapterListView extends Activity {
	private ListView listview;
	private List<Map<String, Object>> data; // List集合中的对象是一个Map对象,而这个Map对象的键是String类型,值是Object类型
	public final static int Type_1 = 0;
	public final static int Type_2 = 1;
	public final static int Type_3 = 2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_base_adapter_list_view);

		listview = (ListView) findViewById(R.id.lv);
		listview.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// TODO Auto-generated method stub
				Log.d("base", "item has worked");
			}
		});
		// 将要绑定的数据赋给data
		data = getData();
		MyAdapter adapter = new MyAdapter(this);
		listview.setAdapter(adapter);

	}

	private List<Map<String, Object>> getData() {
		// TODO Auto-generated method stub
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		Map<String, Object> map;
		// 遍历
		for (int x = 0; x < 50; x++) {
			map = new HashMap<String, Object>();
			map.put("button", "button" + x);
			map.put("text1", "优化ListView" + x);
			map.put("text2", "重写BaseAdapter" + x);

			list.add(map);
		}
		Log.v("myu", "list count="+list.size());
		return list;
	}

	// 通过ViewHolder静态类结合缓存convertView优化ListView性能
	// 使用 ViewHolder 的好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。
	static class ViewHolder1 {
		public Button btn;
		public TextView text1;
		public TextView text2;
	}

	static class ViewHolder2 {
		public TextView text3;
	}

	static class ViewHolder3 {
		public ImageView imageView3;
	}

	public class MyAdapter extends BaseAdapter {

		private LayoutInflater mInflater = null;

		private MyAdapter(Context context) {
			// 根据context上下文加载布局
			mInflater = LayoutInflater.from(context);
		}

		@Override
		public int getCount() {
			Log.v("myu", "getCount()");
			// TODO Auto-generated method stub
			// 在此适配器中所代表的数据集中的条目数
			// 系统首先调用getCount()函数,根据他的返回值得到listView的长度,然后根据这个长度,调用getView()逐一绘制每一行
			// 如果你的getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。
			return data.size();
		}

		@Override
		public Object getItem(int position) {
			Log.v("myu", "getItem(" +position +")");
			// TODO Auto-generated method stub
			// 获取数据集中与指定索引对应的数据项
			return position;
		}

		@Override
		public long getItemId(int position) {
			Log.v("myu", "getItemId(" +position +")");
			// TODO Auto-generated method stub
			// 获取在列表中与指定索引对应的行id
			return position;
		}

		@Override
		public int getItemViewType(int position) {
			// TODO Auto-generated method stub
			Log.v("myu", "getItemViewType " + position);
			if (position % 3 == 0) {
				return Type_1;
			} else if (position % 3 == 1) {
				return Type_2;
			} else {
				return Type_3;
			}
		}

		@Override
		public int getViewTypeCount() {
			Log.v("myu", "getViewTypeCount() ");
			// TODO Auto-generated method stub
			return 3;
		}

		// 获取一个在数据集中指定索引的视图来显示数据
		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			Log.v("myu", "getView("+ position+") ");
			// TODO Auto-generated method stub
			ViewHolder1 holder = null;
			ViewHolder2 holder2 = null;
			ViewHolder3 holder3 = null;
			int type = getItemViewType(position);
			Log.v("myu", "getView " + position + " " + convertView + " type = "
					+ type);

			// 如果缓存convertView为空,则需要创建View
			if (convertView == null) {

				switch (type) {
				case Type_1:
					holder = new ViewHolder1();
					convertView = mInflater.inflate(R.layout.item, null);
					holder.btn = (Button) convertView.findViewById(R.id.btn1);
					holder.btn.setText("button"+position);
					holder.text1 = (TextView) convertView
							.findViewById(R.id.text1);
					holder.text2 = (TextView) convertView
							.findViewById(R.id.text2);

					// 将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
					// 绑定ViewHolder对象
					convertView.setTag(holder);
					break;
				case Type_2:
					holder2 = new ViewHolder2();
					convertView = mInflater.inflate(R.layout.item2, null);
					holder2.text3 = (TextView) convertView
							.findViewById(R.id.text3);
					holder2.text3.setText(data.get(position).get("text1")
							.toString());

					convertView.setTag(holder2);
					break;
				case Type_3:
					holder3 = new ViewHolder3();
					convertView = mInflater.inflate(R.layout.item3, null);
					holder3.imageView3 = (ImageView) convertView
							.findViewById(R.id.imageView);

					convertView.setTag(holder2);
					break;

				default:
					break;
				}

			} else {
				switch (type) {
				case Type_1:
					holder = (ViewHolder1) convertView.getTag();// 取出ViewHolder对象
					/** 设置控件显示的内容,即我们存放在动态数组中的数据 */
					holder.btn.setText((String) data.get(position)
							.get("button")); // 通过get("button")
												// 与MAP做KEY对应
					holder.text1.setText((String) data.get(position).get(
							"text1"));
					holder.text2.setText((String) data.get(position).get(
							"text2"));
					holder.btn.setOnClickListener(new OnClickListener() {

						@Override
						public void onClick(View v) {
							// TODO Auto-generated method stub
							Log.v("base", "你点击了按钮");
							data.remove(position); // 移除该item
							MyAdapter.this.notifyDataSetChanged(); // 刷新ListView
						}
					});
					break;
				case Type_2:
					holder2 = (ViewHolder2) convertView.getTag();
					holder2.text3.setText(data.get(position).get("text1")
							.toString());
					break;
				case Type_3:
					holder3 = (ViewHolder3) convertView.getTag();
					break;

				default:
					break;
				}

			}

			return convertView;
		}

	}

}

效果图:



三种类型的Item分别为一个包含Button和两个TextView、一个只包含TextView、一个只包含ImageView  

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值