自定义视图在使用时生成数据绑定错误

custom view generate data binding error when use it

我创建了一个自定义视图如下

class SquareCheckBox @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0) : ConstraintLayout (context, attrs, defStyle){

    private var layout: ConstraintLayout
    private var checkImageView : ImageView
    private var iconImageView : ImageView
    private var titleTextView : TextView

    var isChecked : Boolean = false
    var iconImage : Int = -1
    var title : String = ""

    init {

        val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val view = inflater.inflate(R.layout.item_square_checkbox, this, true)

        layout = view.layout
        checkImageView = view.checkImageView
        iconImageView = view.iconImageView
        titleTextView = view.titleTextView

        initAttributes(attrs)
        applyUIChanges()
        addAction()

    }

    fun initAttributes(attrs: AttributeSet?){

        attrs?.let {
            val typedArray = context.obtainStyledAttributes(it, R.styleable.square_checkbox_attributes, 0, 0)
            isChecked = typedArray.getBoolean(R.styleable.square_checkbox_attributes_isChecked, false)
            iconImage = typedArray.getResourceId(R.styleable.square_checkbox_attributes_iconImage, -1)
            title = typedArray.getString(R.styleable.square_checkbox_attributes_title)

            typedArray.recycle()
        }
    }

    fun applyUIChanges () {

        if (isChecked) {
            checkImageView.visibility = View.VISIBLE
            titleTextView.setTextColor(resources.getColor(android.R.color.black))
            layout.setBackgroundResource(R.drawable.xml_square_checkbox_selected)
        } else {
            checkImageView.visibility = View.INVISIBLE
            titleTextView.setTextColor(resources.getColor(R.color.lightGray))
            layout.setBackgroundResource(R.drawable.xml_square_checkbox_unselected)
        }

        if (iconImage != -1) {
            iconImageView.setImageResource(iconImage)
        }

        titleTextView.setText(title)
    }

    fun addAction () {

        layout.setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View?) {
                isChecked = !isChecked
                applyUIChanges()
            }
        })
    }
}

这是 xml

<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/xml_square_checkbox_unselected">

        <ImageView
                android:id="@+id/checkImageView"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:src="@drawable/ic_ckeck"
                android:tint="@color/colorPrimary"
                android:visibility="visible"
                app:layout_constraintEnd_toEndOf="parent"
                android:layout_marginTop="4dp"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_marginEnd="4dp"
                android:layout_marginRight="4dp"/>

        <ImageView
                android:id="@+id/iconImageView"
                android:layout_width="35dp"
                android:layout_height="35dp"
                android:layout_centerHorizontal="true"
                android:src="@drawable/ic_placeholder_squre" app:layout_constraintTop_toBottomOf="@+id/checkImageView"
                app:layout_constraintBottom_toTopOf="@+id/titleTextView"
                app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
                android:layout_marginRight="8dp" app:layout_constraintStart_toStartOf="parent"
                android:layout_marginLeft="8dp" android:layout_marginStart="8dp"/>

        <TextView
                android:id="@+id/titleTextView"
                android:layout_width="90dp"
                android:layout_height="wrap_content"
                android:layout_below="@id/iconImageView"
                android:ellipsize="end"
                android:gravity="center"
                android:lines="2"
                android:text="@string/text"
                android:maxLines="2"
                android:textColor="@android:color/black"
                android:textSize="12sp"
                android:layout_marginBottom="4dp"
                android:layout_marginStart="4dp"
                android:layout_marginEnd="4dp"
                android:layout_marginRight="4dp"
                android:layout_marginTop="8dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/iconImageView"
                app:layout_constraintEnd_toEndOf="parent"
                />

    </androidx.constraintlayout.widget.ConstraintLayout>
</merge>

现在当我尝试像这样在我的 MVVM 中使用我的自定义视图时

<com.playground.components.SquareCheckBox
                android:id="@+id/inAppMessageCheckBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:isChecked="@{viewModel.inAppEnabled}"
                app:iconImage="@drawable/ic_allow_inapp"
                app:title="@string/post_listing_settings_in_app_message"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/voipCheckBox" android:layout_marginStart="8dp"
                android:layout_marginEnd="8dp">

它给我以下错误

****/ data binding error ****msg:Cannot find the setter for attribute 'app:isChecked' with parameter type boolean on com.playground.components.SquareCheckBox. file:/Volumes/Data/Work/Amira_Playground/Playground/app/src/main/res/layout/recycler_view_basic_information_settings_item.xml loc:20:33 - 20:54 ****\ data binding error ****

谁能请教一下?

似乎应该可以,但可能 setter 的 name/parameter 解析有问题。文档指出:

For an attribute named example, the library automatically tries to find the method setExample(arg) that accepts compatible types as the argument. The namespace of the attribute isn't considered, only the attribute name and type are used when searching for a method.

您可以使用自定义绑定适配器轻松解决此问题。参见:https://developer.android.com/topic/libraries/data-binding/binding-adapters

像这样:

@BindingAdapter("isChecked")
fun setIsChecked(view: SquareCheckBox, checked: Boolean) {
    view.setChecked(checked)
}