QMUI Android
(官网) 终于发布了,今天趁热打铁,来聊一聊 QMUI Android
开发背后的一些点滴。
关于源码学习
在 Android 里,写 UI 控件基本上是入门的第一步,Android 官方为我们提供了大量的控件,写一些简单的 UI 还是蛮轻松的一件事情,可是要写好 UI 也不是一件容易的事情。说实话,Android 提供的接口这特么的不好用,很多接口都不能很清楚的表达其含义。很多时候都需要你读过源码,梳理过其逻辑,你才会知道其含义,只有读过源码,你才会知道 Android 很多隐藏的而又非常厉害的 API,你才能在实现 UI 特效时信手拈来。
我们在Android UI学习时,一定要做到深入了解其实现机制,否则会四处碰壁,举个例子,就拿沉浸式状态栏来说,市面上已经存在很多款其封装库,但如果你不了解其本质,这些库看上去再完美,你可能依旧无法实现设计师想要的效果,QMUI 也提供了沉浸式方案,简单情况一句代码就解决,复杂情况则需要配合 QMUIWindowInsetLayout
来处理,如果不懂其原理,估计用起来会很痛苦,可以读读我的这篇博文来掌握其原理。
再举另一个例子,我们可能需要像微博一样可以在内容区域加@人或者话题功能,Android 为我们提供了 ClickSpan
来解决 TextView
中这种点击行为。然而 ClickSpan
用起来并不简单,因为这涉及了一些列的知识点,包括 TextView
的事件传递、 ClickSpan
、LinkMovementMethod
的相互影响,使得使用者头疼不已,QMUI
封装了 QMUISpanTouchFixTextView
和 QMUITouchableSpan
,但使用者依然要视情况调用 setMovementMethodDefault()
、 setNeedForceEventToParent(bool needForceEventToParent)
,这是框架为了保证灵活性,系统接口如此,我目前能给出的最优解就是这样了,其原理我的这篇博文也做了阐述。
关于实现方案的探讨
在日常开发中,我们需要广泛的了解 Android 为我们提供的 API,同一个效果,可能有很多种实现方案,但好的方案和坏的方案可能会相差很多。让我举个例子,比方说要实现这个效果:
如果你去网上搜,那么给出的方案基本上都是 LinearLayout
包裹 ImageView
和 TextView
的方案。然而这种方式个人认为不是最佳,TextView
是何其强大啊,何必需要如此包裹,很多人可能只是尝试过 setCompoundDrawables
,但因为没办法做到图标居中而放弃,然而我们还有 ImageSpan
可以用啊,虽然会有对齐问题,但稍加封装即可,因此QMUI
给出的方案是:
textView.setText(QMUISpanHelper.generateSideIconText(true, iconTextSpace, "赠送给好友",wechatDrawable));
TextView
的 span
是异常强大的,可以 google 出一堆的特效,并且我们可以基于 ReplacementSpan
来实现各种自定义效果,其教程 在此。 我们平时要善于发现与总结,这样码其字来才舒心。
关于自定义 View
自定义 View 是每个 UI 开发都必须掌握的,其核心就三个方法:measure
、layout
、draw
,但要完全掌握它们则却是很难的,唯有多读多写才能熟练。QMUI
有一个组件 QMUIFloatLayout
, 我们团队把它作为每个新手的练习任务,要求每个成员有独立写出这个组件的能力。因为这个组件对 measure
和 layout
都能起到很好的练习作用。我觉得这个组件绝对是新人练手的好项目。
QMUI
还存在一个非常牛逼的自定义组件:QMUIQQFaceView
, 这是一个简化的TextView
,支持text、ellipse、QQ表情、QMUITouchSpan
这些基础功能,其主要是为了修复使用 ImageSpan
来显示大量QQ表情的卡顿问题,目前在微信读书上有很好的性能表现。其实微信朋友圈也是自定义View,我其实是看到微信这么做,所以我也这么做的。这个控件基本能满足大多数的场景需求,但是不能设置 gravity
和段间距,因此对它的重构也在进行中了,之后不久就可以与大家见面了。
关于事件分发
日常开发过程中,我们其实很少碰到需要自己处理事件分发的情况。想要下拉刷新?一搜一大片。想要实现 ToolBar
和 RecyclerView
嵌套滚动? CoordinatorLayout
来帮忙。作为一个框架,QMUI
也提供了QMUIPullRefreshLayout
来做下拉刷新,因为这是经常用到的,但我们并没有像其它库一样提供很多内置的 RefreshView
,因为不同的 App 需要的RefreshView
基本都不相同,我认为最主要的还是保证灵活性。关于嵌套滚动,我写了篇文章:玩转Android嵌套滚动;关于下拉刷新的使用,其实我也提供了一个案例:企业微信同事吧下拉刷新动画的实现分析。
关于全局配置
UI 开发接触得最多的颜色、间距。如果一个框架拿出去给别人用,颜色、间距没有一点的配置空间,那会被吊打的,所以我们会提供自己的 Theme, 强制需要使用者使用我们的Theme,这会有一定的侵入性,但如果原本就用的是 Compat Theme 的话,也基本没有影响。
这种方案也就需要开发者对 Theme 有一定的了解了。至少应该能知道取资源时 "@" 和 "?" 的区别。理解这些是有好处的,假如有一天产品让你改 WebView 里调起来的 dialog 的样式时,如果你对 "?" 一点不了解,那你就一点办法都没有了。
关于Android中的坑点
UI 开发强依赖与系统 API,那么系统 API 的本身的问题或者版本差异导致的问题,就只有我们自己去修复了。QMUI
中会修复许多的或大或小的坑点,使得使用者专注于业务逻辑开发。此外,我最近也记录了一些列 Android中的注意事项或技巧 。浏览一遍,或许能对你产生一些帮助。