我使用android数据绑定库,我有一个带复选框的布局,我需要使用自定义检查逻辑(layout)。
有没有办法创建这样的绑定,检查其中一个框会导致其余部分取消选中?什么是最好的方法?
答案 0 :(得分:1)
我建议如下:
OnClickListener
XML
<LinearLayout
android:id="@+id/parent"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<CheckBox android:id="@+id/checkbox_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1"
android:onClick="onCheckboxClicked"/>
<CheckBox android:id="@+id/checkbox_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2"
android:onClick="onCheckboxClicked"/>
</LinearLayout>
活动
public void onCheckboxClicked(View clickedView)
{
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
for (int i=0; i < parent.getChildCount(); i++)
{
View view = parent.getChildAt(i);
if (view instanceof CheckBox)
{
CheckBox checkbox = (CheckBox) view;
if (checkbox.isChecked() && !checkbox.equals(clickedView)) {
checkbox.setChecked(false);
}
}
}
}
您显然可以创建一个名为 CheckBoxGroup 的自定义ViewGroup
,它会收到复选框并自动实现此流程。但我不认为这是必要的,它会使事情复杂化。并且也不会那么灵活,因为复选框必须全部在其中。
答案 1 :(得分:0)
复选框通常单独使用,每个复选框都注册了一个单独的点击监听器。 Android指南也是如此。您可以在以下位置查看:https://developer.android.com/guide/topics/ui/controls/checkbox.html。
但是,如果您有需要使用它们的场景,则必须创建一个逻辑用于自己处理它。 Checkbox有一个方法 setChecked(boolean),可用于设置状态:如果要检查状态,则为true;如果未选中状态,则为false。
您可以附加一个监听器来检查更改是否为支票。
checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
}
});
为每个复选框附加单独的侦听器。当一个更改的检查状态对其他复选框进行适当的更改时。
checkbox1.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
checkbox2.setChecked(false);
checkbox3.setChecked(false);
}
}
});
checkbox2.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
checkbox1.setChecked(false);
checkbox3.setChecked(false);
}
}
});
checkbox3.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
checkbox1.setChecked(false);
checkbox2.setChecked(false);
}
}
});
如果您需要用户只能选择其中一个选项,则可以使用单选按钮并使用无线电组。
电台组: https://developer.android.com/reference/android/widget/RadioGroup.html
答案 2 :(得分:0)
这是你可以尝试的东西。
static
方法并将checkbox
及其值和父布局传递给您,其中包含所有复选框。xml文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.example.Bindings" />
</data>
<RelativeLayout
android:id="@+id/activity_demo"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/linearParent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/chk1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->Bindings.setCheckbox(chk1,linearParent)}"
android:text="1" />
<CheckBox android:id="@+id/chk2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->Bindings.setCheckbox(chk2,linearParent)}"
android:text="2" />
<CheckBox android:id="@+id/chk3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->Bindings.setCheckbox(chk3,linearParent)}"
android:text="3" />
<CheckBox android:id="@+id/chk4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->Bindings.setCheckbox(chk4,linearParent)}"
android:text="4" />
</LinearLayout>
</RelativeLayout>
这是您的自定义方法
public static void setCheckbox(CheckBox checkBox, LinearLayout parentLayout) {
for (int i = 0; i < parentLayout.getChildCount(); i++) {
if (parentLayout.getChildAt(i) instanceof CheckBox) {
CheckBox child = (CheckBox) parentLayout.getChildAt(i);
if (child.getId() != checkBox.getId())
child.setChecked(false);
}
}
}
就是这样,你完成了代码:)
答案 3 :(得分:0)
您可以使用ObservableBoolean
。作为绑定,您只需使用android:checked="@={observableBoolean}"
进行设置即可。使用双向数据绑定setOnCheckedChangeListener()
不再起作用,但您现在已经在视图模型中拥有了这些值。
现在您只需要创建自己的广播组。这可以通过Observable.OnPropertyChangedCallback
addOnPropertyChangedCallback()
ObservableBoolean
到您用于复选框的所有new Observable.OnPropertyChangedCallback() {
private ObservableBoolean observable = new ObservableBoolean();
public void onPropertyChanged(Observable sender, int propertyId) {
ObservableBoolean observable = (ObservableBoolean) sender;
if (observable.get()) {
this.observable.set(false);
this.observable = observable;
}
}
}
轻松实现。
=JOIN(CHAR(10),QUERY(TRANSPOSE(IMPORTRANGE(spreadsheet_key,reference_string)),,2E6))
答案 4 :(得分:0)
为了完成类似的任务,我做了以下工作:
创建了一个独特的ViewModel,它添加在xml
的数据字段中
<import type="android.view.View"/>
<variable
name="viewModel"
type="compackagename.MyViewModel" />
在xml绑定中注意@ = {...}这称为双向绑定(从双向绑定更新变量会自动更新xml)
<CheckBox
android:checked="@={viewModel.checked1}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox
android:checked="@={viewModel.checked2}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
为MyViewModel中的每个复选框添加了ObservableBoolean字段
public final ObservableBoolean checked1 = new ObservableBoolean();
checked1.set(false);
checked2.set(false);
checked1.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable observable, int i) {
if (checked1.get()){
checked2.set(false);
}
}
});
checked2.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable observable, int i) {
if (checked2.get()){
checked1.set(false);
}
}
});
你可以通过在列表中添加ObservableBooleans来优化这一点,但上面是一个很好的起点。