I was searching over the internet for how to perform the new cool android data-binding over the RadioGroup
and I didn't find a single blog post about it.
Its a simple scenario, based on the radio button selected, I want to attach a callback event using android data binding. I don't find any method on the xml part which allows me to define a callback.
Like here is my RadioGroup:
<RadioGroup
android:id="@+id/split_type_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:checkedButton="@+id/split_type_equal"
android:gravity="center"
<!-- which tag ? -->
android:orientation="horizontal">
...
</RadioGroup>
How do I attach a handler method which will be called on RadioGroup
's checkChnged
event will fire using data-binding?
I have tried using onClick
(don't know if it is the same) in layout file and defining method in the Activity and located it using this in the layout file:
<variable
name="handler"
type="com.example.MainActivity"/>
...
<RadioGroup
android:onClick="handler.onCustomCheckChanged"
.. >
And defined method onCustomCheckChanged
like this:
public void onCustomCheckChanged(RadioGroup radio, int id) {
// ...
}
But, it gives me the compilation error:
Error:(58, 36) Listener class android.view.View.OnClickListener with method onClick did not match signature of any method handler.onCustomCheckChanged
I have seen many blogs mentioning it is possible with RadioGroup
but non of them really say how. How can I handle this with data-binding
?
After digging to the bunch of methods, I found this question on SO which helped me understand how to bind single methods of listeners.
Here is what to do with RadioGroup:
In
RadioGroup
listener you have a methodonCheckedChanged(RadioGroup g, int id)
. So you can directly bound that method to your handler or your activity by passing an instance of it as a variable in layout file and calling a method with the same signature.So call on layout file like this:
And in my activity or handler, I need to simply provide the method with same name and signature like this:
Just make sure method is public.
NOTE: This works for any (most of, I have not tried all) listener methods. Like for
EditText
you can provideandroid:onTextChanged
and so on.After some hours I found easy way: two-way databinding in android. It's base skeleton with livedata and Kotlin. Also you can use ObservableField()
layout.xml
In my current project, I did it like this. I have three currency in the project and I choose one of them via RadioGroup.
It's enum with currencies:
A piece of my ViewModel:
Part of my layout (pay attention to binding in RadioGroup and tags of RadioButton):
And the final part - binding adapter.
In this way, I got two-way binding between RadioGroup and a property in my ViewModel.
Often you care more about what was actually checked instead of "something was checked". In such case alternative solution is to ignore RadioGroup and bind all items as below:
where optionA, optionB and optionC are defined in ViewModel like below:
This is usually enough, however if you want to react immediately on click then you can add callBacks and use them like that:
Advantage of such approach is that you don't need to compare and track "id".
I am using a string, and in this case I have bindable based on
viewModel.getCommuteType() viewModel.setCommuteType(String)