作为今年 Google I/O Android Jetpack 的一部分,由去年加盟 Google 的 Jake Wharton 主理的 Android KTX 也发布了第一个 alpha 版本。

A set of Kotlin extensions for Android app development.

Android KTX 的自述很简单,”给安卓开发的 Kotlin extensions 集合”

翻阅 Android KTX 的源码会发现,里面的代码其实非常少,但仍在 alpha 阶段的 Android KTX 却已经收获了超过 7000 个赞。

什么是 Kotlin Extensions

Kotlin provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator. This is done via special declarations called extensions. Kotlin supports extension functions and extension properties.

简单来说就是可以在不继承父类的情况下装饰(扩展)父类,支持对方法和属性进行装饰(扩展)

E.g. :

一般情况下为属性动画添加回调时会需要这样写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
val shrinkAnimator = ValueAnimator.ofFloat(1F, 0F)
...
shrinkAnimator.addListener(object: Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator ? ) {
// Do nothing.
}

override fun onAnimationEnd(animation: Animator ? ) {
hide()
}

override fun onAnimationCancel(animation: Animator ? ) {
// Do nothing.
}

override fun onAnimationStart(animation: Animator ? ) {
// Do nothing.
}
})

而在 Kotlin Extentions 的帮助下可以写成这样

1
2
3
val shrinkAnimator = ValueAnimator.ofFloat(1F, 0F)
...
shrinkAnimator.doOnEnd { hide() }

Kotlin Extensions 在原来 ValueAnimator上增加了一个 doOnEnd()方法,调用起来感觉就跟原生方法一样。

怎么用 Kotlin Extensions

通过查看 Android KTX 的源码可知,上面提到的 doOnEnd()方法即为

1
fun Animator.doOnEnd(action: (animator: Animator) -> Unit) = addListener(onEnd = action)

其调用的 addListener()方法为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fun Animator.addListener(
onEnd: ((animator: Animator) -> Unit)? = null,
onStart: ((animator: Animator) -> Unit)? = null,
onCancel: ((animator: Animator) -> Unit)? = null,
onRepeat: ((animator: Animator) -> Unit)? = null
): Animator.AnimatorListener {
val listener = object : Animator.AnimatorListener {
override fun onAnimationRepeat(animator: Animator) {
onRepeat?.invoke(animator)
}

override fun onAnimationEnd(animator: Animator) {
onEnd?.invoke(animator)
}

override fun onAnimationCancel(animator: Animator) {
onCancel?.invoke(animator)
}

override fun onAnimationStart(animator: Animator) {
onStart?.invoke(animator)
}
}
addListener(listener)
return listener
}

清晰明了,简单易用,对吧。

Kotlin Extensions 是怎么工作的

shrinkAnimator.doOnEnd { hide() }反编译后的代码

1
2
3
4
5
6
7
8
9
10
11
12
var10000 = this.shrinkAnimator;
AnimatorKt.doOnStart((Animator) var10000, (Function1)(new Function1() {
public Object invoke(Object var1) {
this.invoke((Animator) var1);
return Unit.INSTANCE;
}

public final void invoke(@NotNull Animator it) {
Intrinsics.checkParameterIsNotNull(it, "it");
it.hide()
}
}));

doOnEnd方法反编译后的代码

1
2
3
4
5
public static final AnimatorListener doOnEnd(@NotNull Animator $receiver, @NotNull Function1 action) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
Intrinsics.checkParameterIsNotNull(action, "action");
return addListener$default($receiver, action, (Function1) null, (Function1) null, (Function1) null, 14, (Object) null);
}

很明显,Kotlin 其实只是配合 IDE 用了一个障眼法来”欺骗”我们,但这不妨碍我们把代码写得更简洁好看 : )

Reference