看得懂E文的看此文,分析的很透彻:
http://android.amberfog.com/?p=296
1.场景
在使用ListView时,我们经常遇到需要在一个ListView中显示多种视图的场景,例如:聊天软件的聊天界面中,自己发送的消息在左边显示自己的头像,别人发送的消息在右边显示别人的头像,等等。
2.ListView常用方式
2.1 ListView常用的Adapter有:ArrayAdapter,SimpleAdapter,CursorAdapter。在android sdk sample的ApiDemo工程中有详细的使用方法。
2.2 当我们需要在ListView的视图中展示复杂的数据和资源,处理复杂的事件时,我们可以继承BaseAdapter,重写BaseAdapter中的方法来达到目的,主要是getView(int position, View convertView, ViewGroup parent)方法。在android sdk sample的ApiDemo工程中有详细的使用方法。
2.3 当我们需要在ListView中显示多种视图时,仍然使用继承BaseAdapter的方式,要注意的是getItemViewType(int position)和getViewTypeCount()这两个方法。
3.ListView中显示多种视图的实现方式
3.1 实现步骤
3.1.1 定义试图类型常量
我们定义了三种:
- /**
- * 发送的消息
- */
- private static final int TYPE_SEND = 0;
- /**
- * 收到的消息
- */
- private static final int TYPE_RECEIVE = TYPE_SEND + 1;
- /**
- * 图片
- */
- private static final int TYPE_PIC = TYPE_RECEIVE + 1;
3.1.2 重写getItemViewType(int position)和getViewTypeCount()方法
- public int getItemViewType(int position) {
- int type = super.getItemViewType(position);
- try
- {
- type = Integer.parseInt(data.get(position).get("type"));
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- System.out.println("getItemViewType::" + position + " is " + type);
- return type;
- }
- public int getViewTypeCount() {
- System.out.println("getViewTypeCount is " + 3);
- return 3;
- }
由getItemViewType返回对应项的自定义视图类型,getViewTypeCount返回视图类型总数。
注意:getViewTypeCount返回的值必须比视图类型常量值大,以数组来比喻的话,getViewTypeCount返回的是数组的长度,getItemViewType返回的(即3.1.1中定义的常量)就是数组的下标。
3.1.2 重写getView方法
- public View getView(int position, View convertView, ViewGroup parent) {
- System.out.println("getView::" + position);
- int type = TYPE_SEND;
- try
- {
- type = Integer.parseInt(data.get(position).get("type"));
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- ViewHolder holder = null;
- if (convertView == null)
- {
- System.out.println("getView::convertView is null");
- holder = new ViewHolder();
- switch (type)
- {
- case TYPE_SEND:
- convertView = View.inflate(getBaseContext(),
- R.layout.listitem_send, null);
- holder.text = (TextView) convertView
- .findViewById(R.id.message);
- break;
- case TYPE_RECEIVE:
- convertView = View.inflate(getBaseContext(),
- R.layout.listitem_receive, null);
- holder.text = (TextView) convertView
- .findViewById(R.id.message);
- break;
- case TYPE_PIC:
- convertView = new ImageView(getBaseContext());
- ((ImageView) convertView).setImageResource(R.drawable.icon);
- break;
- }
- convertView.setTag(holder);
- }
- else
- {
- System.out.println("getView::convertView not null");
- holder = (ViewHolder) convertView.getTag();
- }
- if (type != TYPE_PIC)
- {
- String msg = data.get(position).get("content");
- holder.text.setText(msg);
- }
- return convertView;
- }
这一部分和2.2是差不多的,不同的地方在于当convertView为空时,需要根据当前项数据对应的视图类型初始化相应的视图布局。其他像getCount,getItem方法照例重写。
3.2 过程分析
在ListView的父类AbsListView中,有一个变量RecycleBin mRecycler,用来存储某一显示项布局对应的视图。实际存储在 ArrayList<View>[] 中,该数组的长度为getViewTypeCount的返回值。RecycleBin 是AbsListView的一个内部类。
当ListView执行 setAdapter方法时,mRecycler会重置,getViewTypeCount方法会被调用。
当ListView要显示某一项时,getItemViewType方法被调用,根据返回值在mRecycler搜索得到缓存的视图。这也是为什么getViewTypeCount返回值要比定义的视图类型常量值大的原因,否则会导致数组越界异常。
然后调用getView方法,缓存的视图被传递给getView方法的convertView形参(详细可以参考AbsListView的obtainView方法)。
当传递进来的convertView形参为null的话,需要根据该项的视图类型,初始化布局。
最后给显示项填充数据。
下载源码:
http://download.youkuaiyun.com/detail/clarketang/3694460
原文:
1.场景
在使用ListView时,我们经常遇到需要在一个ListView中显示多种视图的场景,例如:聊天软件的聊天界面中,自己发送的消息在左边显示自己的头像,别人发送的消息在右边显示别人的头像,等等。
2.ListView常用方式
2.1 ListView常用的Adapter有:ArrayAdapter,SimpleAdapter,CursorAdapter。在android sdk sample的ApiDemo工程中有详细的使用方法。
2.2 当我们需要在ListView的视图中展示复杂的数据和资源,处理复杂的事件时,我们可以继承BaseAdapter,重写BaseAdapter中的方法来达到目的,主要是getView(int position, View convertView, ViewGroup parent)方法。在android sdk sample的ApiDemo工程中有详细的使用方法。
2.3 当我们需要在ListView中显示多种视图时,仍然使用继承BaseAdapter的方式,要注意的是getItemViewType(int position)和getViewTypeCount()这两个方法。
3.ListView中显示多种视图的实现方式
3.1 实现步骤
3.1.1 定义试图类型常量
我们定义了三种:
- /**
- * 发送的消息
- */
- private static final int TYPE_SEND = 0;
- /**
- * 收到的消息
- */
- private static final int TYPE_RECEIVE = TYPE_SEND + 1;
- /**
- * 图片
- */
- private static final int TYPE_PIC = TYPE_RECEIVE + 1;
3.1.2 重写getItemViewType(int position)和getViewTypeCount()方法
- public int getItemViewType(int position) {
- int type = super.getItemViewType(position);
- try
- {
- type = Integer.parseInt(data.get(position).get("type"));
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- System.out.println("getItemViewType::" + position + " is " + type);
- return type;
- }
- public int getViewTypeCount() {
- System.out.println("getViewTypeCount is " + 3);
- return 3;
- }
由getItemViewType返回对应项的自定义视图类型,getViewTypeCount返回视图类型总数。
注意:getViewTypeCount返回的值必须比视图类型常量值大,以数组来比喻的话,getViewTypeCount返回的是数组的长度,getItemViewType返回的(即3.1.1中定义的常量)就是数组的下标。
3.1.2 重写getView方法
- public View getView(int position, View convertView, ViewGroup parent) {
- System.out.println("getView::" + position);
- int type = TYPE_SEND;
- try
- {
- type = Integer.parseInt(data.get(position).get("type"));
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- ViewHolder holder = null;
- if (convertView == null)
- {
- System.out.println("getView::convertView is null");
- holder = new ViewHolder();
- switch (type)
- {
- case TYPE_SEND:
- convertView = View.inflate(getBaseContext(),
- R.layout.listitem_send, null);
- holder.text = (TextView) convertView
- .findViewById(R.id.message);
- break;
- case TYPE_RECEIVE:
- convertView = View.inflate(getBaseContext(),
- R.layout.listitem_receive, null);
- holder.text = (TextView) convertView
- .findViewById(R.id.message);
- break;
- case TYPE_PIC:
- convertView = new ImageView(getBaseContext());
- ((ImageView) convertView).setImageResource(R.drawable.icon);
- break;
- }
- convertView.setTag(holder);
- }
- else
- {
- System.out.println("getView::convertView not null");
- holder = (ViewHolder) convertView.getTag();
- }
- if (type != TYPE_PIC)
- {
- String msg = data.get(position).get("content");
- holder.text.setText(msg);
- }
- return convertView;
- }
这一部分和2.2是差不多的,不同的地方在于当convertView为空时,需要根据当前项数据对应的视图类型初始化相应的视图布局。其他像getCount,getItem方法照例重写。
3.2 过程分析
在ListView的父类AbsListView中,有一个变量RecycleBin mRecycler,用来存储某一显示项布局对应的视图。实际存储在 ArrayList<View>[] 中,该数组的长度为getViewTypeCount的返回值。RecycleBin 是AbsListView的一个内部类。
当ListView执行 setAdapter方法时,mRecycler会重置,getViewTypeCount方法会被调用。
当ListView要显示某一项时,getItemViewType方法被调用,根据返回值在mRecycler搜索得到缓存的视图。这也是为什么getViewTypeCount返回值要比定义的视图类型常量值大的原因,否则会导致数组越界异常。
然后调用getView方法,缓存的视图被传递给getView方法的convertView形参(详细可以参考AbsListView的obtainView方法)。
当传递进来的convertView形参为null的话,需要根据该项的视图类型,初始化布局。
最后给显示项填充数据。
下载源码:
http://download.youkuaiyun.com/detail/clarketang/3694460
原文:http://blog.youkuaiyun.com/clarketang/article/details/6873393