android - 除非我使用显式范围,否则为什么 Kotlin Synthetic 为 Null
问题描述
所以我在这里有一些代码在 1 个月前可以工作。
profile_clickable.throttleClicks {
logger.logEvent(PageTags.MENU_PROFILE_NAV)
edit_picture_button.visibility = View.GONE
ProfileActivity.start(this@HomeMenuActivity, avatar.transition(), username.transition())
}
这段代码现在失败,NPE on edit_picture_button
, avatar
,username
都是 Kotlin 合成的。
当我对这些项目中的每一个(见下文)添加一个显式调用时,它突然起作用了。
profile_clickable.throttleClicks {
logger.logEvent(PageTags.MENU_PROFILE_NAV)
this@HomeMenuActivity.edit_picture_button.visibility = View.GONE
ProfileActivity.start(this@HomeMenuActivity, this@HomeMenuActivity.avatar.transition(), this@HomeMenuActivity.username.transition())
}
throttleClicks 是一个扩展方法,它可以做到这一点:
fun View.throttleClicks(
windowDurationMs: Long = 800,
onClick: View.() -> Unit
) {
setOnClickListener(object : View.OnClickListener {
// Set lastClickTime to - windowDurationMs to ensure the first click won't be throttled.
var lastClickTime = -windowDurationMs
override fun onClick(v: View?) {
val time = SystemClock.elapsedRealtime()
if (time - lastClickTime >= windowDurationMs) {
lastClickTime = time
onClick()
}
}
})
}
为什么我突然必须使用显式范围来避免 NPE?
解决方案
因为您在 type 的函数中使用合成View.() -> Unit
。
所以this
在函数中是你应用这个函数(profile_clickable
)的视图。
Kotlin 合成物的工作方式类似于
val View.profile_clickable: ImageView get() {
if (cache exists) {
return cache
}
return this.findViewById(R.id.profile_clickable)
}
profile_clickable
没有孩子,所以会有例外。
您可以使用以下代码:
profile_clickable.throttleClicks {
logger.logEvent(PageTags.MENU_PROFILE_NAV)
this@HomeMenuActivity.run {
edit_picture_button.visibility = View.GONE
ProfileActivity.start(this, avatar.transition(), username.transition())
}
}
推荐阅读
- vue-cli - magraph:xml to graph 没有出现在我的页面中。(我在Vue-cli中使用了mxgraph)
- python - 使用“”将 unicode 转换为字符串
- angular - 从 Typescript 中的枚举中获取所有项目的数组
- javascript - 从数据数组创建嵌套对象和数组
- angular - 如何使用 AngularFirebase 和 Angular 7 从用户集合中获取用户数据
- java - java中如何替换多个字符串类型同名标签之间的值
- c++ - 不使用命名空间的日期库
- python - 无法正确检测和掩盖轮廓
- jenkins - testng / Jenkins - 包含名称,参数化
- pytorch - 如何在 Pytorch 中保存和加载随机数生成器状态?