Android Tab吸顶 嵌套滚动通用实现方案✅

很多应用的首页都会有一些嵌套滚动、Tab吸顶的布局,尤其是一些生鲜类应用,例如 朴朴超市、大润发优鲜、盒马等等。

 

在 Android 里面,滚动吸顶方式通常可以通过 CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout + NestedScrollView 来实现,但是 AppBarLayoutBehavior fling
无法传递到
NestedScrollView,快速来回滑动偶尔也会有些抖动,导致滚动不流畅。

另外对于头部是一些动态列表的,还是更希望通过 RecyclerView 来实现,那么嵌套的方式变为:RecyclerView + ViewPager + RecyclerView,那么就需要处理好 RecyclerView 的滑动冲突问题。

多个大文件数据排序去重的解题思路

问题

假设有四个文件,每个文件 1GB,文件里的每一行存储一个随机的 int正整数 (0 <= v < 2^32),单文件最多 1亿行。要求对这四个文件进行排序去重,输出一个有序的文件。

假设服务器规格 8核16GB内存,希望执行时间尽可能短。

在上述的前提条件下,如果排序完之后,还希望输出每个数字出现的次数呢?

文件读写效率

在 Java 下,文件的 io 方式分为 字节流 和 字符流,字符流又分为 字符输入流 和 字符输出流。
字节流和字符流的区别在于,字节流是以字节为单位读写文件,字符流是以字符为单位读写文件。

字符流的好处是可以指定编码,比如 UTF-8,GBK 等,而字节流只能使用默认的编码。

对于该题目,相比之下,字符流更适合,因为我们只需要读取每一行,然后转换成 int,不需要考虑编码的问题。所以后文会有很多
BufferReader 和 BufferWriter 相关的代码,这里就不再赘述。

常规思路

假设要对所有的数字读取出来进行排序,全部读取出来其实内存里也能放得下。4个文件400000000行,int值占4个字节,理论上只需要 1.6G 的空间,但是做快排时,递归深度太深容易栈溢出。如果数据量更大,或者内存更小,比较理想的方案是外部排序法。

那么我们可以考虑分治的思想,将一个大文件分成多个小文件,每个小文件放到内存里排序,然后再将这些小文件合并成一个大文件。这样就可以解决内存放不下的问题。

终端 Terminal 的一些实现细节分享

在日常开发中,相信很多小伙伴好奇过以下一些问题,尤其是经常使用命令行工具的…

  • 为什么 AndroidStudio/IDEA 能打印各种颜色的日志
  • 各种 CLI 在执行时,底下的进度条是怎么实现的
  • Vim 在 Terminal 中是如何做到清屏和恢复屏幕的
  • StartAgent 运维平台的 Web Terminal 是怎么做到跟 Terminal 类似的
  • SpringBoot 启动 Logo 是怎么打印出来的

最近在建设云真机平台时,为了便于对 宿主机服务器 & Android设备 的控制,增加了Web Terminal 的功能,通过终端指令控制设备,包含 Web SSH、Android 远程 Shell等,实现过程还蛮有趣的,所以也重新整理了一下 Terminal 的一些细节原理。

深入理解 Android Transition 场景动画

Transition 概念

Transition 是指不同 UI 状态转换时的动画。其中有两个关键概念:场景(Scene)和转换(Transition)。场景定义了一个确定的 UI 布局状态,而转换定义了两个场景切换时过渡的动画。

当两个场景进行切换时,Transition 主要有下面两个行为:

1、 确定开始场景和结束场景中每个 view 的状态。
2、 根据状态差异创建 Animator,用于场景切换时每个 view 的动画。

例如最简单的对View的隐藏增加渐变动画:

Android 页面秒开优化总结

性能优化是一个长期的过程,并非一劳永逸,需要我们去抠细节,找到可以提升的地方。

针对Android平台自身特性的一些优化(例如xml布局优化、方法耗时之类)在这里就不展开了,主要还是从逻辑和业务出发~

数据加载优化

网络请求前置

也许是因为时序的问题,通常情况下 Activity 启动之后有三个步骤:

  1. 加载布局及初始化View
  2. 再进行网络请求等待
  3. 请求结果json解析
  4. 最后再渲染到界面上。

而实际上 步骤1、2、3 这三步是可以并行去做的,假设说 加载布局及初始化View 需要 150ms,整个网络请求耗时 200ms,那么并行之后理想情况就可以节省 150ms 的启动时间。

这时候可能就有疑问了,假设网络请求时间比View初始化来得快,网络请求结束后要去更新UI,就很有可能引起空指针问题。所以针对这种情况,我们需要做一个等待View初始化完的操作。

其实因为 Android 基于消息机制,并且通常情况下View的更新都在主线程,实际上网络请求结束后,post到主线程后更新UI,onCreate 已经执行完了,所以不需要等待也可以。但如果是在子线程去调用非更新View的方法,比如获取一些状态之类的,那就需要做等待操作。

RecyclerView 悬浮吸顶效果实现,支持数据绑定及Touch事件

诸如联系人列表、分类页商品类表等分组场景,都可能需要悬浮吸顶的效果。Android 官方并未提供原生的组件来实现这个功能,因此需要我们自定义实现。

网上看到的基本实现思路都是通过 ItemDecoration ,在滑动过程中去根据当前滑动位置,绘制吸顶的视图。

如果只是需要简单的绘制,确实通过这个方式要简单的多。但是通过这种方式无法支持 Touch 事件。感兴趣的可以参考一下这个:https://gist.github.com/saber-solooki/edeb57be63d2a60ef551676067c66c71 (可能需要梯子才能访问)

RecyclerView Adapter 实现自动多 ViewType

前言

多Type的列表在App中很常见,例如各种电商类App的首页,甚至是购物车、订单详情页面等。我们暂且将页面上每个ViewType对应的模块称之为楼层。那么,以电商订单详情举例,可能有以下楼层:

  • 订单状态(交易成功、交易关闭等)
  • 物流信息
  • 收货地址
  • 订单商品信息列表
  • 价格相关信息
  • 订单信息(订单号、交易流水号等)
  • 其他一些展示信息

那么,我们可以通过不同的 ViewType 来区分这些模块,通常的做法是: