Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android data binding with a custom view

The Android data binding guide discusses binding values within an activity or fragment, but is there a way to perform data binding with a custom view?

I would like to do something like:

<LinearLayout     android:layout_width="match_parent"     android:layout_height="match_parent">      <com.mypath.MyCustomView         android:id="@+id/my_view"         android:layout_width="match_parent"         android:layout_height="40dp"/>  </LinearLayout> 

with my_custom_view.xml:

<layout>  <data>     <variable         name="myViewModel"         type="com.mypath.MyViewModelObject" /> </data>  <LinearLayout     android:layout_width="match_parent"     android:layout_height="match_parent">      <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="@{myViewModel.myText}" />  </LinearLayout>  </layout> 

While it appears possible to do this by setting custom attributes on the custom view, this would quickly become cumbersome if there's a lot of values to bind.

Is there a good way to accomplish what I'm trying to do?

like image 234
Dave Avatar asked Jan 14 '16 20:01

Dave


People also ask

Can we use view binding and data binding together in Android?

View binding doesn't support layout variables or layout expressions, so it can't be used to declare dynamic UI content straight from XML layout files. View binding doesn't support two-way data binding.

What is view binding in Android?

View Binding is one of the best features which provides the views to bind with the activity which is ongoing. Replacing the findViewById() method, hence reducing the boilerplate code, generated the instances of the views of the current layout.

What is a custom view in Android?

A well-designed custom view is much like any other well-designed class. It encapsulates a specific set of functionality with an easy to use interface, it uses CPU and memory efficiently, and so on. In addition to being a well-designed class, though, a custom view should: Conform to Android standards.

Is data binding good in Android?

Using data binding can lead to faster development times, faster execution times and more readable and maintained code. Android data binding generates binding classes at compile time for layouts.


2 Answers

In your Custom View, inflate layout however you normally would and provide a setter for the attribute you want to set:

private MyCustomViewBinding mBinding; public MyCustomView(...) {     ...     LayoutInflater inflater = (LayoutInflater)         context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);     mBinding = MyCustomViewBinding.inflate(inflater); }  public void setMyViewModel(MyViewModelObject obj) {     mBinding.setMyViewModel(obj); } 

Then in the layout you use it in:

<layout xmlns...>     <data>         <variable             name="myViewModel"             type="com.mypath.MyViewModelObject" />     </data>      <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent">          <com.mypath.MyCustomView             android:id="@+id/my_view"             app:myViewModel="@{myViewModel}"             android:layout_width="match_parent"             android:layout_height="40dp"/>      </LinearLayout> </layout> 

In the above, an automatic binding attribute is created for app:myViewModel because there is a setter with the name setMyViewModel.

like image 55
George Mount Avatar answered Sep 16 '22 18:09

George Mount


First, don't do this if this custom view is already being <include> in another layout, such as activity etc. You'll just get an exception about the tag being unexpected value. The data binding already ran the binding on it, so you're set.

Did you try using onFinishInflate to run the bind? (Kotlin example)

override fun onFinishInflate() {     super.onFinishInflate()     this.dataBinding = MyCustomBinding.bind(this) } 

Keep in mind that if you use the binding in your view, it won't be able to be created programmatically, at least it would be very convoluted to support both even if you can.

like image 43
androidguy Avatar answered Sep 16 '22 18:09

androidguy