Android ListView多布局讲解
Posted tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的执行效率是很有帮助的。
以上是关于Android ListView多布局讲解的主要内容,如果未能解决你的问题,请参考以下文章
片段中 ListView 的 setOnItemClickListener
android样式布局--->ListView(附上源代码)