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

  1. /**
  2. * 比原来的多了getItemViewType和getViewTypeCount这两个方法,
  3. *
  4. * */
  5. public class ChatAdapter extends BaseAdapter {
  6. public static final String KEY = "key";
  7. public static final String VALUE = "value";
  8. public static final int VALUE_TIME_TIP = 0;// 7种不同的布局
  9. public static final int VALUE_LEFT_TEXT = 1;
  10. public static final int VALUE_LEFT_IMAGE = 2;
  11. public static final int VALUE_LEFT_AUDIO = 3;
  12. public static final int VALUE_RIGHT_TEXT = 4;
  13. public static final int VALUE_RIGHT_IMAGE = 5;
  14. public static final int VALUE_RIGHT_AUDIO = 6;
  15. private LayoutInflater mInflater;
  16. private List<Message> myList;
  17. public ChatAdapter(Context context, List<Message> myList) {
  18. this.myList = myList;
  19. mInflater = (LayoutInflater) context
  20. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  21. }
  22. @Override
  23. public int getCount() {
  24. return myList.size();
  25. }
  26. @Override
  27. public Object getItem(int arg0) {
  28. return myList.get(arg0);
  29. }
  30. @Override
  31. public long getItemId(int arg0) {
  32. return arg0;
  33. }
  34. @Override
  35. public View getView(int position, View convertView, ViewGroup arg2) {
  36. Message msg = myList.get(position);
  37. int type = getItemViewType(position);
  38. ViewHolderTime holderTime = null;
  39. ViewHolderRightText holderRightText = null;
  40. ViewHolderRightImg holderRightImg = null;
  41. ViewHolderRightAudio holderRightAudio = null;
  42. ViewHolderLeftText holderLeftText = null;
  43. ViewHolderLeftImg holderLeftImg = null;
  44. ViewHolderLeftAudio holderLeftAudio = null;
  45. if (convertView == null) {
  46. switch (type) {
  47. case VALUE_TIME_TIP:
  48. holderTime = new ViewHolderTime();
  49. convertView = mInflater.inflate(R.layout.list_item_time_tip,
  50. null);
  51. holderTime.tvTimeTip = (TextView) convertView
  52. .findViewById(R.id.tv_time_tip);
  53. holderTime.tvTimeTip.setText(msg.getValue());
  54. convertView.setTag(holderTime);
  55. break;
  56. // 左边
  57. case VALUE_LEFT_TEXT:
  58. holderLeftText = new ViewHolderLeftText();
  59. convertView = mInflater.inflate(R.layout.list_item_left_text,
  60. null);
  61. holderLeftText.ivLeftIcon = (ImageView) convertView
  62. .findViewById(R.id.iv_icon);
  63. holderLeftText.btnLeftText = (Button) convertView
  64. .findViewById(R.id.btn_left_text);
  65. holderLeftText.btnLeftText.setText(msg.getValue());
  66. convertView.setTag(holderLeftText);
  67. break;
  68. case VALUE_LEFT_IMAGE:
  69. holderLeftImg = new ViewHolderLeftImg();
  70. convertView = mInflater.inflate(R.layout.list_item_left_iamge,
  71. null);
  72. holderLeftImg.ivLeftIcon = (ImageView) convertView
  73. .findViewById(R.id.iv_icon);
  74. holderLeftImg.ivLeftImage = (ImageView) convertView
  75. .findViewById(R.id.iv_left_image);
  76. holderLeftImg.ivLeftImage.setImageResource(R.drawable.test);
  77. convertView.setTag(holderLeftImg);
  78. break;
  79. case VALUE_LEFT_AUDIO:
  80. holderLeftAudio = new ViewHolderLeftAudio();
  81. convertView = mInflater.inflate(R.layout.list_item_left_audio,
  82. null);
  83. holderLeftAudio.ivLeftIcon = (ImageView) convertView
  84. .findViewById(R.id.iv_icon);
  85. holderLeftAudio.btnLeftAudio = (Button) convertView
  86. .findViewById(R.id.btn_left_audio);
  87. holderLeftAudio.tvLeftAudioTime = (TextView) convertView
  88. .findViewById(R.id.tv_left_audio_time);
  89. holderLeftAudio.tvLeftAudioTime.setText(msg.getValue());
  90. convertView.setTag(holderLeftAudio);
  91. break;
  92. // 右边
  93. case VALUE_RIGHT_TEXT:
  94. holderRightText= new ViewHolderRightText();
  95. convertView = mInflater.inflate(R.layout.list_item_right_text,
  96. null);
  97. holderRightText.ivRightIcon = (ImageView) convertView
  98. .findViewById(R.id.iv_icon);
  99. holderRightText.btnRightText = (Button) convertView
  100. .findViewById(R.id.btn_right_text);
  101. holderRightText.btnRightText.setText(msg.getValue());
  102. convertView.setTag(holderRightText);
  103. break;
  104. case VALUE_RIGHT_IMAGE:
  105. holderRightImg= new ViewHolderRightImg();
  106. convertView = mInflater.inflate(R.layout.list_item_right_iamge,
  107. null);
  108. holderRightImg.ivRightIcon = (ImageView) convertView
  109. .findViewById(R.id.iv_icon);
  110. holderRightImg.ivRightImage = (ImageView) convertView
  111. .findViewById(R.id.iv_right_image);
  112. holderRightImg.ivRightImage.setImageResource(R.drawable.test);
  113. convertView.setTag(holderRightImg);
  114. break;
  115. case VALUE_RIGHT_AUDIO:
  116. holderRightAudio=new ViewHolderRightAudio();
  117. convertView = mInflater.inflate(R.layout.list_item_right_audio,
  118. null);
  119. holderRightAudio.ivRightIcon = (ImageView) convertView
  120. .findViewById(R.id.iv_icon);
  121. holderRightAudio.btnRightAudio = (Button) convertView
  122. .findViewById(R.id.btn_right_audio);
  123. holderRightAudio.tvRightAudioTime = (TextView) convertView
  124. .findViewById(R.id.tv_right_audio_time);
  125. holderRightAudio.tvRightAudioTime.setText(msg.getValue());
  126. convertView.setTag(holderRightAudio);
  127. break;
  128. default:
  129. break;
  130. }
  131. } else {
  132. Log.d("baseAdapter", "Adapter_:"+(convertView == null) );
  133. switch (type) {
  134. case VALUE_TIME_TIP:
  135. holderTime=(ViewHolderTime)convertView.getTag();
  136. holderTime.tvTimeTip.setText(msg.getValue());
  137. break;
  138. case VALUE_LEFT_TEXT:
  139. holderLeftText=(ViewHolderLeftText)convertView.getTag();
  140. holderLeftText.btnLeftText.setText(msg.getValue());
  141. break;
  142. case VALUE_LEFT_IMAGE:
  143. holderLeftImg=(ViewHolderLeftImg)convertView.getTag();
  144. holderLeftImg.ivLeftImage.setImageResource(R.drawable.test);
  145. break;
  146. case VALUE_LEFT_AUDIO:
  147. holderLeftAudio=(ViewHolderLeftAudio)convertView.getTag();
  148. holderLeftAudio.tvLeftAudioTime.setText(msg.getValue());
  149. break;
  150. case VALUE_RIGHT_TEXT:
  151. holderRightText=(ViewHolderRightText)convertView.getTag();
  152. holderRightText.btnRightText.setText(msg.getValue());
  153. break;
  154. case VALUE_RIGHT_IMAGE:
  155. holderRightImg=(ViewHolderRightImg)convertView.getTag();
  156. holderRightImg.ivRightImage.setImageResource(R.drawable.test);
  157. break;
  158. case VALUE_RIGHT_AUDIO:
  159. holderRightAudio=(ViewHolderRightAudio)convertView.getTag();
  160. holderRightAudio.tvRightAudioTime.setText(msg.getValue());
  161. break;
  162. default:
  163. break;
  164. }
  165. //holder = (ViewHolder) convertView.getTag();
  166. }
  167. return convertView;
  168. }
  169. /**
  170. * 根据数据源的position返回需要显示的的layout的type
  171. *
  172. * type的值必须从0开始
  173. *
  174. * */
  175. @Override
  176. public int getItemViewType(int position) {
  177. Message msg = myList.get(position);
  178. int type = msg.getType();
  179. Log.e("TYPE:", "" + type);
  180. return type;
  181. }
  182. /**
  183. * 返回所有的layout的数量
  184. *
  185. * */
  186. @Override
  187. public int getViewTypeCount() {
  188. return 7;
  189. }
  190. class ViewHolderTime {
  191. private TextView tvTimeTip;// 时间
  192. }
  193. class ViewHolderRightText {
  194. private ImageView ivRightIcon;// 右边的头像
  195. private Button btnRightText;// 右边的文本
  196. }
  197. class ViewHolderRightImg {
  198. private ImageView ivRightIcon;// 右边的头像
  199. private ImageView ivRightImage;// 右边的图像
  200. }
  201. class ViewHolderRightAudio {
  202. private ImageView ivRightIcon;// 右边的头像
  203. private Button btnRightAudio;// 右边的声音
  204. private TextView tvRightAudioTime;// 右边的声音时间
  205. }
  206. class ViewHolderLeftText {
  207. private ImageView ivLeftIcon;// 左边的头像
  208. private Button btnLeftText;// 左边的文本
  209. }
  210. class ViewHolderLeftImg {
  211. private ImageView ivLeftIcon;// 左边的头像
  212. private ImageView ivLeftImage;// 左边的图像
  213. }
  214. class ViewHolderLeftAudio {
  215. private ImageView ivLeftIcon;// 左边的头像
  216. private Button btnLeftAudio;// 左边的声音
  217. private TextView tvLeftAudioTime;// 左边的声音时间
  218. }
  219. }

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

     

