如何在android中使用双向数据绑定单选按钮

时间:2018-03-09 13:01:08

标签: android android-databinding 2-way-object-databinding

我正在尝试使用双向数据绑定单选按钮。它的工作方式很好,例如`android:checked =“@ {registration.gender.equals(Gender.FEMALE.getValue())}”。但我的问题是我需要在模型中设置选择单选按钮值。

<?xml version="1.0" encoding="UTF-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools">
   <data>
      <import type="com.callhealth.customer.comman.enums.Gender" />
      <import type="android.text.TextUtils" />
      <import type="java.lang.Integer" />
      <variable name="callback" type="com.callhealth.customer.usermanagement.callback.RegistrationCallback" />
      <variable name="registration" type="com.callhealth.customer.usermanagement.model.request.LoginAndRegistrationRequestModel" />
   </data>
   <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="vertical">
      <android.support.v7.widget.AppCompatTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/label_gender" android:textSize="15sp" />
      <RadioGroup android:id="@+id/gender_group" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:orientation="horizontal">
         <android.support.v7.widget.AppCompatRadioButton android:layout_width="wrap_content" android:checked="@={registration.gender.equals(Gender.MALE.getValue())}" android:layout_height="wrap_content" android:text="@string/label_male" />
         <android.support.v7.widget.AppCompatRadioButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginStart="20dp" android:checked="@={registration.gender.equals(Gender.FEMALE.getValue())}" android:text="@string/label_female" />
      </RadioGroup>
   </LinearLayout>
</layout>

我的模特课

public class LoginAndRegistrationRequestModel extends BaseObservable {

    private Integer gender;

    @Bindable
    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
        notifyPropertyChanged(BR.gender);
    }   
}

当我尝试使用

android:checked="@={registration.gender.equals(Gender.FEMALE.getValue())}" 

Gradel投掷错误

Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> android.databinding.tool.util.LoggedErrorException: Found data binding errors.
  ****/ data binding error ****msg:The expression registrationGender.equals(com.callhealth.customer.comman.enums.Gender.MALE.getValue()) cannot be inverted: There is no inverse for method equals, you must add an @InverseMethod annotation to the method to indicate which method should be used when using it in two-way binding expressions
  file:S:\Umesh\android\android_studio_workspace\CallHealth\app\src\main\res\layout\content_user_registration.xml
  loc:148:48 - 148:97
  ****\ data binding error ****

3 个答案:

答案 0 :(得分:0)

您将其绑定到boolean EXPRESSION。设置它时,它不知道调用什么方法。我会尝试将您的媒体设为boolean(例如isFemale)。听起来有一种方法可以用@InverseMethod注释来指示setter,但我还没有使用它,在我看来boolean方法会更直接。如果您想在java代码的其他地方引用boolean,则可以始终根据Integer gender字段实施Integer属性。

答案 1 :(得分:0)

Try it

  

Blockquote

几个小时后,我找到了简单的方法:在android中进行双向数据绑定。它是livedata和Kotlin的基本骨架。您也可以使用ObservableField()

  • 将视图模型设置为数据

  • 根据需要使用按钮创建您的无线电组。重要提示:全部设置 单选按钮ID !!!

  • 在您的无线电组中设置对已检查变量的双向绑定(使用 viewmodel变量)

  • 享受)

layout.xml

<data>
    <variable
        name="VM"
        type="...YourViewModel" />
</data>


<LinearLayout
            android:id="@+id/settings_block_env"
            ...
            >


            <RadioGroup

                android:id="@+id/env_radioGroup"
                android:checkedButton="@={VM.radio_checked}">

                <RadioButton
                    android:id="@+id/your_id1"/>

                <RadioButton
                   android:id="@+id/your_id2" />

                <RadioButton
                    android:id="@+id/your_id3"/>

                <RadioButton
                    android:id="@+id/your_id4"/>
            </RadioGroup>

        </LinearLayout>

class YourViewModel(): ViewModel {

var radio_checked = MutableLiveData<Int>()


init{
    radio_checked.postValue(R.id.your_id1)//def value
}

//other code
}
  

Blockquote

答案 2 :(得分:0)

您可以为自定义转换器创建@InverseMethod(错误表明它基本上不能转换成等于性别),也可以仅使用布尔值observable进行更改,设置器将立即可用。

例如,如果有

val isFemale = ObservableBoolean() 

在您的ViewModel中,这将立即可用

android:checked="@={viewModel.isFemale}" 

当然,您需要在布局绑定中提供ViewModel变量。

要“修复”那里的内容,您需要创建自己的反方法和设置器以进行检查。

@InverseMethod("toGender")
public static int isFemaleGender(Integer gender) {
        return gender.equals(Gender.FEMALE.getValue());
    } 

public static Integer toGender(boolean checked) {
        if (checked) 
           return Gender.FEMALE;
        else 
           return Gender.MALE;
    }

这两种方法只有在您有2个选项时才有效,因为您基本上会执行true false。您可以为每个选项创建一个Observable或使用@Serega Maleev提供的解决方案