Search code examples
androiddata-bindingandroid-databinding

RadioButton onCheckedChanged with DataBinding and lambdas


I have a RadioButton:

<RadioButton
    android:id="@+id/rdioA"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:checked="@{!q.b}"
    android:onCheckedChanged="@{(cb, isChecked) -> {if (isChecked) q.setB(false)}}"
    android:text="AAA"/>

The variable 'q' is defined as:

<data>
    <import type="android.view.View"/>
    <variable name="q" type="com.example.Q"/>
</data>

The function in Q.java is:

public void setB(boolean b) {
    this.b = b;
}

The compilation error i get is:

/Users/../view_d.xml
Error:(60, 53) Syntax error: extraneous input '=' expecting {<EOF>, '.', '::', '[', '+', '-', '*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'} 
Error:Execution failed for task ':app:compileDevDebugJavaWithJavac'.
> java.lang.RuntimeException: Found data binding errors.

If I use

android:onCheckedChanged="@{q::onCheckedChanged}"

there is no issue - it works.


Solution

  • You cannot use statements in data binding expressions. This includes curly braces or if statements. Use this instead:

    <RadioButton
        android:id="@+id/rdioA"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:checked="@{!q.b}"
        android:onCheckedChanged="@{(cb, isChecked) -> (isChecked) ? q.setB(false) : void}"
        android:text="AAA"/>
    

    You can use ternary expressions to replace if statements. If you want to do nothing, the void keyword can be used to indicate no return value. This works because onCheckedChanged() has a void return value. If you were binding to a listener that expected a return value like onLongClick(), you would use the return type of that listener instead -- true or false for onLongClick()

    You should try to avoid using complex logic inside your data binding expressions. The choice to not support statements was to try to limit the complexity of binding expressions.