`

ListView具有多种item布局——实现微信对话列(转)

 
阅读更多

转载自:http://blog.csdn.net/xyz_lmn/article/details/13745489

 

       这篇文章的效果也是大家常见的,各种通讯应用的对话列表都是这种方式,像微信、whatsapp、易信、米聊等。我们这篇文章也权当为回忆,形成简单的笔记。这篇文章参考了2009年Google IO中的《TurboChargeYourUI-How to make your AndroidUI fast and efficient》和2010年Google IO中的《The World of List View》。像2009年Google IO的资料还是很前沿的,那会android开发资料很少,最重要的就是参考google发布的各种资料。

 

    在《TurboChargeYourUI-How to make your AndroidUI fast and efficient》介绍了怎样提高listview的性能,优化了listview的加载速度。这里的item使用的是单一布局,能够实现view的重用和回收,那么多种布局文件的怎么办呢,如果再使用上面的方法,view的重用会出现问题,Android使用的BaseAdapter提供了解决多种布局文件的重用方法。

 

1)重写 getViewTypeCount() – 该方法返回多少个不同的布局

2)重写 getItemViewType(int) – 根据position返回相应的Item

3)根据view item的类型,在getView中创建正确的convertView,重用时,也会根据当前需要的类型返回对应类型的convertView

 

 

 

/**
 * 比原来的多了getItemViewType和getViewTypeCount这两个方法,
 * 
 * */
public class ChatAdapter extends BaseAdapter {

	public static final String KEY = "key";
	public static final String VALUE = "value";

	public static final int VALUE_TIME_TIP = 0;// 7种不同的布局
	public static final int VALUE_LEFT_TEXT = 1;
	public static final int VALUE_LEFT_IMAGE = 2;
	public static final int VALUE_LEFT_AUDIO = 3;
	public static final int VALUE_RIGHT_TEXT = 4;
	public static final int VALUE_RIGHT_IMAGE = 5;
	public static final int VALUE_RIGHT_AUDIO = 6;
	private LayoutInflater mInflater;

	private List<Message> myList;

	public ChatAdapter(Context context, List<Message> myList) {
		this.myList = myList;

		mInflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	@Override
	public int getCount() {
		return myList.size();
	}

	@Override
	public Object getItem(int arg0) {
		return myList.get(arg0);
	}

	@Override
	public long getItemId(int arg0) {
		return arg0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup arg2) {

		Message msg = myList.get(position);
		int type = getItemViewType(position);
		ViewHolderTime holderTime = null;
		ViewHolderRightText holderRightText = null;
		ViewHolderRightImg holderRightImg = null;
		ViewHolderRightAudio holderRightAudio = null;
		ViewHolderLeftText holderLeftText = null;
		ViewHolderLeftImg holderLeftImg = null;
		ViewHolderLeftAudio holderLeftAudio = null;
		
		if (convertView == null) {
			switch (type) {
			case VALUE_TIME_TIP:
				holderTime = new ViewHolderTime();
				convertView = mInflater.inflate(R.layout.list_item_time_tip,
						null);
				holderTime.tvTimeTip = (TextView) convertView
						.findViewById(R.id.tv_time_tip);
				holderTime.tvTimeTip.setText(msg.getValue());
				convertView.setTag(holderTime);
				break;
			// 左边
			case VALUE_LEFT_TEXT:
				holderLeftText = new ViewHolderLeftText();
				convertView = mInflater.inflate(R.layout.list_item_left_text,
						null);
				holderLeftText.ivLeftIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				holderLeftText.btnLeftText = (Button) convertView
						.findViewById(R.id.btn_left_text);
				holderLeftText.btnLeftText.setText(msg.getValue());
				convertView.setTag(holderLeftText);
				break;

			case VALUE_LEFT_IMAGE:
				holderLeftImg = new ViewHolderLeftImg();
				convertView = mInflater.inflate(R.layout.list_item_left_iamge,
						null);
				holderLeftImg.ivLeftIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				holderLeftImg.ivLeftImage = (ImageView) convertView
						.findViewById(R.id.iv_left_image);
				holderLeftImg.ivLeftImage.setImageResource(R.drawable.test);
				convertView.setTag(holderLeftImg);
				break;

			case VALUE_LEFT_AUDIO:
				holderLeftAudio = new ViewHolderLeftAudio();
				convertView = mInflater.inflate(R.layout.list_item_left_audio,
						null);
				holderLeftAudio.ivLeftIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				holderLeftAudio.btnLeftAudio = (Button) convertView
						.findViewById(R.id.btn_left_audio);
				holderLeftAudio.tvLeftAudioTime = (TextView) convertView
						.findViewById(R.id.tv_left_audio_time);
				holderLeftAudio.tvLeftAudioTime.setText(msg.getValue());
				convertView.setTag(holderLeftAudio);
				break;
			// 右边
			case VALUE_RIGHT_TEXT:
				holderRightText= new ViewHolderRightText();
				convertView = mInflater.inflate(R.layout.list_item_right_text,
						null);
				holderRightText.ivRightIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				holderRightText.btnRightText = (Button) convertView
						.findViewById(R.id.btn_right_text);
				holderRightText.btnRightText.setText(msg.getValue());
				convertView.setTag(holderRightText);
				break;

			case VALUE_RIGHT_IMAGE:
				holderRightImg= new ViewHolderRightImg();
				convertView = mInflater.inflate(R.layout.list_item_right_iamge,
						null);
				holderRightImg.ivRightIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				holderRightImg.ivRightImage = (ImageView) convertView
						.findViewById(R.id.iv_right_image);
				holderRightImg.ivRightImage.setImageResource(R.drawable.test);
				convertView.setTag(holderRightImg);
				break;

			case VALUE_RIGHT_AUDIO:
				holderRightAudio=new ViewHolderRightAudio();
				convertView = mInflater.inflate(R.layout.list_item_right_audio,
						null);
				holderRightAudio.ivRightIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				holderRightAudio.btnRightAudio = (Button) convertView
						.findViewById(R.id.btn_right_audio);
				holderRightAudio.tvRightAudioTime = (TextView) convertView
						.findViewById(R.id.tv_right_audio_time);
				holderRightAudio.tvRightAudioTime.setText(msg.getValue());
				convertView.setTag(holderRightAudio);
				break;

			default:
				break;
			}
			
		} else {
			Log.d("baseAdapter", "Adapter_:"+(convertView == null) );
			switch (type) {
			case VALUE_TIME_TIP:
				holderTime=(ViewHolderTime)convertView.getTag();
				holderTime.tvTimeTip.setText(msg.getValue());
				break;
			case VALUE_LEFT_TEXT:
				holderLeftText=(ViewHolderLeftText)convertView.getTag();
				holderLeftText.btnLeftText.setText(msg.getValue());
				break;
			case VALUE_LEFT_IMAGE:
				holderLeftImg=(ViewHolderLeftImg)convertView.getTag();
				holderLeftImg.ivLeftImage.setImageResource(R.drawable.test);
				break;
			case VALUE_LEFT_AUDIO:
				holderLeftAudio=(ViewHolderLeftAudio)convertView.getTag();
				holderLeftAudio.tvLeftAudioTime.setText(msg.getValue());
				break;
			case VALUE_RIGHT_TEXT:
				holderRightText=(ViewHolderRightText)convertView.getTag();
				holderRightText.btnRightText.setText(msg.getValue());
				break;
			case VALUE_RIGHT_IMAGE:
				holderRightImg=(ViewHolderRightImg)convertView.getTag();
				holderRightImg.ivRightImage.setImageResource(R.drawable.test);
				break;
			case VALUE_RIGHT_AUDIO:
				holderRightAudio=(ViewHolderRightAudio)convertView.getTag();
				holderRightAudio.tvRightAudioTime.setText(msg.getValue());
				break;

			default:
				break;
			}
			
			//holder = (ViewHolder) convertView.getTag();
		}
		return convertView;
	}

	/**
	 * 根据数据源的position返回需要显示的的layout的type
	 * 
	 * type的值必须从0开始
	 * 
	 * */
	@Override
	public int getItemViewType(int position) {

		Message msg = myList.get(position);
		int type = msg.getType();
		Log.e("TYPE:", "" + type);
		return type;
	}

	/**
	 * 返回所有的layout的数量
	 * 
	 * */
	@Override
	public int getViewTypeCount() {
		return 7;
	}

	class ViewHolderTime {
		private TextView tvTimeTip;// 时间
	}

	class ViewHolderRightText {
		private ImageView ivRightIcon;// 右边的头像
		private Button btnRightText;// 右边的文本
	}

	class ViewHolderRightImg {
		private ImageView ivRightIcon;// 右边的头像
		private ImageView ivRightImage;// 右边的图像
	}

	class ViewHolderRightAudio {
		private ImageView ivRightIcon;// 右边的头像
		private Button btnRightAudio;// 右边的声音
		private TextView tvRightAudioTime;// 右边的声音时间
	}

	class ViewHolderLeftText {
		private ImageView ivLeftIcon;// 左边的头像
		private Button btnLeftText;// 左边的文本
	}

	class ViewHolderLeftImg {
		private ImageView ivLeftIcon;// 左边的头像
		private ImageView ivLeftImage;// 左边的图像
	}

	class ViewHolderLeftAudio {
		private ImageView ivLeftIcon;// 左边的头像
		private Button btnLeftAudio;// 左边的声音
		private TextView tvLeftAudioTime;// 左边的声音时间
	}

}

 

 

分享两张微信、易信的图,你也可以做成这样子。

     

 

 

源码见附件

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    实现微信对话列

    在微信对话列的实现中,我们需要考虑多种类型的item布局,比如文字消息、图片消息、语音消息等,这需要用到ListView的Adapter的自定义功能。 首先,我们需要创建一个继承自BaseAdapter的自定义适配器,这个适配器将...

    按照字母排列——仿照微信联系人

    在Android开发中,我们经常需要实现类似微信联系人列表的功能,即按照姓名的首字母进行排序并分组显示。这个功能的核心在于理解ListView组件、数据排序以及如何利用Adapter来实现字母索引。以下是对这个话题的详细...

    安卓Android源码——高仿微信.zip

    【标题】"安卓Android源码——高仿微信.zip"揭示了这个压缩包包含的是一个针对Android平台的开源项目,目标是实现对微信应用界面的高度模仿。这个项目旨在帮助开发者理解和学习如何在Android平台上构建类似微信的...

    listview 加载不同item 布局

    写的demo只有第一条item布局不一样,剩下的item布局都一样;主要用于实现在listview加上headview时又有下拉...所有就把原本listview要加的headview布局加到listview的item布局中;这样在加下拉刷新控件就不会起冲突了;

    安卓Android源码——简易微信客户端和服务器源码.zip

    这篇文档将深入解析《安卓Android源码——简易微信客户端和服务器源码》的相关知识点,旨在帮助读者理解Android应用开发的基本原理以及如何构建一个简单的微信类通信应用。首先,我们要了解Android系统的基础架构和...

    在Android中ListView多种Item布局的实现

    总的来说,实现Android中ListView多种Item布局的关键在于自定义BaseAdapter,并在`getView()`方法中根据数据动态决定使用哪种布局。聊天界面的实现则需要考虑消息的发送与接收,根据数据的不同属性调整布局样式。这...

    2011.08.26——— android ListView之多个item布局

    这篇博客"2011.08.26——— android ListView之多个item布局"深入探讨了如何在ListView中实现多个不同类型的Item布局,这对于创建动态、丰富的用户界面至关重要。在Android应用设计中,ListView通常用于显示如联系人...

    Android 仿微信对话列表滑动删除效果

    本教程将详细介绍如何在Android项目中实现“仿微信对话列表滑动删除效果”。 首先,我们需要理解滑动删除的核心原理。这种效果通常是通过在ListView或者RecyclerView等滚动视图上添加手势检测来实现的。当用户滑动...

    ListView Item多布局的实现

    然而,有时我们不仅仅满足于单一的列表项布局,而是希望在同一个ListView中展示多种不同的布局,这就是所谓的"ListView Item多布局"。这种功能可以使得应用界面更加丰富多彩,提供更好的用户体验。本文将详细介绍...

    Android中ListView多种Item布局的实现

    它允许用户滚动查看不同条目,并且可以通过自定义适配器实现多种类型的Item布局,以满足各种复杂的界面需求。本篇将深入探讨如何在Android中实现一个模拟聊天界面的ListView,其中包含两种不同的Item布局:一种用于...

    博客《带checkbox的ListView实现(三)——CheckableImageView的实现方法》源码

    博客《带checkbox的ListView实现(三)——CheckableImageView的实现方法》源码,博客地址:http://blog.csdn.net/harvic880925/article/details/41948211

    仿微信对话列表滑动删除功能

    在Android开发中,微信对话列表滑动删除功能是一项常见的用户交互设计,它为用户提供了一种高效、直观的方式来管理他们的聊天记录。实现这个功能主要涉及到ListView或者RecyclerView组件的自定义适配器以及手势检测...

    ListView加载多item布局

    当我们需要在一个ListView中展示多种不同类型的item布局时,这就涉及到"ListView加载多item布局"的技术。本教程将深入探讨如何实现这一功能,并结合性能优化策略,使ListView在处理大量数据时仍能保持流畅的用户体验...

    安卓listview相关相关-android ListView实现显示微信好友列表.rar

    - ListView是一个可滚动的视图,通常用于显示一组具有相同布局的列表项。它可以动态加载数据,以优化内存使用,提高性能。 2. **Adapter原理**: - ListView的工作离不开Adapter,它负责将数据源(如ArrayList)...

    多种Item布局的ListView的优化

    然而,当ListView需要显示多种不同的Item布局时,优化工作变得尤为重要。本教程将深入探讨如何对多种Item布局的ListView进行优化,以提高用户体验和应用性能。 1. **使用ViewHolder模式** ViewHolder模式是优化...

    Android ListView侧滑显示操作项(仿微信消息列表)

    在提供的"ListViewSlidingMenu"文件中,可能包含了实现这一功能的示例代码,包括自定义的ListView项布局、滑动监听器、Adapter等。通过阅读和理解这些代码,开发者可以更好地掌握如何在实际项目中实现类似的功能。 ...

    Android 实现微信界面

    程序总体使用TabHost实现微信界面的四个模块,在每一个tab选项布局里使用自定义的ListView,添加ImageView和TextView控件,显示通讯录列表信息。自定义ListView的列表项布局文件,将每个ListView要显示的内容构成一个...

    listview多种item实现方法

    listview多种item

    android ListView 网格布局

    本文将深入探讨如何在Android中实现一个基于ArrayAdapter的网格布局ListView。 首先,我们要了解ListView的基本结构。ListView是由多个列表项(List Item)组成的,每个列表项通常对应一个View。在Android中,我们...

    博客对应源码

    博客《Animation动画详解(十三)——实现ListView Item进入动画》对应源码,博客地址:http://blog.csdn.net/harvic880925/article/details/50988685

Global site tag (gtag.js) - Google Analytics