繁体   English   中英

我如何(继续,后 Kotlin Android 扩展)访问小部件作为数组元素(这是双重包含)?

[英]How do I (continue to, post-Kotlin Android Extensions) access widgets as array elements (which are doubly-included)?

我正在“现代化”一些 15 个月大的代码以利用 Kotlin 扩展视图绑定(从已弃用的 Kotlin ZE84E30B9390CDB64DB6DB2C9AB87846D 编译器插件迁移)。

我遇到的问题与在我的代码中使用Array<ConstraintLayout>类型的变量的做法有关。 整个帖子中的charKeys都说明了这一点。

我在 XML 中使用嵌套的include

我正在努力寻找正确的新语法或方法。 我还不能编译这段代码。

注意:所有 Kotlin 和 XML 已缩减为仅相关部分。

首先,“旧”方式 - 效果很好。

拼图碎片.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 扩展)。 此代码允许(允许)我执行以下操作:

拼图碎片.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(...)
        }
    }

@@@@@@@@@@@@@@@@@@@@@@@

所以 - 这是老方法。 一切都很酷。 现在我正在转换这段代码。 我有:

拼图碎片.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) 不显示属于 item_kkey 的任何小部件。

我不知道我是否只是遗漏了一些明显的东西? 或者,如果整个“'模糊类型'ConstraintLayouts 数组”方法无效(不再有效)? 或者如果它介于两者之间?

与往常一样,非常感谢任何帮助、建议和想法。

您的.kkey是合成属性的另一种用途,因此如果没有 Kotlin Android 扩展,您将无法做到这一点。 合成属性在您调用它的任何 ConstraintLayout 上使用findViewById来查找子视图。

使用视图绑定,不存在视图的此类属性。 但是生成的 class 确实具有include块的属性。 这些属性返回您包含的布局文件的生成绑定类。 但是,您尚未在include元素上使用android:id元素,因此无法通过绑定 class 访问它们。

即使您这样做了,这也与您的 ConstraintLayout Array 策略不兼容。

我建议为了便于转换代码,您可以直接替换合成属性,如下所示:

val ConstraintLayout.kkey: TextView get() = findViewById(R.id.kkey)

与合成属性相比,这样做的一个缺点是每次使用它时都必须找到视图,这比合成属性在重复使用时要慢一些。 但我认为它在这里不会很重要,因为这个特定的视图始终是您正在搜索的布局的唯一子级。

请注意,此策略具有与他们弃用 Android 扩展相同的弱点。 在任意 ConstraintLayout 上调用它是不安全的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM