Android ListView多布局讲解

时间:2023-02-22 17:36:50

Listview优化是一个老生常谈的事情了,其优化的方面也有很多种,例如,布局重用、在getView()中减少逻辑计算、减少在页面滑动的时候加在图片,而是在页面停止滚动的时候再加在图片。而今天要介绍的是另一种方式,那就是多布局。

一般使用的场景有一下两种情况:

① 当一个item有多重布局的情况下,使用部分隐藏来实现既笨拙又效率低下,这时多布局会是个不错的选择;

② 当一个item很复杂,页面内容多,item高度很高,甚至超过手机屏幕,这个时候就需要使用多布局将页面拆分成多个小item来提高执行效率。

举个栗子:如下销售订单列表,我们发现一个单个item的页面高度很高,内容也很多,中部的商品个数还具有不确定性,这时的实现的方式我们可以看下:

Android ListView多布局讲解

代码如下:

 @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布局对象是是否消耗内存的和执行时间的。

那么,我们用多布局拆分下:

Android ListView多布局讲解

这种布局方式就叫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. cat -n与nl的区别

    cat -n filename:空行也算一行 nl filename:空行不算一行

  2. Java笔记1-Java相关概念和如何实现跨平台

    一.Java相关概念 1.Java语言的核心特点跨平台面向对象 2.Java的历史版本JDK1.0,JDK1.1,JDK1.2....JDK5.0,JDK6.0,JDK7.0,JDK8.0 注意:JD ...

  3. python学习第六天

    一. 模块介绍1. 模块的定义:用一堆代码实现了某个功能的代码集合     包的定义:本质就是一个目录(必须导游一个_init_.py文件),是用来从逻辑上组织模块的.2. 需要多个函数才能完成(函数 ...

  4. css如何实现背景透明,文字不透明?

    之前做了个半透明弹层,但设置背景半透明时,子元素包含的字体及其它元素也都变成了半透明.对opacity这个属性认识的不透彻,在这里做一些总结,方便以后使用.   背景透明,文字不透明的解决方法:   ...

  5. 设置高级的Logstash 管道

    设置高级的Logstash 管道: 一个Logstash 管道在很多实用例子有一个或者多个输入,filter,和output 插件. 本节中 创建Logstash 配置文件来指定那些插件和讨论每个插件 ...

  6. 类中成员函数与数据成员private&sol;pubic&sol;protected

    类中成员函数与数据成员private/pubic/protected

  7. VS Code开发调试&period;NET Core

    使用VS Code开发 调试.NET Core 应用程序   使用VS Code开发 调试.NET Core RC2应用程序,由于.NET Core 目前还处于预览版. 本文使用微软提供的示例进行开发 ...

  8. 实现BUG自动检测 - ASP&period;NET Core依赖注入

    我个人比较懒,能自动做的事绝不手动做,最近在用ASP.NET Core写一个项目,过程中会积累一些方便的工具类或框架,分享出来欢迎大家点评. 如果以后有时间的话,我打算写一个系列的[实现BUG自动检测 ...

  9. Groovy读取文件信息

    1. eachLine -- 打开和读取文件的每一行 new File("foo.txt").eachLine { println it.toUpperCase(); } 2. r ...

  10. IE9以及以下不支持jquery ajax跨域问题

    1.代码中加 jQuery.support.cors = true; 2. 设置ie浏览器 工具->Internet 选项->安全->自定义级别” 将“其他”选项中的“通过域访问数据 ...