在设置双向数据绑定的绑定适配器时出现了错误:<标识符> 期望。

4

我正在尝试为TextInputEditText设置双向绑定,使用的是Float变量。

下面是我整个DataBindingAdapters类的内容:

object DataBindingAdapters  {
    @BindingAdapter("android:text")
    @JvmStatic
    fun setText(view: TextInputEditText, value: Float) {
        if(value != view.text.toString().toFloat()) {
            view.setText(value.toString())
        }
    }


    @InverseBindingAdapter(attribute = "android:text")
    fun getText(view: TextInputEditText): Float  {

        return view.text.toString().toFloat()
    }

}

但我得到的是:
error: <identifier> expected
            float callbackArg_0 = mBindingComponent.null.getText(inputFieldSize);

我漏掉了什么?


你是否正在尝试通过双向绑定将 LiveData<Float> 对象设置到 UI 的 android:text 上?如果是的话,我建议在两个方法中都将这些 Float 参数设置为可空。 - Jeel Vankhede
你已经找到解决方案了吗? - LMaker
@LMaker 不是的。只是使用字符串来绑定... - Alexander Suraphel
你解决了吗?怎么解决的? - Dr4ke the b4dass
@Dr4ketheb4dass 我通过使用字符串绑定并在保存时进行转换来完全规避了这个问题。这不值得。现在我已经转向 Compose :) - Alexander Suraphel
3个回答

3

您需要另外一个绑定适配器,如InverseBindingAdapter文档中所述:

@BindingAdapter(value = [ "android:textAttrChanged"], requireAll = false)
fun setTextWatcher( view: TextInputEditText, textAttrChanged: InverseBindingListener?) {
    val newValue =  object: TextWatcher {
        override fun afterTextChanged(s: Editable?) = Unit

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit

        override fun onTextChanged( s:CharSequence,  start:Int,  before:Int,  count:Int) {
                textAttrChanged?.onChange()
        }
    }

    val  oldValue = ListenerUtil.trackListener(view, newValue, R.id.textWatcher)
    if (oldValue != null) {
        view.removeTextChangedListener(oldValue)
    }
    view.addTextChangedListener(newValue)
}

当你创建@InverseBindingAdapter(attribute = "android:text")时,会创建一个事件android:textAttrChanged,你需要为它添加一个绑定适配器。
调用textAttrChanged?.onChange()将触发你创建的InverseBindingAdapter
编辑: 另外,由于你使用的是Kotlin,所以不需要将绑定适配器放在一个object中。一个单独的文件就足够了。只需删除包装object DataBindingAdapters {..}@JvmStatic即可。

1
不幸的是,这对我没有起作用。我仍然得到相同的错误。 - Alexander Suraphel
@AlexanderSuraphel 你是如何解决的? - William Hu
1
@WilliamHu 我通过使用字符串绑定并在保存时进行转换来完全规避了这个问题。这不值得。现在我已经转向 Compose :) - Alexander Suraphel

1

我曾经遇到过同样的问题,通过像官方文档中一样将反向绑定适配器设置为静态的方式解决了它:

    @InverseBindingAdapter(attribute = "android:text")
    @JvmStatic fun getText(view: TextInputEditText): Float  {

        return view.text.toString().toFloat()
    }

请注意在fun getText(...之前的@JvmStatic。这是与您问题中的代码唯一不同之处。
顺便说一下:Mohru's answer也在编辑部分提到了这一点,但至少对我来说,它并不明显,无法在第一时间找到;)

0

我有同样的问题,

解决方法是:

class MyView {
  companion object {
     @BindingAdapter("android:text")
    @JvmStatic
    fun setText(view: TextInputEditText, value: Float) {
        if(value != view.text.toString().toFloat()) {
            view.setText(value.toString())
        }
    }


    @InverseBindingAdapter(attribute = "android:text")
    fun getText(view: TextInputEditText): Float  {

        return view.text.toString().toFloat()
    }
  }
}

此外,您可能需要添加textAttrChanged事件。如果必要,它会告诉您xxx: textAttrChanged未找到......错误。然后在companion object主体旁边添加以下方法。
@BindingAdapter(value = ["android:textAttrChanged"], requireAll = false)
        @JvmStatic fun setValue(view: MyView, textAttrChanged: InverseBindingListener) {
            val newValue = object : TextWatcher {
                override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
                override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
                override fun afterTextChanged(s: Editable) {
                    textAttrChanged.onChange()
                }
            }
            view.binding.editText.addTextChangedListener(newValue)
        }

除此之外,您可能会在上述代码中收到警告。

然后您可以使用:

object XXXAdapter {
   //Put the binding methods here.
}

为了消除警告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接