1. 程式人生 > >Android ListView多布局講解

Android ListView多布局講解

android

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     @Override10     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     @Override25     public int getViewTypeCount() {26         return 3;27     }28 29     @Override30     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 }


Android ListView多布局講解