• Android之ListView性能优化——使用ConvertView和ViewHolder


    使用ConvertView和ViewHolder的优化是针对ListView的Adapter(BaseAdapter)的。这种优化的优点如下:
    1)重用了ConveertView,在很大程度上减少了内存的消耗。通过判断ConvertView是否为NULL,如果是NULL那么就需要生成一个新的View出来(通过LayoutInflater生成),绑定数据后显示给用户;如果ConvertView不是NULL,则我们需要做的就只有绑定数据并呈现给用户。
    2)由于ListView中的Item往往都是只有一个模板,即整个ListView的所有Item用的都是一套ID,所以我们可以把findViewById()方法提取出来,即全程之找一遍ID,这样可以避免让程序不停的做同样的事情。这样做的话通常需要用到另一个内部类(通常写成ViewHolder,在这个类中定义Item中需要用到的控件的名称),这样做也可以方便我们调用控件的onClick()事件等等。
    3)综上,这样做不仅减少了项目性能的消耗,也减少了内存的消耗。

    下面贴代码。先介绍一下这段代码,这是笔者从一个“图灵机器人”的程序中截取出来的一个BaseAdapter,其中的ChatMessage是聊天内容的实体类,其中有text(聊天的内容)、type(对方说话或者我方说话)等属性。代码如下:

     1 public class ChatListAdapter extends BaseAdapter {
     2     public static List<ChatMessage> chatList;
     3     private LayoutInflater inflater;
     4 
     5     public ChatListAdapter(Context context) {
     6         chatList = new ArrayList<ChatMessage>();
     7         inflater = LayoutInflater.from(context);
     8         chatList.add(new ChatMessage("您好,我是小慕,有什么可以帮您的吗?", Type.ANSWER));
     9     }
    10 
    11     @Override
    12     public int getCount() {
    13         return chatList.size();
    14     }
    15 
    16     @Override
    17     public Object getItem(int position) {
    18         return chatList.get(position);
    19     }
    20 
    21     @Override // 返回某个位置的Item的类型(对面说话还是我方说话)
    22     public int getItemViewType(int position) {
    23         // Type是在ChatMessage中定义的枚举类型的变量,有两个枚举值:ASK表示我向“小慕”提问,ANSWER表示“小慕”回答我
    24         if (chatList.get(position).getType() == Type.ASK) {
    25             return 0;
    26         } else {
    27             return 1;
    28         }
    29     }
    30 
    31     @Override // 返回ListView有几种类型的Item
    32     public int getViewTypeCount() {
    33         return 2;
    34     }
    35 
    36     @Override
    37     public long getItemId(int position) {
    38         return position;
    39     }
    40 
    41     @Override // 布局Item
    42     public View getView(int position, View convertView, ViewGroup parent) {
    43         ViewHolder holder;
    44         if (convertView == null) { // 如果为空,就表示是第一次加载,还没有加入到缓存中
    45             holder = new ViewHolder();
    46             if (getItemViewType(position) == 0) { // 我方说话
    47                 convertView = inflater.inflate(R.layout.sideworks_chatlist_item_ask, null);
    48                 holder.time = (TextView) convertView.findViewById(R.id.control_chatitem_ask_time);
    49                 holder.info = (TextView) convertView.findViewById(R.id.control_askitem_message);
    50             } else if (getItemViewType(position) == 1) { // 对方说话
    51                 convertView = inflater.inflate(R.layout.sideworks_chatlist_item_reply, null);
    52                 holder.time = (TextView) convertView.findViewById(R.id.control_chatitem_reply_time);
    53                 holder.info = (TextView) convertView.findViewById(R.id.control_replyitem_message);
    54             }
    55             convertView.setTag(holder); // 加入缓存
    56         } else {
    57             holder = (ViewHolder) convertView.getTag(); // 如果ConvertView不为空,则表示在缓存中
    58         }
    59         holder.time.setText(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    60         holder.info.setText(chatList.get(position).getText());
    61         return convertView;
    62     }
    63 
    64     // 自定义的容器类(相当于一个Item),其中放置着需要我们放置数据的控件的名称
    65     private static class ViewHolder {
    66         TextView time;
    67         TextView info;
    68     }
    69 }

    最后说一下,当我们说了话或者对方说了话,我们就需要更新视图,方法是:先在chatList中添加一条数据,然后调用BaseAdapter(注意一定要是同一个Adapter实例)的notifyDataSetChanged()方法进行刷新。

  • 相关阅读:
    10 款最佳剪贴板管理器
    悉数美剧《黑客军团》中的黑客工具
    Vim的使用方法
    Mysql跨平台(Windows,Linux,Mac)使用与安装
    Linux下网络故障诊断
    RHEL6.2下挂载光驱安装软件
    MySQL数据库服务器的架设
    Unix如何轻松快速复制
    【Linux基础】Linux常用命令汇总
    博客编号数字密码
  • 原文地址:https://www.cnblogs.com/blog-wzy/p/5299193.html
Copyright © 2020-2023  润新知