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的執行效率是很有幫助的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM