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

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

 

 

 

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

     

 

Demo下载,请猛击。

 

 

 

 

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

 

 

posted @ 2013-12-22 20:03  张兴业  阅读(1696)  评论(9编辑  收藏  举报