zoukankan      html  css  js  c++  java
  • 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

    [java] view plain copy
     
     
     
     在CODE上查看代码片派生到我的代码片
    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. }  

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

         

    注意:

    使用Listview显示多样视图时,用到了getItemViewType和getViewTypeCount,但是我一运行程序就会报数组越界异常,经过查资料发现,getItemViewType的值一定要从0开始,我开始设置的type类型是从1开始的,结果就悲催了,app一直崩溃,报Java.lang.ArrayIndexOutOfBoundsException。最后把type类型改成从0开始就好了,最后注意一点,getViewTypeCount返回值一定要大于等于getItemViewType的个数。

  • 相关阅读:
    LeetCode 139. Word Break
    Amazon behavior question
    学习笔记之100 TOP Ikm C++ Online Test Questions
    学习笔记之IKM C++ 11
    学习笔记之C/C++指针使用常见的坑
    LeetCode 208. Implement Trie (Prefix Tree)
    队列 & 栈//岛屿的个数
    队列 & 栈//设计循环队列
    队列 & 栈//设计循环队列
    查找表类算法//存在重复元素 III
  • 原文地址:https://www.cnblogs.com/chenliyang/p/6559473.html
Copyright © 2011-2022 走看看