这篇文章的效果也是大家常见的,各种通讯应用的对话列表都是这种方式,像微信、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. .net中对象序列化技术浅谈

    .net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...

  2. Seo的几个境界

    Seo的境界 第一层,弄些关键词排名上去. 是的,大部分人理解的Seoer,就到此为止 这里有技巧若干若干.很值得一些人去卖弄. 第二层,大量广泛的收录,很好的pr值 恭喜您,把握搜索长尾, 这种不显 ...

  3. paip. 解决java程序不能自动退出

    paip. 解决java程序不能自动退出 原因:有东西在运行,所以,不能自动退出.. 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址: ...

  4. Apache JMeter 测试Http请求

    环境安装:JDK 下载:http://jmeter.apache.org/download_jmeter.cgi 启动: 简单HTTP请求测试

  5. 使用iMovie和Keynote制作App Preview

    App Preview是什么 App Preview就是一段15-30秒的短视频,用来展示你的应用的特性.用户界面.交互方式等内容.在App Store你的应用的详细信息页面里,放在原来的截图之前.体 ...

  6. 使用vs自带的性能诊断工具

    visual studio是个强大的集成开发环境,内置了程序性能诊断工具.下面通过两段代码进行介绍. static void Main( string[] args) { Test1(); Test2 ...

  7. Maven之问题解决汇总

    Maven使用中,遇到的问题及解决办法记录下来 pom.xml顶部报错问题解决方法:http://stackoverflow.com/questions/5074063/maven-error-fai ...

  8. 刷连记录的迟到检测---Table表格增加一列值

    公司OA新增加了 刷脸记录 ,用于查看自己是否迟到,但是没有什么提醒,于是乎自己写了一个脚本 刷连记录 类似于这样的: 运行脚本后,是这个样子的: 擦,我本月已经迟到了 3次了.... 拖拽 刷脸记录 ...

  9. Awesome C/C++

    Awesome C/C++ A curated list of awesome C/C++ frameworks, libraries, resources, and shiny things. In ...

  10. 【linux】vim编辑器vim+taglist+ctags的配置

    很多linux软件开发实际上并不实在X window的情况下进行的,这时我们不可能启动基于X window的图形化窗口,在这一情况下我们所能使用的主要的编辑器是vim和emacs.(ps:emacs和 ...