Android 数据绑定:多次调用自定义绑定适配器时生成的代码中缺少返回语句

问题描述 投票:0回答:2

我正在使用android数据绑定库和MVVM架构。在 xml 布局中,我定义了一个名为 viewModel、类型为 myViewModel 的变量。该布局有几个 TextInputEditText,我使用了以下自定义绑定适配器:

//makes the drawable_right of the TextView clickable
@SuppressLint("ClickableViewAccessibility")
@BindingAdapter("onDrawableRightClick")
inline fun TextView.setOnDrawableRightClick(crossinline f: () -> Unit) {
    this.setOnTouchListener(View.OnTouchListener { _, event ->
        if (event.action == MotionEvent.ACTION_UP) {
            if (event.rawX >= this.right - this.paddingRight - this.compoundDrawables[DRAWABLE_RIGHT].bounds.width()) {
                f()
                return@OnTouchListener true
            }
        }
        false
    })
}

在布局中,我将

app:onDrawableRightClick="@{() -> viewModel.doThing()}"
添加到其中一个 TextInputEditText 中,然后单击运行。一切正常,没问题。

现在我返回并将

app:onDrawableRightClick="@{() -> viewModel.doOtherThing()}"
添加到第二个 TextInputEditText。这次编译失败并显示
error: missing return statement

错误出现在MyFragmentBindingImpl(生成)中,在这段代码中:

public final kotlin.Unit _internalCallbackInvoke(int sourceId ) {
    switch(sourceId) {
        case 1: {
            // localize variables for thread safety
            // viewModel
            com.example.MyViewModel viewModel = mViewModel;
            // viewModel != null
            boolean viewModelJavaLangObjectNull = false;

            viewModelJavaLangObjectNull = (viewModel) != (null);
            if (viewModelJavaLangObjectNull) {

                   viewModel.doOtherThing();
            }
            return null;
        }
        case 2: {
            // localize variables for thread safety
            // viewModel
            com.example.MyViewModel viewModel = mViewModel;
            // viewModel != null
            boolean viewModelJavaLangObjectNull = false;

            viewModelJavaLangObjectNull = (viewModel) != (null);
            if (viewModelJavaLangObjectNull) {

                viewModel.doThing();
            }
            return null;
        }  
    }
}

switch 之外既没有默认情况,也没有 return 语句。这会导致错误,但我非常确定处理每种情况时都不需要默认情况...无论如何,当我返回 xml 并删除侦听器绑定之一时,MyFragmentBindingImpl 会更改为:

public final kotlin.Unit _internalCallbackInvoke(int sourceId ) {
    // localize variables for thread safety
    // viewModel
    com.example.MyViewModel viewModel = mViewModel;
    // viewModel != null
    boolean viewModelJavaLangObjectNull = false;

    viewModelJavaLangObjectNull = (viewModel) != (null);
    if (viewModelJavaLangObjectNull) {

      viewModel.doThing();
    }
    return null;
}

编译器又高兴了,但我需要多次使用绑定适配器。如何让库添加返回语句?有解决办法吗?

我正在使用 Android Studio 3.4 预览版。谢谢大家

java android kotlin android-databinding android-binding-adapter
2个回答
11
投票
@SuppressLint("ClickableViewAccessibility")
@BindingAdapter("onDrawableEndClick")
fun setOnDrawableEndClick(view: TextView, listener: OnCompoundDrawableClickListener?) {
    val padding = 10
    if (listener != null) {
        view.setOnTouchListener { _, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                if (view.compoundDrawables[DRAWABLE_RIGHT] == null) return@setOnTouchListener false
                else if (event.rawX >= (view.right - view.compoundDrawables[DRAWABLE_RIGHT].bounds.width() - padding)) {
                    listener.onDrawableEnd()
                    return@setOnTouchListener true
                }
            }
            return@setOnTouchListener false
        }
    }
}

尝试这样的事情,我正在为侦听器使用自定义接口(OnCompoundDrawableClickListener)


0
投票

我知道我们已经有了这个问题的答案,这是一个相当古老的话题。但是当我在我的案例中尝试第一个解决方案时,我不得不创建太多不必要的接口,所以我在这里提出了另一个解决方案:

在视图模型中,而不是:

fun doThing() {/* Do thing */}
fun doOtherThing() {/* Do other thing */}

我把它改为:

val doThing: () -> Unit = {/* Do thing */}
val doOtherThing: () -> Unit = {/* Do other thing */}

然后在 XML 文件中:

...
app:onDrawableRightClick="@{viewModel.doThing}"
...
app:onDrawableRightClick="@{viewModel.doOtherThing}"

它在我的情况下效果很好,希望它可以帮助别人。

© www.soinside.com 2019 - 2024. All rights reserved.