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. Windows在结构objective C开发环境

    对于近期打算iPhone.iPod touch和iPad开发一些应用程序,所以.需要开始学习Objective C(苹果推出的类似C语言的开发语言).因为苹果的自我封闭的产业链发展模式(从芯片.机器. ...

  2. Objective-C和Swift

    在项目中同时使用Objective-C和Swift 苹果发布的Swift语言可以和之前的Objective-C语言同时存在于一个项目中. 可能有人会认为是同一个类文件中既可以有Objective-C也 ...

  3. spring bean范围

    总结: 实例代码具体解释: 文件夹结构 Car.java package com.coslay.beans.autowire; public class Car { private String br ...

  4. 【转】浏览器DNS 预取读技术的危害

    今天中午在http://news.ycombinator.com/news看到一篇文章标题: Saved 10 billion DNS queries per month by disabling D ...

  5. [转]网上看到的关于C中内存分配的描述

    1栈   -   有编译器自动分配释放     2堆   -   一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收     3全局区(静态区),全局变量和静态变量的存储是放在一块的,初始 ...

  6. C# 6.0 功能预览

    C# 6.0 功能预览 (一) 一.索引的成员和元素初始化 1.1 原始初始化集合 Dictionary 1.2 键值初始化集合 Dictionary 1.3 运算符 $ 初始化集合 Dictiona ...

  7. Effective C++(13) 用对象管理资源

    问题聚焦: 从这条准则开始,都是关于资源管理的. 资源,一旦用了它,将来必须还给系统. 本条准则,基于对象的资源管理办法,建立在C++的构造函数,析构函数和拷贝函数(拷贝构造函数和重载赋值操作符)的基 ...

  8. 【xcode插件介绍】Alcatraz ----The package manager for Xcode

    对于许多iOS开发者而言,Alcatraz并不陌生,甚至是相当的喜闻乐见.Alcatraz是一款开源的Xcode包管理器,由Marin Usalj.Delisa Mason和Jurre Stender ...

  9. try { var mergeFilePath = string.Format("{0}mergepdf.pdf", tempDownDir); PDFPrintHelper.MergePDFFile(pdfList, mergeFi

    winform 按顺序连续打印多个PDF文件   关于PDF打印的问题,前面有篇文章(点这里查看)也叙述过,今天来谈谈另外一种方法 其实方法很简单,因为需要把多个PDF文档按顺序连续打印,为此我们为什 ...

  10. dtrace sample

    #!/usr/sbin/dtrace -s #pragma D option flowindent /* monitor file open */ syscall::open:entry { prin ...