Android 这是Kotlin';s";“懒惰”吗;?
我一直在努力追踪这个奇怪的异常现象,相信这是Kotlin的一个bug。每当我在UI中单击前两个按钮中的一个时,最后一个按钮会镜像其背景,就像它也被单击一样 我相信这个bug与我使用的“by lazy”有关,因为如果我修改代码并使用一个函数来分配背景,bug就会消失 我做了。该应用程序很简单,只有3个切换按钮,如下所示: 在这个屏幕截图中,我只点击了按钮#1,注意到按钮#3的背景也根据指定的背景绘制而改变,即使您检查按钮#3,它也会显示为“checked=false” 这是我的片段代码:Android 这是Kotlin';s";“懒惰”吗;?,android,kotlin,Android,Kotlin,我一直在努力追踪这个奇怪的异常现象,相信这是Kotlin的一个bug。每当我在UI中单击前两个按钮中的一个时,最后一个按钮会镜像其背景,就像它也被单击一样 我相信这个bug与我使用的“by lazy”有关,因为如果我修改代码并使用一个函数来分配背景,bug就会消失 我做了。该应用程序很简单,只有3个切换按钮,如下所示: 在这个屏幕截图中,我只点击了按钮#1,注意到按钮#3的背景也根据指定的背景绘制而改变,即使您检查按钮#3,它也会显示为“checked=false” 这是我的片段代码: cla
class FirstFragment : Fragment() {
private val buttonBackgroundDrawable by lazy {
context?.let { context ->
ContextCompat.getDrawable(context, R.drawable.button_background)
}
}
private fun getButtonBackground(): Drawable? {
return context?.let { context ->
ContextCompat.getDrawable(context, R.drawable.button_background)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_first, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Bugged
buttonBackgroundDrawable?.let { bgDrawable ->
toggleButton1.background = bgDrawable
toggleButton2.background = bgDrawable
toggleButton3.background = bgDrawable
}
// Works
// toggleButton1.background = getButtonBackground()
// toggleButton2.background = getButtonBackground()
// toggleButton3.background = getButtonBackground()
}
}
以下是背景可绘制代码:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape android:shape="oval">
<corners android:radius="6dp" />
<solid android:color="#f00" />
</shape>
</item>
<item>
<shape android:shape="oval">
<corners android:radius="6dp" />
<solid android:color="#aaa" />
<stroke android:width="3dp" android:color="#fff" />
</shape>
</item>
</selector>
如果有人确认这是一个bug,或者向我解释我在代码中做错了什么,我很乐意听到,因为我对这一点完全感到困惑。这是预期的行为
lazy
只在第一次访问属性时初始化属性一次,因此您正在实例化一个由所有按钮共享的可绘制属性。更改可绘制实例的属性值将影响共享同一可绘制实例的任何内容
至于为什么您的第二个按钮没有改变,这可能只是由于在多个视图上使用StateListDrawable实例而导致的未定义的行为,这是从未打算执行的操作,但显然不会触发任何警告
另一方面,您的
getButtonBackground()
函数每次调用时都会实例化一个不同的可绘制实例,因此每个按钮都会获得自己的不同可绘制实例。这是预期的行为lazy
只在第一次访问属性时初始化属性一次,因此您正在实例化一个由所有按钮共享的可绘制属性。更改可绘制实例的属性值将影响共享同一可绘制实例的任何内容
至于为什么您的第二个按钮没有改变,这可能只是由于在多个视图上使用StateListDrawable实例而导致的未定义的行为,这是从未打算执行的操作,但显然不会触发任何警告
另一方面,您的
getButtonBackground()
函数每次调用时都会实例化一个不同的可绘制实例,因此每个按钮都会获得自己的不同可绘制实例。这不是一个懒惰的
错误,这是由单个可绘制实例引起的getButtonBackground()
每次调用它时都会创建新实例。drawable单个实例属性的更改会影响应用到的其他视图。
因此,您需要为所有按钮或xml中的集合创建新的drawable。这不是一个
惰性
错误,这是由drawable的单个实例引起的getButtonBackground()
每次调用它时都会创建新实例。drawable单个实例属性的更改会影响应用到的其他视图。
因此,您需要为所有按钮或集合创建新的可绘制xml