I'm trying to use databinding with custom views (a possible usage George Mount showed here).
One can't imagine building compound views without <merge>
tag. However, in this situation databinding fails:
MyCompoundView
class:
public class MyCompoundView extends RelativeLayout { MyCompoundViewBinding binding; public MyCompoundView (Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context){ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); binding = MyCompoundViewBinding.inflate(inflater, this, true); }
my_compound_view.xml
: by app:isGone="@{!data.isViewVisible}"
i hoped to control the visibility of the whole compound view
<?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" > <data> <variable name="data" type="com.example.MyViewModel"/> </data> <merge android:layout_width="wrap_content" android:layout_height="wrap_content" app:isGone="@{!data.isViewVisible}"> <ImageView android:id="@+id/image_image" android:layout_width="60dp" android:layout_height="60dp" app:imageUrl="@{data.imagePhotoUrl}"/> <!-- tons of other views--> </merge> </layout>
The compiler errors:
Error:(13) No resource identifier found for attribute 'isGone' in package 'com.example' Error:(17, 21) No resource type specified (at 'isGone' with value '@{!data.isViewVisible}').
I have all needed @BindingAdapter
methods. Now I inherit the view from FrameLayout
and use <RelativeLayout>
instead of <merge>
- and it works. But I have extra nested layout.
Question: merge
attrs are ignored. Is there any way to workaround that?
Android Studio 1.5.1 stable
Gradle plugin com.android.tools.build:gradle:1.5.0
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.
Kotlin Android Extensions is deprecated, which means that using Kotlin synthetics for view binding is no longer supported.
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.
Use the <merge> tag For example, if your main layout is a vertical LinearLayout in which two consecutive views can be re-used in multiple layouts, then the re-usable layout in which you place the two views requires its own root view.
There is no merge object after inflation, so there is nothing to assign values to with a merge tag. I can't think of any binding tag that will work on merge.
You can assign the tag to the root element and use the BindingAdapter to do what you want.
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" > <data> <variable name="data" type="com.example.MyViewModel"/> </data> <merge android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView app:isGone="@{!data.isViewVisible}" android:id="@+id/image_image" android:layout_width="60dp" android:layout_height="60dp" app:imageUrl="@{data.imagePhotoUrl}"/> <!-- tons of other views--> </merge> </layout>
If you want to do something with the Binding class itself, you can use the DataBindingUtil to find the object from the View.
@BindingAdapter("isGone") public static void setGone(View view, boolean isGone) { ViewDataBinding binding = DataBindingUtil.findBinding(view); //... do what you want with the binding. }
Actually you can use <merge>
tag inside <include>
and do data binding.
Ex:
incl_button.xml
<layout> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:id="btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click" /> </merge> </layout>
fragment_example.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/incl_button" android:id="@+id/layout_btn" /> </LinearLayout> </layout>
ExampleFragment.kt
binding.layoutBtn.btn.setOnClickListener{ //... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With