Demo下载,请猛击。

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

ListView具有多种item布局——实现微信对话列的更多相关文章

  1. ListView实现多种item布局的方法和注意事项

    这篇文章的效果也是大家常见的,各种通讯应用的对话列表都是这种方式,像微信.whatsapp.易信.米聊等.我们这篇文章也权当为回忆,形成简单的笔记.这篇文章参考了2009年Google IO中的< ...

  2. 对RecycleView的多种item布局的封装

    本文是借鉴bingoogolapple写得BGAAdapter-Android而产生的,对此表示感谢. 效果 1.Adapter的使用 1.继承BaseAdapter 这里是我的adapter pub ...

  3. listView 多个item布局

    package kds.szkingdom.wo.android.adapter; import java.util.List; import android.content.Context; imp ...

  4. ListView之多种类型Item

    一.概述 一般而言,listview每个item的样式是一样的,但也有很多应用场景下不同位置的item需要不同的样式. 拿微信举例,前者的代表作是消息列表,而后者的典型则是聊天会话界面. 本文重点介绍 ...

  5. ListView 完全优化 + 多种listitem布局处理

    #  百度了下,感觉下面的博客文章还都挺全面的,写的很好,直接分享得了 Android性能优化--Listview优化 - tonycheng93 - 博客园http://www.cnblogs.co ...

  6. Android进阶笔记11:ListView篇之ListView显示多种类型的条目(item)

    ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...

  7. Android进阶笔记10:ListView篇之ListView显示多种类型的条目(item)

    ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...

  8. RecyclerView的使用之多种Item加载布局

    精益求精,为了更加透彻熟练得掌握,本文再次给大家介石介绍下如何利用RecyclerView实现多Item布局的加载,多Item布局的加载的意思就是在开发过程中List的每一项可能根据需求的不同会加载不 ...

  9. 【转】Android ListView加载不同的item布局

    原创教程,转载请保留出处:http://www.eoeandroid.com/thread-72369-1-1.html     最近有需求需要在listView中载入不同的listItem布局,开始 ...

