我如何(继续 post-Kotlin Android 扩展)将小部件作为数组元素(双重包含)访问?
How do I (continue to, post-Kotlin Android Extensions) access widgets as array elements (which are doubly-included)?
我正在“现代化”一些 15 个月前的代码以利用
Kotlin Extension View Binding(从已弃用的迁移
Kotlin Android 扩展编译器插件)。
我遇到的问题与使用 vars 的实践有关
在我的代码中键入 Array<ConstraintLayout>
。这是
在这篇文章中以 charKeys 为例。
我在 XML.
中使用嵌套的 include
s
我正在努力寻找正确的新语法或方法。我
尚无法编译此代码。
注意:所有 Kotlin 和 XML 已缩减为仅相关部分。
首先,“旧”方法 - 效果很好。
PuzzleFragment.kt
import kotlinx.android.synthetic.main.fragment_puzzle.*
import kotlinx.android.synthetic.main.item_keyboard.*
import kotlinx.android.synthetic.main.item_keyboard.view.*
import kotlinx.android.synthetic.main.item_kkey.view.*
:
class PuzzleFragment : Fragment() {
lateinit var charKeys: Array<ConstraintLayout>
charKeys = arrayOf(
kbd_char_0,
kbd_char_1
:
)
fragment_puzzle.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/puzzle_fragment"
>
<include layout="@layout/item_keyboard" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_keyboard.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/keyboard"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/kbd_char_0"
>
<include layout="@layout/item_kkey" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/kbd_char_1"
>
<include layout="@layout/item_kkey" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
item_kkey.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
>
<TextView
android:id="@+id/kkey"
/>
</merge>
同样,所有这些都在(正在)工作(使用 Kotlin Android
扩展)。而这段代码允许(允许)我做事
喜欢:
PuzzleFragment.kt
for (x in 0 until someNumber) {
val shape = charKeys[x].background as GradientDrawable
shape.setStroke(...)
charKeys[x].kkey.setTextColor(...)
for (key in charKeys)
key.isEnabled = false
for ((kx, key) in charKeys.withIndex())
key.elevation = ... //using kx
for (cx in 0 until maxGuessLength)
makeKeyRed(charKeys[cx], true)
private fun makeKeyRed(key: ConstraintLayout, doRed: Boolean) {
when {
doRed -> key.kkey.setTextColor(...)
key.kkey.text != "#" -> key.kkey.setTextColor(...)
else -> key.kkey.setTextColor(...)
}
}
所以 - 那是老办法。一切都很酷。现在我正在转换这段代码。我有:
PuzzleFragment.kt
import com.zazzem.thats.databinding.FragmentPuzzleBinding
class PuzzleFragment : Fragment(R.layout.fragment_puzzle) {
private var _binding: FragmentPuzzleBinding? = null
private val binding get() = _binding!!
以下代码似乎没问题(IDE 中没有“突出显示”的错误):
lateinit var charKeys: Array<ConstraintLayout>
charKeys = arrayOf(
binding.item_keyboard.kbd_char_0,
binding.item_keyboard.kbd_char_1,
:
)
for (x in 0 until someNumber) {
val shape = charKeys[x].background as GradientDrawable
shape.setStroke(...)
但它与下一行代码“分崩离析”:
charKeys[x].kkey.setTextColor(...)
它不喜欢这里的“kkey”(“未解决的引用”)。而且,事实上,
基本代码完成 (Ctrl + Space) 显示 none 个小部件
是 item_kkey.
的一部分
我不知道我是否只是遗漏了一些明显的东西?或者如果这个
整个“'vaguely-typed' ConstraintLayouts 数组”方法不是
有效(不再)?或者介于两者之间?
您的 .kkey
是合成 属性 的另一种用法,因此如果没有 Kotlin Android 扩展,您将无法做到这一点。合成 属性 在幕后使用 findViewById
在任何你调用它的 ConstraintLayout 上找到子视图。
对于视图绑定,不存在此类视图属性。但是生成的 class 确实具有 include
块的属性。这些属性 return 是您要包含的布局文件的生成绑定 classes。但是,您尚未在 include
元素上使用 android:id
元素,因此无法通过绑定 class.
访问它们
即使您这样做了,也不会与此处的 ConstraintLayout Array 策略兼容。
为了便于转换代码,我建议您创建一个直接替换合成 属性 的代码,如下所示:
val ConstraintLayout.kkey: TextView get() = findViewById(R.id.kkey)
与合成属性 属性 相比,它的一个缺点是每次使用它时都必须查找视图,这比重复使用合成属性要慢一些。但我认为它在这里不是很重要,因为这个特定视图始终是您正在搜索的布局的唯一子视图。
请注意,此策略具有与他们弃用 Android 扩展相同的弱点。在任意 ConstraintLayout 上调用它是不安全的。
我正在“现代化”一些 15 个月前的代码以利用 Kotlin Extension View Binding(从已弃用的迁移 Kotlin Android 扩展编译器插件)。
我遇到的问题与使用 vars 的实践有关
在我的代码中键入 Array<ConstraintLayout>
。这是
在这篇文章中以 charKeys 为例。
我在 XML.
中使用嵌套的include
s
我正在努力寻找正确的新语法或方法。我 尚无法编译此代码。
注意:所有 Kotlin 和 XML 已缩减为仅相关部分。
首先,“旧”方法 - 效果很好。
PuzzleFragment.kt
import kotlinx.android.synthetic.main.fragment_puzzle.*
import kotlinx.android.synthetic.main.item_keyboard.*
import kotlinx.android.synthetic.main.item_keyboard.view.*
import kotlinx.android.synthetic.main.item_kkey.view.*
:
class PuzzleFragment : Fragment() {
lateinit var charKeys: Array<ConstraintLayout>
charKeys = arrayOf(
kbd_char_0,
kbd_char_1
:
)
fragment_puzzle.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/puzzle_fragment"
>
<include layout="@layout/item_keyboard" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_keyboard.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/keyboard"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/kbd_char_0"
>
<include layout="@layout/item_kkey" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/kbd_char_1"
>
<include layout="@layout/item_kkey" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
item_kkey.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
>
<TextView
android:id="@+id/kkey"
/>
</merge>
同样,所有这些都在(正在)工作(使用 Kotlin Android 扩展)。而这段代码允许(允许)我做事 喜欢:
PuzzleFragment.kt
for (x in 0 until someNumber) {
val shape = charKeys[x].background as GradientDrawable
shape.setStroke(...)
charKeys[x].kkey.setTextColor(...)
for (key in charKeys)
key.isEnabled = false
for ((kx, key) in charKeys.withIndex())
key.elevation = ... //using kx
for (cx in 0 until maxGuessLength)
makeKeyRed(charKeys[cx], true)
private fun makeKeyRed(key: ConstraintLayout, doRed: Boolean) {
when {
doRed -> key.kkey.setTextColor(...)
key.kkey.text != "#" -> key.kkey.setTextColor(...)
else -> key.kkey.setTextColor(...)
}
}
所以 - 那是老办法。一切都很酷。现在我正在转换这段代码。我有:
PuzzleFragment.kt
import com.zazzem.thats.databinding.FragmentPuzzleBinding
class PuzzleFragment : Fragment(R.layout.fragment_puzzle) {
private var _binding: FragmentPuzzleBinding? = null
private val binding get() = _binding!!
以下代码似乎没问题(IDE 中没有“突出显示”的错误):
lateinit var charKeys: Array<ConstraintLayout>
charKeys = arrayOf(
binding.item_keyboard.kbd_char_0,
binding.item_keyboard.kbd_char_1,
:
)
for (x in 0 until someNumber) {
val shape = charKeys[x].background as GradientDrawable
shape.setStroke(...)
但它与下一行代码“分崩离析”:
charKeys[x].kkey.setTextColor(...)
它不喜欢这里的“kkey”(“未解决的引用”)。而且,事实上, 基本代码完成 (Ctrl + Space) 显示 none 个小部件 是 item_kkey.
的一部分我不知道我是否只是遗漏了一些明显的东西?或者如果这个 整个“'vaguely-typed' ConstraintLayouts 数组”方法不是 有效(不再)?或者介于两者之间?
您的 .kkey
是合成 属性 的另一种用法,因此如果没有 Kotlin Android 扩展,您将无法做到这一点。合成 属性 在幕后使用 findViewById
在任何你调用它的 ConstraintLayout 上找到子视图。
对于视图绑定,不存在此类视图属性。但是生成的 class 确实具有 include
块的属性。这些属性 return 是您要包含的布局文件的生成绑定 classes。但是,您尚未在 include
元素上使用 android:id
元素,因此无法通过绑定 class.
即使您这样做了,也不会与此处的 ConstraintLayout Array 策略兼容。
为了便于转换代码,我建议您创建一个直接替换合成 属性 的代码,如下所示:
val ConstraintLayout.kkey: TextView get() = findViewById(R.id.kkey)
与合成属性 属性 相比,它的一个缺点是每次使用它时都必须查找视图,这比重复使用合成属性要慢一些。但我认为它在这里不是很重要,因为这个特定视图始终是您正在搜索的布局的唯一子视图。
请注意,此策略具有与他们弃用 Android 扩展相同的弱点。在任意 ConstraintLayout 上调用它是不安全的。