标签归档:GitHub

Android 复杂的列表视图新写法: MultiType 详解篇

前言

在开发我的 TimeMachine 时,我有一个复杂的聊天页面,于是我设计了我的类型池系统,它是完全解耦的,因此我能够轻松将它抽离出来分享,并给它取名为 MultiType.

从前,比如我们写一个类似微博列表页面,这样的列表是十分复杂的:有纯文本的、带转发原文的、带图片的、带视频的、带文章的等等,甚至穿插一条可以横向滑动的好友推荐条目。不同的 item 类型众多,而且随着业务发展,还会更多。如果我们使用传统的开发方式,经常要做一些繁琐的工作,代码可能都堆积在一个 Adapter 中:我们需要覆写 RecyclerView.AdaptergetItemViewType 方法,罗列一些 type 整型常量,并且 ViewHolder 转型、绑定数据也比较麻烦。一旦产品需求有变,或者产品设计说需要增加一种新的 item 类型,我们需要去代码堆里找到我们原来的逻辑去修改,或者找到正确的位置去增加代码。这些过程都比较繁琐,侵入较强,需要小心翼翼,以免改错影响到其他地方。

现在好了,我们有了 MultiType,简单来说,MultiType 就是一个多类型列表视图的中间分发框架,它能帮助你快速并且清晰地开发一些复杂的列表页面。它本是为聊天页面开发的,聊天页面的消息类型也是有大量不同种类,并且新增频繁,而 MultiType 能够轻松胜任,代码模块化,随时可拓展新的类型进入列表当中。它内建了 类型View 的复用池系统,支持 RecyclerView,使用简单灵活,令代码清晰、拥抱变化。

因此,我写了这篇文章,目的有几个:一是以作者的角度对 MultiType 进行入门和进阶详解。二是传递我开发过程中的思想、设计理念,这些偏细腻的内容,即使不使用 MultiType,想必也能带来很多启发。最后就是把我自觉得不错的东西分享给大家,试想如果你制造的东西很多人在用,即使没有带来任何收益,也是一件很自豪的事情。

目录

MultiType 的特性

  • 轻盈,整个类库只有 10 个类文件,aarjar 包大小只有 10KB
  • 周到,支持 局部类型池 和 全局类型池,并支持二者共用,当出现冲突时,以局部的为准
  • 灵活,几乎所有的部件(类)都可被替换、可继承定制,面向接口/抽象编程
  • 纯粹,只负责本分工作,专注多类型的列表视图 类型分发
  • 高效,没有性能损失,内存友好,最大限度发挥 RecyclerView 的复用性
  • 可读,代码清晰干净、设计精巧,极力避免复杂化,可读性很好,为拓展和自行解决问题提供了基础

总览

MultiType 能轻松实现如下页面,它们将在示例篇章具体提供:


继续阅读

使用 MailOtto 做预加载

最近我开源了一个专注懒事件的事件总线 MailOtto: https://github.com/drakeet/MailOtto 并写了一个用它来做预加载的实践案例:第一个页面预先为第四个页面发起数据加载请求,等用户进入第四个页面,那加载好的数据才会分发给它,若在数据下来前进入第四个页面,也会等完成的时候自动接收到。

这个数据需要 8 秒,如果进入到第四个页面才开始加载,体验就很不好,就算只要 1 秒,也会有一个文本从无到有闪动的过程。如果在第一个页面停留超过 8 秒,它足够完成全程预加载,进入第四个页面里面就能直接拿到数据,可谓完美预加载。

本文就是来介绍一下这个实践案例。
继续阅读

CrashWoodpecker

enframe_2015-09-02-17-51-03

因为我的 Android Studio 在使用的过程中, 经常会出现 App 崩溃了, 而 AS 自带的 logcat 并没有搜集到异常信息, 特别烦恼, 怎么折腾怎么重连都不痛快, 特别是对于那种 “启动崩” 的异常, 很难马上捕捉到, 丢失也是经常的.

