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的视图缓存机制,避免了每 ...
随机推荐
- centos6的安装,一步一图,有图有真相
打开虚拟机VMware,点击文件,选择[新建虚拟机],如图所示
- 输入 URL 到页面完成加载过程中的所有发生的事情?
转到浏览器中输入URL给你一个页面后,.有些事情,你每天都在使用,学的是计算机网络知道是怎么回事.DNS解析然后页面的回馈,只是要讲好还是有难度. 之前fex团队的nwind专门写过这个问题的博客: ...
- 折腾源WRT的AC路无线路由-2
在创纪录的开箱图,开箱后,我觉得大尺寸,因此,获得一些各种尺寸,喜欢网上购物的参考.也许这,安装后,它占用的大小:基本长度=28.5cm.深度=19.5cm,高=19.5,因为制造商推荐的约两个天线是 ...
- 通过SqlClr制作Sql自动化批量执行脚本
原文:通过SqlClr制作Sql自动化批量执行脚本 通过SqlClr制作Sql自动化批量执行脚本 在与同事一起做项目时,看到同事用sqlclr做批量执行脚本,感觉挺新奇的就上网搜集资料自己模仿跟做了个 ...
- Smarty属性
Attributes [属性] 大多数函数都带有自己的属性以便于明确说明或者修改他们的行为. smarty函数的属性很像HTML中的属性. 静态数值不需要加引号,但是字符串建议使用引号. 如果用 ...
- MVC框架的插件与拦截器基础
自制MVC框架的插件与拦截器基础 上篇谈到我自己写的MVC框架,接下来讲讲插件及拦截器! 在处理一些通用的逻辑最好把它封装一个插件或者拦截器,以便日后可以直接拿过来直接使用.在我的框架中可以通过继承以 ...
- Android Wear和二维码
这是一篇发布在Android官方开发者社区博客,15年年初的时候就看到了这篇文章,直到现在才有时间把它翻译下来. 这是一篇如何在Android Wear上面如何正确地展示二维码的文章,里面有许多的经验 ...
- 关于Dictionary字典和List列表
命名空间System.Collections.Generic中有两个非常重要,而且常用的泛型集合类,它们分别是Dictionary<TKey,TValue>字典和List<T> ...
- 从Java到C (大纲)
Binder机制,从Java到C (大纲) 转载请标注:张小燕:http://www.cnblogs.com/zhangxinyan/p/3487381.html 前段时间一直在看有关Binder ...
- ASP.NET MVC中使用Unity进行依赖注入的三种方式
在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...