解决方案
基于this issue 和this fix:
ViewExtension.kt
fun View.animateFadeOut(animDuration: Long = 250L) {
this.animate()
.alpha(0F)
.setDuration(animDuration)
.setListener(object : AbstractAnimatorListener() {
override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
super.onAnimationEnd(animation, isReverse)
show(false)
}
override fun onAnimationEnd(p0: Animator?) {
show(false)
}
})
.start()
}
fun View.show(show: Boolean) {
val vis = if (show) View.VISIBLE else View.GONE
if (visibility != vis) {
visibility = vis
}
}
AbstractAnimatorListener.kt
abstract class AbstractAnimatorListener : Animator.AnimatorListener {
override fun onAnimationRepeat(p0: Animator?) {}
override fun onAnimationEnd(p0: Animator?) {}
override fun onAnimationCancel(p0: Animator?) {}
override fun onAnimationStart(p0: Animator?) {}
override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
onAnimationEnd(animation)
}
override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
onAnimationStart(animation)
}
}
说明
尝试使用 Java 8 Defaults 删除 API 26 中添加的这些方法并使用替代动画:
Animator.AnimatorListener:
在 API 级别 26 中添加了 onAnimationEnd
void onAnimationEnd (Animator animation, boolean isReverse)
在 API 级别 26 中添加了 onAnimationStart
void onAnimationStart (Animator animation, boolean isReverse)
这些方法可以被覆盖,但不是必需的,以便在动画开始时获取额外的播放方向信息。
AnimatorSet:
从 Android 8.0 (API 26) 开始,AnimatorSet API 支持
反向搜索和播放。
注意:
/**
* Skipping calling super when overriding this method results in
* {@link #onAnimationStart(Animator)} not getting called.
*/
default void onAnimationStart(Animator animation, boolean isReverse) {
onAnimationStart(animation);
}
我需要将this 添加到我的build.gradle 文件中进行测试
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
或替换
super.onAnimationEnd(animation, isReverse)
通过
onAnimationEnd(animation)
为了避免错误:
在 JVM 目标 1.6 中禁止对 Java 默认方法进行超级调用。
用'-jvm-target 1.8'重新编译
并将下一行添加到我的 gradle.properties 文件 thanks to this answer
android.enableD8=true
为了避免异常:
com.android.dx.cf.code.SimException:默认或静态界面
没有使用 --min-sdk-version >= 24
的方法
现在可以编译了,刚刚启动了一个kitKat模拟器……
它可以工作,而且我的项目中也启用了 MultiDex。
对不起,我无法复制它。
或者,使用 Java 8 默认删除这两个方法,它也可以工作。
注意2:
关于 AnimatorListenerAdapter 的 Arpan 建议可行,但没有必要。
您可以删除这些方法,更改动画并创建:
object EmptyAnimatorListener : Animator.AnimatorListener {
override fun onAnimationRepeat(p0: Animator?) {}
override fun onAnimationEnd(p0: Animator?) {}
override fun onAnimationCancel(p0: Animator?) {}
override fun onAnimationStart(p0: Animator?) {}
}
并像这样使用委托:
.setListener(object : Animator.AnimatorListener by EmptyAnimatorListener {
override fun onAnimationStart(animation: Animator) {
// Do something
}
override fun onAnimationEnd(animation: Animator) {
// Do something
}
})
注3:
转载添加到扩展函数中:
E/AndroidRuntime: 致命异常: main
进程:...机器人,PID:3409
java.lang.VerifyError: com/.../ui/common/extension/android/view/ViewExtensionKt$animateFadeOut$1
使用 Java Defaults 删除 Api 26 方法可以解决问题。
-
替换调用你的 onAnimationEnd 的超级调用也可以解决它:
override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
onAnimationEnd(animation)
}
调用 super.onAnimationStart(animation: Animator?, isReverse: Boolean) 需要 API 26:
- 反编译 Kotlin 字节码显示这些方法无法解析: