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>> appList = 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                 appList.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                     appList.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                 appList.add(hashMapFoot);
34             }
35         } catch (JSONException e) {
36             return null;
37         }
38         return appList;
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 = inflater.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 = inflater.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 = inflater.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的执行效率是很有帮助的。

时间: 2024-05-07 00:10:27

Android ListView多布局讲解的相关文章

Android——ListView多布局+适配器(二)

Android--ListView多布局+适配器(二) <span style="font-size:18px;">package com.example.administrator.newstop.entity; /** * Created by Administrator on 2016/8/4. */ public class News { private String title; private String pubDate; private int img; p

Android ListView 多种布局--进阶二

Android ListView 多种布局–进阶一 中提及了这么一个需求,本博文就这个需求的实现做进一步探讨. 前面是单列,后面是双列的情况,使用ListView实现,一般的解决思路是处理getView和getCount方法,如下实现: 首先实现Adapter,处理getView和getCount方法 public class DoubleAdapter extends BaseAdapter implements OnClickListener{ private List<String> m

Android ListView Animation 布局动画

AnimationSet set = new AnimationSet(false); Animation animation = new AlphaAnimation(0,1); //AlphaAnimation 控制渐变透明的动画效果 animation.setDuration(500); //动画时间毫秒数 set.addAnimation(animation); //加入动画集合 animation = new TranslateAnimation(1, 13, 10, 50); //S

Android——ListView布局+适配器(三)

Android--ListView布局+适配器(三) package com.example.administrator.newstop; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import andro

android ListView item有多重布局

android的listview的一个关键技术就是重绘利用. public View getView(int position, View convertView, ViewGroup parent) { return null; } 从Adatper的getview函数我们可以知道,函数提供了一个convertView的对象,这个对象是我们可以在一个列表中重复利用避免每次getview都进行重绘的关键.我们平常使用的都是大多是单个布局的item,所以我们可以通过建立一个holder就可以重复利

Android学习笔记二十五之ListView多布局实现

Android学习笔记二十五之ListView多布局实现 这一节是介绍ListView这个控件的最后一节,实现一个Item的多布局.像我们经常在用的各种即时通讯工具,QQ.微信等,假设他们的会话界面是ListView实现的,那么ListView就有多种Item布局,这一节,我们就来实现一个ListView的多种Item. 要实现ListView里面有多种Item,就要重写适配器的两个方法getViewTypeCount()和getItemViewType(int position),第一个方法是

android listview的item布局中含有button,不会响应listview的onitemclick监听 以及 onitemlongclick监听问题解决

效果图: activity的布局xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent&qu

Android ListView Adapter的getItemViewType和getViewTypeCount多种布局

 <Android ListView Adapter的getItemViewType和getViewTypeCount多种布局> 在Android的ListView中,如果在一个ListView中要实现多种样式的ListView布局样式,则需要在ListView的适配器Adapter中用到:getItemViewType()和getViewTypeCount().getViewTypeCount()告诉ListView需要加载多少种类型的Item View,getItemViewType(

Android ListView使用BaseAdapter与ListView的优化 (转至 http://www.open-open.com/lib/view/open1339485728006.html)

在ListView的使用中,有时候还需要在里面加入按钮等控件,实现单独的操作.也就是说,这个ListView不再只是展示数据,也不仅仅是这一行要来处理用户的操作,而是里面的控件要获得用户的焦点.读者可以试试用SimpleAdapter添加一个按钮到ListView的条目中,会发现可以添加,但是却无法获得焦点,点击操作被ListView的Item所覆盖.这时候最方便的方法就是使用灵活的适配器BaseAdapter了. ▲图4-35 BaseAdapter中的方法 使用BaseAdapter必须写一