Android ListView多布局講解
阿新 • • 發佈:2017-07-17
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多布局講解