android数据绑定:如何避免编程触发的OnCheckedChange
我现在尝试在我的项目中使用android数据绑定,遇到了这样的问题,例如:我有3个复选框作为复选框组,如果选中第一个复选框,那么变量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"
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.
}