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. publicclass ChatAdapter extends BaseAdapter { 
  6.  
  7.     publicstaticfinal String KEY = "key"
  8.     publicstaticfinal String VALUE = "value"
  9.  
  10.     publicstaticfinalint VALUE_TIME_TIP = 0;// 7种不同的布局 
  11.     publicstaticfinalint VALUE_LEFT_TEXT = 1
  12.     publicstaticfinalint VALUE_LEFT_IMAGE = 2
  13.     publicstaticfinalint VALUE_LEFT_AUDIO = 3
  14.     publicstaticfinalint VALUE_RIGHT_TEXT = 4
  15.     publicstaticfinalint VALUE_RIGHT_IMAGE = 5
  16.     publicstaticfinalint 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.     publicint 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.     publiclong 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.     publicint 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.     publicint getViewTypeCount() { 
  210.         return7
  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.  

 

 

 

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

    

 

Demo下载,请猛击。

posted @ 2013-12-31 17:50  萧萧  阅读(116)  评论(0)    收藏  举报