所以我做了这么一个库, 仿造 Square 检测并展示内存泄露的 LeakCanary. 当开发过程中, 如果有没有处理的异常导致 crash, 使用了 CrashWoodpecker 以后, 便会起一个新的美观页面, 以很友好的方式即时展示异常信息. 更多内容可以参看一下我写在 GitHub 的文档:

CrashWoodpecker

An uncaught exception handler library like Square’s LeakCanary.

Getting started

NOTE: There is a big bug before VERSION 0.9.5, QAQ thank goodness, it has been fixed in version 0.9.5, please update to 0.9.5+.

In your build.gradle:

dependencies {
  debugCompile 'me.drakeet.library:crashwoodpecker:0.9.7'
  releaseCompile 'me.drakeet.library:crashwoodpecker-do-nothing:0.9.7'
}

In your Application class:

public class ExampleApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    CrashWoodpecker.fly().to(this);
  }
}

And in your AndroidManifest.xml file:

<application
    android:name=".ExampleApplication" // <-- 
    ...
    ...>
</application>

That is all! CrashWoodpecker will automatically show an Activity when your app crash with uncaught exceptions in your debug build.

7BDF054B-21AE-4A66-ACBF-6A51B1A0FA96

Demo apk download: LittleWood.apk

源代码: https://github.com/drakeet/CrashWoodpecker

径向羽化 FingerTransparentView

前不久群里有人问怎么实现「类似 Instagram 径向模糊透露手指底部内容」的效果。device-2015-08-06-133045-d因为要实时用算法羽化其实挺麻烦的,效率也不见得好,于是我当即很快提供了一个思路便是通过 Ps 做一张中心透明,边缘羽化的图片,再结合 Android 自定义 View 常用的 Canvas 与 Paint 这两个类的混合模式 Xfermode,在白板上挖出一个能容纳这张羽化图片的洞,混合去除,再将羽化图片填充进去即可。

说来抽象,结果便是如右 GIF 图所示。正好那天比较闲,想得快,做得也快,一个钟头完全靠着自己就几乎完美实现了。

Maven:

dependencies {
    compile 'me.drakeet.fingertransparentview:fingertransparentview:1.0.1'
}

不过,一般人可能不会用到这个东西,之所以在这边写出来,觉得它还是挺不错的一个自定义 View 教程,开发者可以看看源码学习下也不错,主要可以学到的内容有:

  • 双指缩放 Bitmap
  • 触摸事件分发与传递
  • Android 提供的混合绘图接口 Xfermode
  • 自定义 View 的一些流程

源代码:https://github.com/drakeet/FingerTransparentView
继续阅读

更温和的交互:呼吸式闪动警示 view 背景

前天晚上做了个简单的小工具类,叫做 BreathingViewHelper,传入一个 view 和需要的背景颜色之后,它的背景就会呈呼吸式闪动,可以用来做警示一些必要的内容没有填写或选择。

其实实现方法很简单,就是开个线程隔 38毫秒调用一下 setBackgroundColor 而已,之所以是 38mm 是因为只要间隔小于50毫秒的刷新率,人的肉眼就会当成是连续的;这样可以避免过多刷新,也是比较友好。

关键就是一个类呼吸函数,首先想到正弦函数,但正弦函数用起来感觉有点呼吸急促,因为它的呼和吸是均衡的,之后 Google 了下,找到一个更加逼真的呼吸函数:

s1

s2
继续阅读

AndroidUIView

前不久开始自学 Swift 并且开始开发 iOS App,发现 iOS 的 UIButton 有个特性特别喜欢,就是你只需要设置按钮的背景图片即可自动带有按下去按钮变暗的效果,而 Android 如果要做到一样的效果,通常都需要写一个 xml 文件,写 selector,而且设计师也要配合着做两种状态的图,即正常状态的图 + 按钮被按下去的状态图。 所以觉得 iOS 的这个 UIButton 这点非常实在(=。=),便简单仿造着做了个 AndroidUIView,并且提供了 XML 自定义接口,可以设置按下去蒙版的颜色、透明度、形状,还有圆角: s1 s2

(分别是正常状态图和按下去之后的状态图)

https://github.com/drakeet/AndroidUIView

继续阅读