zoukankan      html  css  js  c++  java
  • Android ListView多布局讲解

     Listview优化是一个老生常谈的事情了,其优化的方面也有很多种,例如,布局重用、在getView()中减少逻辑计算、减少在页面滑动的时候加在图片,而是在页面停止滚动的时候再加在图片。而今天要介绍的是另一种方式,那就是多布局。

    一般使用的场景有一下两种情况:

    ① 当一个item有多重布局的情况下,使用部分隐藏来实现既笨拙又效率低下,这时多布局会是个不错的选择;

    ② 当一个item很复杂,页面内容多,item高度很高,甚至超过手机屏幕,这个时候就需要使用多布局将页面拆分成多个小item来提高执行效率。

    举个栗子:如下销售订单列表,我们发现一个单个item的页面高度很高,内容也很多,中部的商品个数还具有不确定性,这时的实现的方式我们可以看下:

     代码如下:

     1 @Override
     2 public View getView(final int position, View convertView, ViewGroup rootview) {
     3      ViewHolder viewHolder = null;
     4      if (convertView == null) {
     5          viewHolder = new ViewHolder();
     6          convertView = inflater.inflate(R.layout.item_list_order, rootview, false);
     7          // ...
     8          convertView.setTag(viewHolder);
     9      } else {
    10          viewHolder = (ViewHolder) convertView.getTag();
    11      }
    12  
    13      for (int i = 0; i < arrListOrder.get(position).size(); i++) {
    14          View v = inflater.inflate(R.layout.item_order_goods, null);
    15          // ...
    16          viewHolder.llayoutGoodsList.addView(v);
    17      }
    18  
    19      // ...
    20      return convertView;
    21 }

    这种写法诟病很大,严重影响性能,此外如果商品数量有个10个8个的会导致item过高,此外在getView()中for循环new布局对象是是否消耗内存的和执行时间的。

    那么,我们用多布局拆分下:

    这种布局方式就叫ListView的多布局。采用将一个大的 item 切割成多个小item以降低布局的复杂度,提高重用率。那么直接看这种方式的实现方式:

     1 public class OrderListActivity extends Activity {
     2     // ...
     3 
     4     /** 解析请求数据 */
     5     private ArrayList<HashMap<String, Object>> analyticalData(String json) {
     6         ArrayList<HashMap<String, Object>> arrListGoods = new ArrayList<>();
     7         try {
     8             JSONArray jsArr = new JSONArray(json);
     9             for (int i = 0; i < jsArr.length(); i++) {
    10                 JSONObject jsObj = jsArr.optJSONObject(i);
    11                 // 头部
    12                 hashMapHead.put("order_sn", jsObj.optString("order_sn")); // 销售订单号
    13                 // ...
    14                 hashMapHead.put("item_type", OrderListAdapter.NI_ORDER_ITEM_HEAD); // 设置布局类型
    15                 arrListGoods.add(hashMapHead);
    16 
    17                 // 商品
    18                 JSONArray arrJsonGoods = jsObj.getJSONArray("order_goods");
    19                 JSONObject jsobjPay = new JSONObject();
    20                 for (int j = 0; j < arrJsonGoods.length(); i++) {
    21                     HashMap<String, Object> hashMapGoods = new HashMap<>();
    22                     hashMapHead.put("goods_name", jsObj.optString("goods_name")); //商品名
    23                     // ...
    24                     hashMapHead.put("item_type", OrderListAdapter.NI_ORDER_ITEM_GOODS);
    25                     arrListGoods.add(hashMapGoods);
    26                 }
    27 
    28                 // 底部
    29                 HashMap<String, Object> hashMapFoot = new HashMap<>();
    30                 hashMapFoot.put("address", jsObj.optString("address")); // 地址
    31                 // ... 
    32                 hashMapHead.put("item_type", OrderListAdapter.NI_ORDER_ITEM_FOOT);
    33                 arrListGoods.add(hashMapFoot);
    34             }
    35         } catch (JSONException e) {
    36             return null;
    37         }
    38         return arrListGoods;
    39     }
    40 }
     1 public class OrderListAdapter extends BaseAdapter {
     2 
     3     public static final int NI_ORDER_ITEM_HEAD = 0; // 这要从0按顺序往下变化,否则报错“数组下标溢出”,原因还不清楚
     4     public static final int NI_ORDER_ITEM_GOODS = 1;
     5     public static final int NI_ORDER_ITEM_FOOT = 2;
     6 
     7     // ...
     8     /** 获取布局的类型 */
     9     @Override
    10     public int getItemViewType(int position) {
    11         try {
    12             int i = Integer.parseInt(mAppList.get(position).get("item_type").toString());
    13             switch (i){
    14                 case NI_ORDER_ITEM_HEAD:
    15                 case NI_ORDER_ITEM_GOODS:
    16                 case NI_ORDER_ITEM_FOOT:
    17                     return i;
    18             }
    19         } catch (Exception e) {
    20         }
    21         return super.getItemViewType(position);
    22     }
    23     /** 获取布局类型的总数 */
    24     @Override
    25     public int getViewTypeCount() {
    26         return 3;
    27     }
    28 
    29     @Override
    30     public View getView(int position, View convertView, ViewGroup rootview) {
    31         ViewHolder viewHolderHead = null;
    32         ViewHolder viewHolderGoods = null;
    33         ViewHolder viewHolderFoot = null;
    34         int type = getItemViewType(position);
    35         if (convertView == null) {
    36             switch(type){
    37                 case NI_ORDER_ITEM_HEAD:
    38                     viewHolderHead = new viewHolderHead();
    39                     convertView = mInflater.inflate(R.layout.item_list_order_head, rootview, false);
    40                     // ...初始化布局
    41                     convertView.setTag(R.layout.item_list_order_head, viewHolderHead); // 这里要用setTag(int, Object);
    42                     break;
    43                 case NI_ORDER_ITEM_GOODS:
    44                     viewHolderGoods = new viewHolderGoods();
    45                     convertView = mInflater.inflate(R.layout.item_list_order_goods, rootview, false);
    46                     // ...初始化布局
    47                     convertView.setTag(R.layout.item_list_order_goods, viewHolderGoods);
    48                     break;
    49                 case NI_ORDER_ITEM_FOOT: 
    50                     viewHolderFoot = new viewHolderFoot();
    51                     convertView = mInflater.inflate(R.layout.item_list_order_foot, rootview, false);
    52                     // ...初始化布局
    53                     convertView.setTag(R.layout.item_list_order_foot, viewHolderFoot);
    54                     break;
    55             }
    56         } else {
    57             switch(type){
    58                 case NI_ORDER_ITEM_HEAD:
    59                     viewHolderHead = getTag(R.layout.item_list_order_head);
    60                     break;
    61                 case NI_ORDER_ITEM_GOODS:
    62                     viewHolderGoods = getTag(R.layout.item_list_order_goods);
    63                     break;
    64                 case NI_ORDER_ITEM_FOOT:
    65                     viewHolderFoot = getTag(R.layout.item_list_order_foot);
    66                     break;
    67             }
    68         }
    69         switch(type){
    70             case NI_ORDER_ITEM_HEAD:
    71                 // ...处理逻辑
    72                 break;
    73             case NI_ORDER_ITEM_GOODS:
    74                 // ...
    75                 break;
    76             case NI_ORDER_ITEM_FOOT:
    77                 // ...
    78                 break;
    79         }
    80         return convertView;
    81     }
    82 
    83     private class ViewHolderHead {
    84         // ...
    85     }
    86     private class ViewHolderGoods {
    87        // ...
    88     }
    89     private class ViewHolderFoot {
    90         // ...
    91     }
    92 
    93     // ...
    94 }

    好,到这里就介绍完了,活用多布局,对提高Listview的执行效率是很有帮助的。

  • 相关阅读:
    myeclipse学习总结一(在MyEclipse中设置生成jsp页面时默认编码为utf-8编码)
    使用Android Studio调试UiAutomator过程中遇到的问题
    手游性能之渲染分析2
    手游性能之渲染分析1
    手脱ASProtect v1.23 RC1(有Stolen Code)之以壳解壳
    手脱ASProtect v1.23 RC1(有Stolen Code)
    Java 中extends与implements使用方法
    Java在处理大数据的时候一些小技巧
    Oracle 分页原理
    powerdesigner连接数据库 导出数据
  • 原文地址:https://www.cnblogs.com/steffen/p/6062737.html
Copyright © 2011-2022 走看看