随机推荐

  1. [Python爬虫] 在Windows下安装PIP+Phantomjs+Selenium

    最近准备深入学习Python相关的爬虫知识了,如果说在使用Python爬取相对正规的网页使用"urllib2 + BeautifulSoup + 正则表达式"就能搞定的话:那么动态 ...

  2. MySQL的几种连接 join/inner join/cross join/逗号/left join/right join/natural join

    转载请注明出处!! 之前数据表连接操作多使用逗号或者join,对几种连接的概念一直浑浑噩噩,最近研究了一波,把这些连接的区别搞明白了.   连接:A xjoin B(主表 操作 关联表)  selec ...

  3. Leetcode 342 Power of Four 数论

    题意:判断一个数是不是4的幂数,和Power of two类似. 先判断num是否大于0,再判断num是否能开根号,最后判断num开根号后的数是否是2^15的约数. 提示:4的幂数开根号就是2的幂数. ...

  4. Leetcode 66 Plus One STL

    题意让大数加1 我的做法是先让个位+1,再倒置digits,然后进位,最后倒置digits,得到答案. class Solution { public: vector<int> plusO ...

  5. 如何将Scrapy 部署到Scrapyd上?

    安装上传工具 1.上传工具 scrapyd-client 2.安装方法: pip install scrapyd-client 3.上传方法: python d:\Python27\Scripts\s ...

  6. 微软BI 之SSIS 系列 - 利用 SSIS 模板快速开发 SSIS Package

    开篇介绍 在做 ETL 项目的时候,往往很多 Package 的开发都是基于相同的模型和流程.比如在 Package 开始运行时需要向 Process Log 表中插入记录,在 Package 运行结 ...

  7. ubuntu 12.04 "系统的网络服务与此版本的网络管理器不兼容

    ubuntu 12.04 "系统的网络服务与此版本的网络管理器不兼容“ 2013-05-10 21:18 2271人阅读 评论(0) 收藏 举报 今天上午在实验室一顿乱整,不知道整坏了什么, ...

  8. Android JNI HelloWorld实现

    创建一个JNIDemo的Android工程 在项目下创建一个文件夹jni.(注意必须是jni目录) 在jni目录下创建两个文件:Android.mk 和 first_jni.c(.c文件的名字可以任意 ...

  9. 什么是automatic variable?

    看代码符号$?搞不清楚是什么?   看代码. $share = Get-WmiObject -Class Win32_Share -ComputerName $Server.name -Credent ...

  10. Spring MVC+Quartz 定时任务持久化

    请自行参考: http://sloanseaman.com/wordpress/2011/06/06/spring-and-quartz-and-persistence/ https://object ...