概述

目前像淘宝及展示列表等都有多个item展示的需求,可能大多数如果没做过,第一眼就是ListView去嵌套ListView,虽然这样是可以完成,但是这样做会导致手机过度绘制,为什么呢?因为当一个Item加载的时候又会去更新item里面的adapter,apapter又会去更新自己的item,这样就会导致加载一条x*n耗时.

解决思路

当我遇到这样的问题时候,其实我们可以把整个List,当做一个List处理,怎么做呢?其实就是一个复杂的ListView:

  • 头部分为一个type
  • 内容分为一个type
  • 顶部分为一个type

然后可以通过listview或者recyclerview的getItemViewTypegetViewTypeCount,特别注意一下,如果你使用了PulltoRefresh的ListView,那么就需要getViewTypeCount返回5(3+2),为什么呢,通过源码可以看到PullToRefreshListView也是add了Header.(自己可以看源码解决)

难点

难点其实在于对于服务器的数据的要求.一般服务器返回回来的数据都是一个List里面包含了多个List:

{"code": "0000","desc": null,"token": "ad762d27-ced6-4092-b415-ddad8ee0b98e__1472123395714","msg": [{"amount": 601,"consignee": "andrea","address": "天府软件园A区","orderItem": [ #列表数据{"thumbnail": null,"quantity": 1,"price": 601,"name": "熊猫座椅","id": 11}],"freight": 0,"orderStatus": "unconfirmed","productCount": 1,"shippingStatus": "unshipped","phone": "15892999216","areaName": "四川省成都市","id": 9,"sn": "20160825202","paymentStatus": "unpaid","createDate": 1472123141000},{"amount": 601,"consignee": "andrea","address": "天府软件园A区","orderItem": [ #列表数据{"thumbnail": null,"quantity": 1,"price": 601,"name": "熊猫座椅","id": 10}],"freight": 0,"orderStatus": "unconfirmed","productCount": 1,"shippingStatus": "unshipped","phone": "15892999216","areaName": "四川省成都市","id": 8,"sn": "20160825102","paymentStatus": "unpaid","createDate": 1472122855000}],"page": {"total": 8,"pageNumber": 1,"pageSize": 2}
}

遇到这样数据,我们难道要求服务器的哥们帮我改改吗?如果不给改怎么办?当然可以解决了.怎么办呢?那我们就可以去拆分数据了,怎么拆呢?:

  • 把一个item拆分成三份.
  • 第一份 : 保留item关系且和需要展示的顶部数据.
  • 第二份 : 保留item关系且和需要展示购买列表数据.
  • 第三分 : 保留item关系且和需要展示顶部购买数量,价格,支付状态等展示或者按钮和文本

通过上面描述,基本说明了遇到的难点.

代码实现

我仅仅是贴出相关的核心代码:

    /*** 拆分订单** @author Tanck* @param list* @return*/private List<ShopOrderListResponse.MsgBean> handleList(List<ShopOrderListResponse.MsgBean> list) {if (null == list || 0 == list.size())return list;List<ShopOrderListResponse.MsgBean> temp = new ArrayList<>();for (int i = 0; i < list.size(); i++) {//拆解一个订单++total;bean = list.get(i);bean.setType(1);//给bean增加了一个type字段,所以这样可以用来set,为了在adapter里面去判断是什么类型temp.add(bean);//先增加一个头for (int j = 0; j < list.get(i).getOrderItem().size(); j++) {//拆解一个订单里面的具体每个订单++total;bean = (ShopOrderListResponse.MsgBean) bean.clone();//这里用了深拷贝,是因为要对数据进行修改,后面会给出连接.bean.setType(2);bean.setOrderPosition(j);temp.add(bean);//增加一个内容}
//            ++total;bean = (ShopOrderListResponse.MsgBean) bean.clone();bean.setType(3);temp.add(bean);//尾部添加一个}return temp;}

有了拆分后,那么就需要如何展示了.看看我的adapter吧:

    @Overridepublic int getItemViewType(int position) {return list.get(position).getType();}@Overridepublic int getViewTypeCount() {return 5;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (null == convertView) {holder = new ViewHolder();switch (getItemViewType(position)) {case 1: // headconvertView = View.inflate(context, R.layout.item_shop_order_list_head, null);holder.time = (TextView) convertView.findViewById(R.id.tv_item_order_time);holder.status = (TextView) convertView.findViewById(R.id.tv_item_order_status);holder.detailHead = (RelativeLayout) convertView.findViewById(R.id.rl_item_order_detail_head);break;case 2:// contentconvertView = View.inflate(context, R.layout.item_shop_order_list_content, null);holder.icon = (ImageView) convertView.findViewById(R.id.iv_sp_my_order_item);holder.orderMoney = (TextView) convertView.findViewById(R.id.tv_sp_my_order_money);holder.number = (TextView) convertView.findViewById(R.id.tv_sp_my_order_number);holder.orderName = (TextView) convertView.findViewById(R.id.tv_sp_my_order_name);holder.content = (RelativeLayout) convertView.findViewById(R.id.rl_sp_my_order_content);break;case 3: // bottomconvertView = View.inflate(context, R.layout.item_shop_order_list_bottom, null);holder.money = (TextView) convertView.findViewById(R.id.tv_item_order_money);holder.cancel = (TextView) convertView.findViewById(R.id.tv_item_order_cancel);holder.pay = (TextView) convertView.findViewById(R.id.tv_item_order_pay);holder.detailBottom = (LinearLayout) convertView.findViewById(R.id.ll_item_order_detail_bottom);holder.opt = (RelativeLayout) convertView.findViewById(R.id.rl_item_order_opt);holder.back = (TextView) convertView.findViewById(R.id.tv_item_order_back);holder.backGoods = (TextView) convertView.findViewById(R.id.tv_item_order_back_goods);break;}convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}String tempPayStatus = list.get(position).getPaymentStatus();String tempOrderStatus = list.get(position).getOrderStatus();String tempShippingStatus = list.get(position).getShippingStatus();holder.setListener(position);switch (getItemViewType(position)) {case 1:// headholder.time.setText(context.getString(R.string.order_time) + getDate(list.get(position).getCreateDate()));/*** 订单状态未确认unconfirmed,已确认confirmed,已完成completed,已取消cancelled,已失效failure*/if ("failure".equals(tempOrderStatus)) {holder.status.setText(R.string.time_out_close);} else if ("unpaid".equals(tempPayStatus) && "cancelled".equals(tempOrderStatus)) {holder.status.setText(R.string.cancel_order);} else if ("unpaid".equals(tempPayStatus)) {holder.status.setText(R.string.unpaid);} else if ("paid".equals(tempPayStatus) && "unconfirmed".equals(tempOrderStatus)) {holder.status.setText(R.string.paid);} else if ("paid".equals(tempPayStatus) && "confirmed".equals(tempOrderStatus)) {holder.status.setText(R.string.unsend);} else if ("shipped".equals(tempShippingStatus)) {holder.status.setText(R.string.unrec);} else if ("received".equals(tempShippingStatus)) {holder.status.setText(R.string.received);} else {holder.status.setText(R.string.not_no);}holder.detailHead.setOnClickListener(holder);break;case 2:// contentint tempP = list.get(position).getOrderPosition();//获取orderItem真实位置String iconString = list.get(position).getOrderItem().get(tempP).getThumbnail();if (StringUtil.isEmpty(iconString))holder.icon.setScaleType(ImageView.ScaleType.FIT_XY);XUtilsImageLoader.getHomeAdvImg(context, R.drawable.udesk_defualt_failure, holder.icon, iconString);holder.orderName.setText(list.get(position).getOrderItem().get(tempP).getName());holder.number.setText("x" + list.get(position).getOrderItem().get(tempP).getQuantity());holder.orderMoney.setText("¥" + list.get(position).getOrderItem().get(tempP).getPrice());holder.content.setOnClickListener(holder);break;case 3://bottomholder.money.setText("共" + list.get(position).getProductCount() + "件商品 实付:¥" + list.get(position).getAmount());holder.detailBottom.setOnClickListener(holder);if ("failure".equals(tempOrderStatus)) {//交易关闭holder.opt.setVisibility(View.GONE);} else if ("unpaid".equals(tempPayStatus) && "cancelled".equals(tempOrderStatus)) {//没给钱,点击已取消holder.opt.setVisibility(View.GONE);} else if ("unpaid".equals(tempPayStatus)) {//待付款holder.opt.setVisibility(View.VISIBLE);// TODO 展示取消及付款,隐藏退货,退款holder.pay.setVisibility(View.VISIBLE);holder.cancel.setVisibility(View.VISIBLE);holder.back.setVisibility(View.GONE);holder.backGoods.setVisibility(View.GONE);holder.pay.setOnClickListener(holder);holder.cancel.setOnClickListener(holder);} else if ("paid".equals(tempPayStatus) && "unconfirmed".equals(tempOrderStatus)) {//给了钱,没确认holder.opt.setVisibility(View.VISIBLE);// TODO 展示退款,隐藏取消及付款,退货holder.cancel.setVisibility(View.GONE);holder.pay.setVisibility(View.GONE);holder.backGoods.setVisibility(View.GONE);holder.back.setVisibility(View.VISIBLE);holder.back.setOnClickListener(holder);} else if ("paid".equals(tempPayStatus) && "confirmed".equals(tempOrderStatus)) {//给了钱,且确认了holder.opt.setVisibility(View.VISIBLE);// TODO 展示退款,隐藏取消及付款,退货holder.cancel.setVisibility(View.GONE);holder.pay.setVisibility(View.GONE);holder.back.setVisibility(View.VISIBLE);holder.backGoods.setVisibility(View.GONE);holder.back.setOnClickListener(holder);} else if ("shipped".equals(tempShippingStatus)) {//待收货holder.opt.setVisibility(View.VISIBLE);// TODO 展示退款,隐藏取消及付款,退货(后期可能会增加查看物流)holder.cancel.setVisibility(View.GONE);holder.pay.setVisibility(View.GONE);holder.backGoods.setVisibility(View.GONE);holder.back.setVisibility(View.VISIBLE);holder.back.setOnClickListener(holder);} else if ("received".equals(tempShippingStatus)) {//收货了,待评价holder.opt.setVisibility(View.VISIBLE);// TODO 展示退货,隐藏取消及付款,退款holder.back.setVisibility(View.GONE);holder.cancel.setVisibility(View.GONE);holder.pay.setVisibility(View.GONE);holder.backGoods.setVisibility(View.VISIBLE);holder.backGoods.setOnClickListener(holder);} else { // 等待确认holder.opt.setVisibility(View.GONE);}break;}return convertView;}

原型模式学习(参考这儿)

总结

我们可以用一个ListView或者RecyclerView去做很多复杂类型的,为什么这样做不卡?因为自带了复用机制,复用机制的话这里就不用多说了.所以经过这样我们就可以随意做复杂的列表而且不卡顿.

Demo地址:Demo地址

Android 仿淘宝京东等我的订单界面及任意列表拓展相关推荐

  1. Android仿淘宝京东商品规格参数颜色筛选

    Android 选择商品属性sku 最近项目中使用SKU属性查询,类似淘宝京东商品的选择,在网上查询了弄了几个源码看看,发现还是实现不了多属性选择问题,再原基础上改动相当费事,所以想干脆自己处理这个问 ...

  2. Android 仿淘宝京东商品详情页阻力翻页效果

    原文链接:http://code.taobao.org/p/android-example/diff/46/trunk/%E5%95%86%E5%9F%8E%E8%AF%A6%E6%83%85/src ...

  3. Android 仿淘宝京东商品详情视频+图片与图片第一帧获取

    近日项目有个新需求就是把原本的商品详情只有图片展示,改为视频+图片方式展示. 此博客只提供记录,与思路具体根据自己需求实现.首先想到的是Google搜索下别人的实现方式来参考实现发现不怎么适合项目需求 ...

  4. Android仿淘宝、京东Banner滑动查看图文详情

    文章目录 写在前面 效果图 原理分析 核心代码 源码地址 写在前面 本文基于 ViewPager2 实现的 Banner 效果,进而实现了仿淘宝.京东Banner滑动至最后一页时继续滑动来查看图文详情 ...

  5. 仿淘宝京东商品规格属性选择的最简单实现

    仿淘宝京东商品规格属性选择的最简单实现 商城里面的规格选择,网上大部分是自定义控件实现的,显得很是麻烦,而我的实现方式是大家最常用的控件RecyclerView,特点是性能好,简单.废话不多说,先看实 ...

  6. Android仿淘宝详情页面viewPager滑动到最后一张图片跳转的功能

    需要做一个仿淘宝客户端ViewPager滑动到最后一页,再拖动的时候跳到详情的功能,刚开始我也迷糊了,通过查阅相关资料发现有好多种实现方法,下面小编给大家分享实例代码,感兴趣的朋友一起看看吧 需要做一 ...

  7. 纯css仿淘宝京东导航菜单栏

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  8. JavaScript仿淘宝京东放大镜效果(鼠标事件)------JavaScript学习之路10

    JavaScript仿淘宝京东放大镜效果 注意 一定计算好放大比例,本程序放大5倍,具体放大倍数,自定 效果 完整源码 <!DOCTYPE html> <html lang=&quo ...

  9. Android仿淘宝首页UI(附代源代码及示例图片)

    Android仿淘宝首页UI(附代源代码及示例图片) 可以收获 运行出来的效果 部分代码 源代码 可以收获 更改Layout中的文字和drawble中的图片即可生成适应于不同情景的APP,帮助开发者完 ...

最新文章

  1. linux入门教程命令,Linux入门命令掌握
  2. 上云、微服务化和DevOps,少走弯路的办法
  3. 数据查找matlab,MATLAB:使用矢量化查找已排序数据的统计信息
  4. 6421B Lab5 路由和远程访问的配置与故障排除
  5. 浅谈SCOM Agent的心跳响应机制
  6. 《例说51单片机(C语言版)(第3版)》一1.7 实时练习
  7. 搭建Zabbix Proxy HA
  8. python爬虫案例——糗事百科数据采集
  9. C#学习笔记(十):反射
  10. shiro框架的使用
  11. VSTO 3.0 for Office 2007 Programming
  12. java 调用net remoting_获取 org.springframework.remoting.RemoteAccessException: 在进行调用时无法访问远程服务?...
  13. 基础篇——树莓派远程连接工具VNC不显示视频或摄像头画面解决方式
  14. Centos7.5系统部署禅道协调管理系统以及配置优化
  15. iOS 本地通知基本使用
  16. 国内外可信计算技术发展概况(转载1)
  17. C# 调用NationalInstruments的dll报错问题 未能加载文件或程序集
  18. 小说里的编程 【连载之二十二】元宇宙里月亮弯弯
  19. 软件测试工程师必备技能——Linux基础知识
  20. python断网还能用吗_python 断网

热门文章

  1. 【数据结构】最大曼哈顿距离
  2. page_to_pfn 、virt_to_page、 virt_to_phys、page、页帧pfn、内核虚拟地址、物理内存地址linux内核源码详解
  3. 一个大学生的心灵告白:世界上最后一封情书
  4. 1995-2020年国泰安并购重组数据库
  5. linux的一页是多大
  6. 炫龙T3-pro 9代cpu无csm兼容选项笔记本GPT硬盘纯uefi安装windows7系统方法
  7. 服务器固态盘和机械盘哪个好
  8. 点滴生活感悟(更新至29)
  9. 自动化的8种定位方式
  10. cad图转成shp文件并把其平面坐标投影配准成大地坐标(配准针对没有底图的情况)