Search code examples
androidandroid-databindingandroid-mvvmandroid-radiogroup

How to check radiobuttons using kotlin code while using MVVM architecture?


I am using MVVM architecture in my app and there are 4 radiobuttons in a 2*2 grid inside a radiogroup but the the problem is oncheckedChanged is not getting called in viewmodel class, here's the xml code:

          <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/_10sdp"
            android:checkedButton="@id/singleRadioBtn"
            android:onCheckedChanged="@{viweModel::selectOption}"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <RadioButton

                    android:layout_width="0dp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_weight="1"
                  ></RadioButton>

                <Space
                    android:layout_width="@dimen/_8sdp"
                    android:layout_height="match_parent" />

                <RadioButton

                    android:layout_width="0dp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_weight="1"
                   ></RadioButton>
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/_8sdp"
                android:orientation="horizontal">

                <RadioButton

                    android:layout_width="0dp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_weight="1"
               ></RadioButton>

                <Space
                    android:layout_width="@dimen/_8sdp"
                    android:layout_height="match_parent" />

                <RadioButton
                    android:layout_width="0dp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_weight="1"
                  ></RadioButton>
            </LinearLayout>
        </RadioGroup>

and in viewmodel:

 fun selectOption(radioGroup: RadioGroup, id: Int)
    {
        radioGroup.check(id)
    }

But the above function is not getting called. So what I am doing wrong here? Please help!


Solution

  • I think your problem is not with DataBinding - it's rather because you put LinearLayouts inside RadioGroup. Since Radiogroup is a subclass of LinearLayout itself it makes a mess, so in general you'll have to do something additional in code to make it work (but then DataBinding in the case is not so useful), you can look through discussion here.

    If you try to place RadioButtons just inside RadioGroup (without nested LinearLayouts) I guess your method should be called.

    As a workaround you could bind another callback - each RadioButton's onClick (setting index of RadioGroup there explicitly):

    //...........
    <RadioButton
          android:layout_width="0dp"
          android:layout_height="30dp"
          android:layout_weight="1"
          android:onClick="@{(v) -> viewModel.selectOption(1)}"
    ></RadioButton>
    
    <Space
         android:layout_width="8dp"
         android:layout_height="match_parent" />
    
    <RadioButton
    
         android:layout_width="0dp"
         android:layout_height="30dp"
         android:layout_weight="1"
         android:onClick="@{(v) -> viewModel.selectOption(2)}"
    ></RadioButton>
    //...............
    

    UPDATE

    One of the choices - to make it work according to your current model:

    1. To give id to Radiogroup (so it can be used in binding expression)
    2. To give ids to RadioButtons
    3. To change a little bit method in ViewModel

    XML

    <RadioGroup
        android:layout_width="match_parent"
        android:id="@+id/radioGroup"
        .......>
    <RadioButton
        android:layout_width="0dp"
        android:id="@+id/button1"
        android:onClick="@{(v) -> viewModel.selectOption(radioGroup,v)}" // <- v - is your button
    

    ViewModel

    fun selectOption(radioGroup: RadioGroup, radioButton: View)
    {
        radioGroup.check(radioButton.id)
    }