Android ListView多布局讲解
Listview优化是一个老生常谈的事情了,其优化的方面也有很多种,例如,布局重用、在getView()中减少逻辑计算、减少在页面滑动的时候加在图片,而是在页面停止滚动的时候再加在图片。而今天要介绍的是另一种方式,那就是多布局。
一般使用的场景有一下两种情况:
① 当一个item有多重布局的情况下,使用部分隐藏来实现既笨拙又效率低下,这时多布局会是个不错的选择;
② 当一个item很复杂,页面内容多,item高度很高,甚至超过手机屏幕,这个时候就需要使用多布局将页面拆分成多个小item来提高执行效率。
举个栗子:如下销售订单列表,我们发现一个单个item的页面高度很高,内容也很多,中部的商品个数还具有不确定性,这时的实现的方式我们可以看下:

代码如下:
@Override
public View getView(final int position, View convertView, ViewGroup rootview) {
ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.item_list_order, rootview, false);
// ...
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
} for (int i = 0; i < arrListOrder.get(position).size(); i++) {
View v = inflater.inflate(R.layout.item_order_goods, null);
// ...
viewHolder.llayoutGoodsList.addView(v);
} // ...
return convertView;
}
这种写法诟病很大,严重影响性能,此外如果商品数量有个10个8个的会导致item过高,此外在getView()中for循环new布局对象是是否消耗内存的和执行时间的。
那么,我们用多布局拆分下:

