将布尔值绑定到复选框MVVM

时间:2018-04-25 09:22:01

标签: java android mvvm

我正在尝试通过viewmodel将布尔值绑定到视图,但Android Studio会抛出错误,我无法找到问题。 viewModel.infilltype是一个布尔值,android:checked也应该是一个布尔值。

"错误:' @ {viewModel.infillType}'与属性android:checked(attr)boolean不兼容。 消息{kind = ERROR,text = error:' @ {viewModel.infillType}'与属性android不兼容:checked(attr)boolean。,sources = [E:\ SportveldOnderhoud \ app \ src \ main \ res \ layout \ list_item_check.xml:14],原始消息=,工具名称= Optional.of(AAPT) )}"

我有以下代码(我将粘贴相关的代码段)

Check.java(Model)

public class Check {

    private UUID mId;
    private String mTitle;
    private Date mDate;
    ....
    private boolean mInfilltype;
    ....

    public Check() {
        this(UUID.randomUUID());
    }

    public Check(UUID id) {
        mId = id;
        mDate = new Date();
    }
    public UUID getId() {
        return mId;
    }

    ....

    public boolean isInfilltype() {
        return mInfilltype;
    }

    public void setInfilltype(boolean infilltype) {
        mInfilltype = infilltype;
    }
}

视图模型:

public class CheckViewModel extends BaseObservable {
    private Check mCheck;
    private Activity mActivity;

    public CheckViewModel(Activity activity) {
        mActivity = activity;
    }

    @Bindable
    public String getTitle() {
        return mCheck.getTitle();
    }

    @Bindable
    public String getRenderedDate() {
        return mCheck.getDate().toString();
    }

    @Bindable
    public boolean infillType() {
        return mCheck.isInfilltype();
    }

    public Check getCheck() {
        return mCheck;
    }

    public void setCheck(Check crime) {
        mCheck = crime;
        List<String> strings;
        notifyChange();
    }

    public void onCheckClicked() {
        Intent intent = CheckPagerActivity.newIntent(mActivity, mCheck.getId());
        mActivity.startActivity(intent);
    }
}

查看:

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable name="viewModel" type="nl.lekolkman.android.sportveldonderhoud.CheckViewModel" />
    </data>

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{() -> viewModel.onCheckClicked()}"
        >

        <CheckBox
            android:id="@+id/solved_check_box"
            android:checked="@{viewModel.infillType}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"/>

        <TextView
            android:id="@+id/title_text_view"
            android:text="@{viewModel.title}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/solved_check_box"
            android:textStyle="bold"
            tools:text="Crime Title"/>

        <TextView
            android:id="@+id/date_text_view"
            android:text="@{`Date solved: ` + viewModel.renderedDate ?? `(not solved)`}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/solved_check_box"
            android:layout_below="@id/title_text_view"
            tools:text="Check Date"/>

    </RelativeLayout>
</layout>

3 个答案:

答案 0 :(得分:1)

原来我必须添加:

android { 
...
    dataBinding {
            enabled = true
        } 
build.gradle中的

然而它仍然无法正常工作,但是在将maven添加到build.gradle文件中的存储库后,它确实有效

答案 1 :(得分:0)

我对java并不是很熟悉,但我很确定在C#中你的boolean需要一个初始值(非null)来正确绑定。

尝试更改

private boolean mInfilltype;

private boolean mInfilltype = false;

答案 2 :(得分:0)

您可以使用或展开Android Compound View绑定适配器

import androidx.databinding.BindingAdapter;
import androidx.databinding.BindingMethod;
import androidx.databinding.BindingMethods;
import androidx.databinding.InverseBindingListener;
import androidx.databinding.InverseBindingMethod;
import androidx.databinding.InverseBindingMethods;
import androidx.annotation.RestrictTo;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
/**
 * @hide
 */
@RestrictTo(RestrictTo.Scope.LIBRARY)
@BindingMethods({
        @BindingMethod(type = CompoundButton.class, attribute = "android:buttonTint", method = "setButtonTintList"),
        @BindingMethod(type = CompoundButton.class, attribute = "android:onCheckedChanged", method = "setOnCheckedChangeListener"),
})
@InverseBindingMethods({
        @InverseBindingMethod(type = CompoundButton.class, attribute = "android:checked"),
})
public class CompoundButtonBindingAdapter {
    @BindingAdapter("android:checked")
    public static void setChecked(CompoundButton view, boolean checked) {
        if (view.isChecked() != checked) {
            view.setChecked(checked);
        }
    }
    @BindingAdapter(value = {"android:onCheckedChanged", "android:checkedAttrChanged"},
            requireAll = false)
    public static void setListeners(CompoundButton view, final OnCheckedChangeListener listener,
            final InverseBindingListener attrChange) {
        if (attrChange == null) {
            view.setOnCheckedChangeListener(listener);
        } else {
            view.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (listener != null) {
                        listener.onCheckedChanged(buttonView, isChecked);
                    }
                    attrChange.onChange();
                }
            });
        }
    }
}

参考:code docs