android数据绑定:如何避免编程触发的OnCheckedChange

android数据绑定:如何避免编程触发的OnCheckedChange,android,checkbox,data-binding,android-databinding,Android,Checkbox,Data Binding,Android Databinding,我现在尝试在我的项目中使用android数据绑定,遇到了这样的问题,例如:我有3个复选框作为复选框组,如果选中第一个复选框,那么变量type是1。第二个使类型为2,第三个使类型为3。所以我用这种方式实现代码 // layout.xml <android.support.v7.widget.AppCompatCheckBox android:layout_width="50dp" android:layout_height="50dp"

我现在尝试在我的项目中使用android数据绑定,遇到了这样的问题,例如:我有3个复选框作为复选框组,如果选中第一个复选框,那么变量
type
是1。第二个使
类型
为2,第三个使
类型
为3。所以我用这种方式实现代码

   // layout.xml


   <android.support.v7.widget.AppCompatCheckBox
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:checked="@{userInfoViewModel.type == 1}"
        android:onCheckedChanged="@{(compoundButton, checked) -> userInfoViewModel.onTypeChecked(checked, 1)}"
        />

   <android.support.v7.widget.AppCompatCheckBox
        android:layout_width="50dp"
        android:layout_height="55dp"
        android:checked="@{userInfoViewModel.type == 2}"
        android:onCheckedChanged="@{(compoundButton, checked) -> userInfoViewModel.onTypeChecked(checked, 2)}"
        />

    <android.support.v7.widget.AppCompatCheckBox
        android:layout_width="50dp"
        android:layout_height="55dp"
        android:checked="@{userInfoViewModel.type == 3}"
        android:onCheckedChanged="@{(compoundButton, checked) -> userInfoViewModel.onTypeChecked(checked, 3)}"
        />
现在的问题是,如果我选中了第一个复选框,那么我就选中了第二个复选框<代码>类型应设置为2,并且UI应正确更新。但实际情况是,
uncheck
事件也发生在第一个复选框上,在
type
设置为2之后,然后触发
type.set(0)
,因此不选中复选框

事实上,这个问题对我来说是一样的。我需要的是数据绑定的解决方案

在非数据绑定项目中,我认为最好的解决方案是使用
setCheckedSilent
(答案是@Emanuel Andrada)

但在数据绑定中,我无法做到这一点。有没有专家可以帮我

根据@Arpan Sharma的回答,听
onClick
,而不是
onCheckedChanged
。此解决方案目前有效,但我担心选中的
值是否始终正确

public void onTypeChecked(View view, int i) {
    Boolean checked = ((CheckBox) view).isChecked();

    if (checked) {
        type.set(i);
    } else {
        type.set(0);
    }
}

我遇到了同样的问题,我用onCLick listener代替onCHeck 这样,当以编程方式设置检查状态时,监听器不会更改检查状态。
在您的问题中,您应该尝试为您的复选框设置不同的复选更改侦听器。

我第一次遇到这个问题,我认为最好使用绑定适配器来实现

下面是绑定适配器的代码

interface OnUserCheckedChangeListener {
    fun onUserCheckChange(view:CompoundButton, isChecked:Boolean)
}
@BindingAdapter("onUserCheckedChange")
fun setUserCheckedChangeListener(view:CompoundButton, listener: OnUserCheckedChangeListener?){
    if(listener == null){
        view.setOnClickListener(null)
    }else{
        view.setOnClickListener {
            listener.onUserCheckChange(view, view.isChecked)
        }
    }
}
我们可以在任何复合按钮上使用它

<CheckBox
            android:id="@+id/finish_check"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"   
            android:checked="@{your_condition}"
            onUserCheckedChange="@{(view, checked) -> vm.onItemChecked(todo, checked)}"
            />

数据绑定非常简单

xml中的复选框组件

 <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onCheckedChanged="@{(compoundButton, checked) -> 
changeKeyboardVM.onCheckedChange(compoundButton, checked)}" />
现在布尔值检查
true
on已选中
在未选中时使用
onClick
而不是
onCheckedChanged
来防止双向绑定

来自
项目订单视图.xml

<data>

    <variable
        name="viewModel"
        type="com.package.name.OrderItemViewModel" />
</data>

           <CheckBox
                android:id="@+id/cb_selected"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="8dp"
                android:buttonTint="@color/white"
                android:checked="@{viewModel.isSelect}"
                android:onClick="@{() -> viewModel.onClickedCheckBox()}"
                android:textColor="@color/white" />

从ViewModel中公开一个ObservableBolean,然后在该布尔值上使用双向数据绑定

然后可以使用ObservableBolean的值来决定要做什么,而不是将其编码到XML中

android:checked="@={vm.checkedValue}"
见:

在CheckedChangeListener中写入

if (button.isPressed()) {
    // A user pressed Switch.
}

也许来自的一些答案可能会有所帮助,例如,定义
android:onCheckedChanged
listener,但我没有测试。

那么如何区分是选中还是取消选中呢?处理时获取当前状态?它应该能够工作。顺便说一句,谷歌是如此愚蠢?没有优雅的解决方案?我已经尝试过你的解决方案(检查问题的更新),它在我的环境中工作。但我正在考虑复选框的状态是否总是正确的。当点击回调被触发时,复选框的状态总是被更新?是的,复选框的状态将被自动更改,在监听器中,您必须检查其状态,然后相应地采取行动。每次点击都会选中/取消选中复选框。不必担心。是的,状态应该每次都更改,但我担心的是:状态是否总是在调用onclick回调之前发生变化。您没有解决问题,因为您没有设置
android:checked
。这有什么帮助?是否在
android:checked
set之后调用
onUserCheckedChange
?刷卡时是否会引发一次检查更改事件?如何处理刷卡?请显示一些代码。我不明白,你做了什么?
<data>

    <variable
        name="viewModel"
        type="com.package.name.OrderItemViewModel" />
</data>

           <CheckBox
                android:id="@+id/cb_selected"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="8dp"
                android:buttonTint="@color/white"
                android:checked="@{viewModel.isSelect}"
                android:onClick="@{() -> viewModel.onClickedCheckBox()}"
                android:textColor="@color/white" />
public class OrderItemViewModel {

    public final ObservableField<Boolean> isSelect;
    public final OrderItemViewModelListener mListener;
    private final Order mOrder;

    public OrderItemViewModel(Order order, OrderItemViewModelListener listener) {
        this.mListener = listener;
        this.mOrder = order;

        isSelect = new ObservableField<>(mOrder != null ? mOrder.isSelect() : false);
    }

    /**
     * Using onClick instead of onCheckedChanged
     * to prevent 2-ways binding issue.
     */
    public void onClickedCheckBox() {
        mListener.onCheckChanged();
    }

    public interface OrderItemViewModelListener {
        void onCheckChanged();
    } 
}
android:checked="@={vm.checkedValue}"
if (button.isPressed()) {
    // A user pressed Switch.
}