这种布局方式就叫ListView的多布局。采用将一个大的 item 切割成多个小item以降低布局的复杂度,提高重用率。那么直接看这种方式的实现方式:
public class OrderListActivity extends Activity {
// ...
/** 解析请求数据 */
private ArrayList<HashMap<String, Object>> analyticalData(String json) {
ArrayList<HashMap<String, Object>> arrListGoods = new ArrayList<>();
try {
JSONArray jsArr = new JSONArray(json);
for (int i = 0; i < jsArr.length(); i++) {
JSONObject jsObj = jsArr.optJSONObject(i);
// 头部
hashMapHead.put("order_sn", jsObj.optString("order_sn")); // 销售订单号
// ...
hashMapHead.put("item_type", OrderListAdapter.NI_ORDER_ITEM_HEAD); // 设置布局类型
arrListGoods.add(hashMapHead);
// 商品
JSONArray arrJsonGoods = jsObj.getJSONArray("order_goods");
JSONObject jsobjPay = new JSONObject();
for (int j = 0; j < arrJsonGoods.length(); i++) {
HashMap<String, Object> hashMapGoods = new HashMap<>();
hashMapHead.put("goods_name", jsObj.optString("goods_name")); //商品名
// ...
hashMapHead.put("item_type", OrderListAdapter.NI_ORDER_ITEM_GOODS);
arrListGoods.add(hashMapGoods);
}
// 底部
HashMap<String, Object> hashMapFoot = new HashMap<>();
hashMapFoot.put("address", jsObj.optString("address")); // 地址
// ...
hashMapHead.put("item_type", OrderListAdapter.NI_ORDER_ITEM_FOOT);
arrListGoods.add(hashMapFoot);
}
} catch (JSONException e) {
return null;
}
return arrListGoods;
}
}
public class OrderListAdapter extends BaseAdapter {
public static final int NI_ORDER_ITEM_HEAD = 0; // 这要从0按顺序往下变化,否则报错“数组下标溢出”,原因还不清楚
public static final int NI_ORDER_ITEM_GOODS = 1;
public static final int NI_ORDER_ITEM_FOOT = 2;
// ...
/** 获取布局的类型 */
@Override
public int getItemViewType(int position) {
try {
int i = Integer.parseInt(mAppList.get(position).get("item_type").toString());
switch (i){
case NI_ORDER_ITEM_HEAD:
case NI_ORDER_ITEM_GOODS:
case NI_ORDER_ITEM_FOOT:
return i;
}
} catch (Exception e) {
}
return super.getItemViewType(position);
}
/** 获取布局类型的总数 */
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public View getView(int position, View convertView, ViewGroup rootview) {
ViewHolder viewHolderHead = null;
ViewHolder viewHolderGoods = null;
ViewHolder viewHolderFoot = null;
int type = getItemViewType(position);
if (convertView == null) {
switch(type){
case NI_ORDER_ITEM_HEAD:
viewHolderHead = new viewHolderHead();
convertView = mInflater.inflate(R.layout.item_list_order_head, rootview, false);
// ...初始化布局
convertView.setTag(R.layout.item_list_order_head, viewHolderHead); // 这里要用setTag(int, Object);
break;
case NI_ORDER_ITEM_GOODS:
viewHolderGoods = new viewHolderGoods();
convertView = mInflater.inflate(R.layout.item_list_order_goods, rootview, false);
// ...初始化布局
convertView.setTag(R.layout.item_list_order_goods, viewHolderGoods);
break;
case NI_ORDER_ITEM_FOOT:
viewHolderFoot = new viewHolderFoot();
convertView = mInflater.inflate(R.layout.item_list_order_foot, rootview, false);
// ...初始化布局
convertView.setTag(R.layout.item_list_order_foot, viewHolderFoot);
break;
}
} else {
switch(type){
case NI_ORDER_ITEM_HEAD:
viewHolderHead = getTag(R.layout.item_list_order_head);
break;
case NI_ORDER_ITEM_GOODS:
viewHolderGoods = getTag(R.layout.item_list_order_goods);
break;
case NI_ORDER_ITEM_FOOT:
viewHolderFoot = getTag(R.layout.item_list_order_foot);
break;
}
}
switch(type){
case NI_ORDER_ITEM_HEAD:
// ...处理逻辑
break;
case NI_ORDER_ITEM_GOODS:
// ...
break;
case NI_ORDER_ITEM_FOOT:
// ...
break;
}
return convertView;
}
private class ViewHolderHead {
// ...
}
private class ViewHolderGoods {
// ...
}
private class ViewHolderFoot {
// ...
}
// ...
}
好,到这里就介绍完了,活用多布局,对提高Listview的执行效率是很有帮助的。
Android ListView多布局讲解的更多相关文章
- Android ListView多布局
使用listview多布局会出现一点问题: 由于多个item布局给单一的item布局是不一样的,使用起来,contentview的复用会出现问题. 避免出现问题的有这几个方法: 1.重写 getVie ...
- android listview需要呈现多个布局
android listview需要呈现多个布局 之前的做法很笨 在getView()方法里面,不仅将viewHolder作为tag属性设置给convertView 还将当前的position作为ta ...
- Android ListView Adapter的getItemViewType和getViewTypeCount多种布局
<Android ListView Adapter的getItemViewType和getViewTypeCount多种布局> 在Android的ListView中.假设在一个Lis ...
- android listView布局等分列
android listView布局4等分列. 必须要加上<RelativeLayout 在外层,不然等分不起作用 <RelativeLayout xmlns:android=" ...
- Android ListView的item背景色设置以及item点击无响应等相关问题
Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的ite ...
- Android ListView工作原理完全解析,带你从源码的角度彻底理解
版权声明:本文出自郭霖的博客,转载必须注明出处. 目录(?)[+] Adapter的作用 RecycleBin机制 第一次Layout 第二次Layout 滑动加载更多数据 转载请注明出处:h ...
- android ListView 九大重要属性详细分析、
android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...
- 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...
- Android ListView 常用技巧
Android ListView 常用技巧 Android TextView 常用技巧 1.使用ViewHolder提高效率 ViewHolder模式充分利用了ListView的视图缓存机制,避免了每 ...
随机推荐
- How to:如何在调用外部文件时调试文件路径(常见于使用LaunchAppAndWait和LaunchApp函数)
原文:How to:如何在调用外部文件时调试文件路径(常见于使用LaunchAppAndWait和LaunchApp函数) IS里调用外部文件的时候,一般都是用LaunchAppAndWait函数,比 ...
- 学习的例子gcc+gdb+make
1 小侃GCC 在正式使用gcc之前,我们先来侃侃gcc是啥玩意儿? 历史 如今的GCC是GNU Compiler Collection的简称.既然是Collection,就是指一些工具链的集合. 最 ...
- 分区表在安装系统(MBR)丢失或损坏
操作系统能识别出硬盘中的各个不同的分区,是靠硬盘分区表(MBR)来识别的. 硬盘分区表中记录了各个分区的位置和大小以及类型等信息,假设这个分区表破坏了,那么这块硬盘里面的分区就会丢失.系统是无法在浏览 ...
- WebApp 框架
Razor 在WebApp 框架的运用 前面有两章介绍了WebApp框架<WebApp MVC,“不一样”的轻量级互联网应用程序开发框架>和<WebApp MVC 框架的开发细节 ...
- WCF中队列服务详解
WCF中队列服务详解 一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务 ...
- JQUERY 插件开发——MENU(导航菜单)
JQUERY 插件开发——MENU(导航菜单) 故事背景:由于最近太忙了,已经很久没有写jquery插件开发系列了.但是凭着自己对这方面的爱好,我还是抽了一些时间来过一下插件瘾的.今天的主题是导航菜单 ...
- 【SSRS】入门篇(七) -- 报表发布
原文:[SSRS]入门篇(七) -- 报表发布 完成[SSRS]入门篇(六) -- 分组和总计后,第一份简单的报表就已完成了,下面把报表发布到报表服务器上. (实际情况下,报表展示给用户未必是用报表服 ...
- sqlserver查询所有表的行数的sql语句
原文:sqlserver查询所有表的行数的sql语句 select object_name(id),rowcnt from sysindexes where indid<2 and object ...
- 同TTX更可爱的层次分析法游戏破解
最近的工作太忙,没啥时间写文章,今天遇到一点点的游戏,浅析.以中午的优势写这篇文章. 移动MM的游戏.前面我们已经写过非常多文章,没有看过的朋友,自行查找就可以,今天我们继续分析一个类似的游戏,只是使 ...
- MVC5搜索/查询 流程功能的实现
接着上次的篇幅,我们这篇手动来写一个查询的流程代码! 搜索/查询 流程功能的实现 那现在要做搜索(查询)功能我们第一步应该做什么呢!第一次是不是我们应该去Controller(控制器)里去搞一个搜索 ...