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多布局讲解的更多相关文章

  1. Android ListView多布局

    使用listview多布局会出现一点问题: 由于多个item布局给单一的item布局是不一样的,使用起来,contentview的复用会出现问题. 避免出现问题的有这几个方法: 1.重写 getVie ...

  2. android listview需要呈现多个布局

    android listview需要呈现多个布局 之前的做法很笨 在getView()方法里面,不仅将viewHolder作为tag属性设置给convertView 还将当前的position作为ta ...

  3. Android ListView Adapter的getItemViewType和getViewTypeCount多种布局

     <Android ListView Adapter的getItemViewType和getViewTypeCount多种布局> 在Android的ListView中.假设在一个Lis ...

  4. android listView布局等分列

    android listView布局4等分列. 必须要加上<RelativeLayout 在外层,不然等分不起作用 <RelativeLayout xmlns:android=" ...

  5. Android ListView的item背景色设置以及item点击无响应等相关问题

    Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的ite ...

  6. Android ListView工作原理完全解析,带你从源码的角度彻底理解

    版权声明:本文出自郭霖的博客,转载必须注明出处.   目录(?)[+] Adapter的作用 RecycleBin机制 第一次Layout 第二次Layout 滑动加载更多数据   转载请注明出处:h ...

  7. android ListView 九大重要属性详细分析、

    android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...

  8. 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...

  9. Android ListView 常用技巧

    Android ListView 常用技巧 Android TextView 常用技巧 1.使用ViewHolder提高效率 ViewHolder模式充分利用了ListView的视图缓存机制,避免了每 ...

随机推荐

  1. mongodb操作:利用javaScript封装db.collection.find()后可调用函数源码解读

    { "_mongo" : connection to YOURIP:27017{ SSL: { sslSupport: false, sslPEMKeyFile: "&q ...

  2. 关于PHP的工作流引擎

    关于PHP的工作流引擎,除了三大主流开源:PorcessMaker(排名第一,因其有拖放式图形定义界面),RadiCore(基于PETRI NET)和CuteFlow以外,另外还有一个不为人知的,但却 ...

  3. jquery.validate 以alert方式显示错误方法

    $.validator.setDefaults({ submitHandler: function() { alert("submitted!");return false; } ...

  4. sql点滴40—mysql乱码问题总结

    原文:sql点滴40-mysql乱码问题总结 本文将为大家讲解如何处理Java连接过程中的MySQL中文乱码问题.一般MySQL中文乱码问题都是与字符集有关,这里作者的经历也大致差不多. MySQL默 ...

  5. DirectX:函数连接两个随机filter

    函数连接两个随机filter HRESULT ConnectFilters( IBaseFilter *pSrc, IBaseFilter *pDest ) { IPin *pIn = 0; IPin ...

  6. 全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org

    先给出官网地址:deflang.org 一句话简介:可扩展编程语言 Def 的目标是将 C++ 的高效抽象和 Lisp 的强大表现力融为一体. 你可以通过阅读 入门教程 .源码 或 测试用例 来简要或 ...

  7. leetcode第33题--Search for a Range

    Given a sorted array of integers, find the starting and ending position of a given target value. You ...

  8. Object.prototype.toString &amp; typeof

    Object.prototype.toString & typeof Object.prototype.toString 获取某个对象属于哪种内置类型 typeof  得到某个对象的类型 差别 ...

  9. orcale复制表结构及其数据

    http://hi.baidu.com/tag/Oracle/feeds http://hi.baidu.com/gqftuisidibabiq/item/14d306cc87cbdf45bcef69 ...

  10. JSFIDDLE 动力 Threejs 功能探秘

    JSFIDDLE 助力 WebGL 功能探秘 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协 ...