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

2019-03-02 00:12|来源: 网路

       这篇文章的效果也是大家常见的,各种通讯应用的对话列表都是这种方式,像微信、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


博主参加了2013博客之星评选,谢谢帮助,投票猛击

http://vote.blog.csdn.net/blogstaritem/blogstar2013/xyz_lmn


/**
 * 比原来的多了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;// 左边的声音时间
	}

}




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

     


Demo下载,请猛击。




/**
* @author 张兴业
*  iOS入门群:83702688
*  android开发进阶群:241395671
*  我的新浪微博:@张兴业TBOW
*/



转自:http://my.oschina.net/201003674/blog/288965

相关问答

更多
  • 名字决定一生!你叫什么名字也许会影响你一辈子。现在的父母给小孩子取名都很讲究,也很重视,因为他们都知道名字太重要的。小孩还没出生,可能已经找了大师或高人取好了名字。父母都希望自己的小孩健康成长,长大后有出息,有成就。名字,是一个终身的符号,每时每刻都影响着一个人。 微信取名与给小孩取名一样重要,微信名代表着你,代表着你的行业,代表着你的品牌,代表着你的产品……名字的背后其实就是你自己,或是你的企业,或是你的品牌,或是你的产品……想像一样,当微友与你的微信在对话的时候,他一定不会认为自己是跟一个手机或一个机器 ...
  • 微信2下载[2023-08-16]

    您好,打开手机浏览器或者是应用商城,然后输入微信进行搜索,在搜索结果中下载安装这款软件即可
  • 主要是在交货前充分做好程序测试,是否能满足你的需求。 另外,售后服务一定要有保证,如果有更新协议的话最好确定更新时间和周期; 基本上就这样,最好选择一些信誉比较好的公司吧。企业开发微信小程序要明确自己的需求。 把需求提交给产品进行设计。 设计和开发做好小程序后提交审核最终上线。
  • 开通微信商城的流程如下: 一、注册微信公众平台的服务号; 我们必须先注册微信公众平台的服务号,因为只有服务号才可能开通支付功能,实现线上的交易。至于如何申请微信公平台请参照我们的《微信公众号的申请和完善》。 二、微信认证服务号(申请公函); 进入微信公众平台之后点击右侧中设置的微信认证,如何搭建自己的微商城(上) 点击之后就会出现微信认证的界面 如何搭建自己的微商城(上) 微信认证 根据提示进行一步一步的认证,我们的公众号认证可以算是基本成型,不过认证的最后是要给腾迅缴纳300元认证费用的。认证通过之后,服 ...
  • 自己开通不了,可以找美基营销代开通
  • 1. 看你的资源是如何的。 2. 如果有好的技术就可以开发小程序。 3. 如果自己有实体的企业可以开发一个自己的小程序。
  • 微信小程序”开发之前必须要完成和注册认证。 您好,开发微信小程序之前必须要完成注册认证,你也可以找微信第三方开发商,具体你可以百度一下。 微信小程序申请流程如下: 1. 进入微信公众平台官方网站,点击右上方“立即注册”。 2. 在选择注册账号类型的页面,点击左下方的“小程序”。 3. 填写需要注册的邮箱、密码以及验证码后,点击“注册”按钮。注意:需要之前没有在公众号注册过的邮箱,每个邮箱仅能申请一个小程序,填写完成以后会发送一封确认邮件到邮箱。 4. 登录注册用的邮箱,激活账号。 5. 接下来填写主题类型、 ...
  • 小程序本身是微信提供的一个平台,使用和注册都是不需要钱的(企业需要300认证费)。注册下来的名字也永久是你的,就是小程序你要用起来里面的功能是需要开发的,要么自己开发要么找第三方合作。
  • 请制作您自己的适配器,可以从BaseAdapter扩展并实现getView()方法,根据您想要的每个项目更改您的布局。 检查这段代码,这可能会有所帮助: public class MyAdapter extends BaseAdapter{ private ArrayList data; private LayoutInflater inflater; public MyAdapter(ArrayList data){ this.da ...