使用lambda找不到数据绑定事件的方法

时间:2018-01-17 00:30:33

标签: android data-binding lambda kotlin android-databinding

我使用:: notation(即UIImageView)进行了一些事件,但是这需要android:onClick="@{vm::doIt}"的签名才能拥有不必要的doIt参数,我最终会这样做忽略未使用的警告。我正在尝试清理它并转移到lambda事件表示法(即`android:onClick =“@ {() - > vm.doIt()},但编译器会抛出异常。

layout.xml

View

ViewModel.kt

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="vm"
            type="com.myapp.ViewModel"/>
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> vm.buttonClicked()}"
            <!--android:onClick="@{vm::buttonClicked}" worked with view param in buttonClicked in the viewModel -->
            android:text="@{vm.buttonText}"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </android.support.constraint.ConstraintLayout>
</layout>

错误

class ViewModel(): BaseObservable{

    //Bindings - All works great!

    //Event handler... not found, worked with commented param and :: notation
    fun buttonClicked(/*view: View*/){
        //Do button click stuff
    }
}

3 个答案:

答案 0 :(得分:3)

正如您在关于android:onClick="@{vm::doIt}"解决方案的评论中所述,即使您不使用它,onClick处理程序也必须具有View参数。

只要lambda接受buttonClicked参数,通过lambda调用无参数View方法的解决方法就可以很好地工作,。这很简单。 Unused parameters to lambdas can be named "_"为清楚起见。因此可以配置onClick处理程序:

android:onClick="@{_ -> vm.buttonClicked()}"

答案 1 :(得分:1)

显然,数据绑定生成的类处于错误状态,并且没有正确重新生成,使缓存无效并且清理修复了问题。

答案 2 :(得分:0)

方法的签名在viewModel中必须相同

我正在使用

android:onClick="@{v -> viewModel.settingsClick(v)}"

,viewModel中的方法是

 public void settingsClick() {
   ...
}