user4413257
user4413257

Reputation:

Static data-binding in Android [literals]

I have created custom layout which contains image and title. To reuse this layout I'm using <include> tag. The problem is that I'm not even able to bind string literal into the layout being included. I tried to follow these instructions, but without success.

layout/titlebar.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="title" type="String"/>
        <!-- <variable name="imgSrc" type="android.graphics.drawable.Drawable" /> -->
    </data>
    <LinearLayout ... >
        <!-- <ImageView ... android:src="{imgSrc}" /> -->
        <TextView ... android:text="@{title, default=DefaultTitle}" />
    </LinearLayout>
</layout>

layout/otherlayout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:bind="http://schemas.android.com/apk/res-auto"
              ... 
              >
    <!-- bind:imgSrc="@{@drawable/some_image}" -->
    <include layout="@layout/titlebar"
             bind:title="@{Example}"  <---------- does not work 
             />
    ...
</LinearLayout>

In gradle I have enabled data-binding for module:

android {
    ...
    dataBinding {
        enabled = true
    }
    ...
}

Upvotes: 5

Views: 4584

Answers (2)

user4413257
user4413257

Reputation:

Fixed layout/otherlayout.xml based on @CzarMatt answer

<?xml version="1.0" encoding="utf-8"?>
<!-- 
layout with bindings has to be wrapped in <layout> tag so {LayoutName}Bindings 
class can be auto-generated for binding purposes 

xmlns:alias="http://schemas.android.com/apk/res-auto" 
creates an "app namespace" for custom attributes
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto">
    <LinearLayout  ... >
        <!-- 
        // if this layout is also using title "data variable" 
        // and we want to use default value if title is null
        bind:title='@{title ?? "Settings"} 

        // passing literal reference into the binding
        bind:title="@{@string/settings_constant}"
        -->
        <include layout="@layout/titlebar"
                 bind:title='@{"Settings"}'
                 />
        ...
    </LinearLayout>
</layout>

Data-binding requires to set layout via DataBindingUtil as @RaviRupareliya suggested, otherwise data-binding will not work:

public class OtherActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        // setContentView(R.layout.otherlayout);
        DataBindingUtil.setContentView(this, R.layout.otherlayout);
    }
    ...
}

Upvotes: 9

CzarMatt
CzarMatt

Reputation: 1823

From the docs:

Variables may be passed into an included layout's binding from the containing layout by using the application namespace and the variable name in an attribute

This means that, the following data variable must be included in both your titlebar and otherlayout XML files:

<data>
    <variable name="title" type="java.lang.String"/>
</data>

and the <include> should look something like this:

<include layout="@layout/titlebar"
       bind:title="@{title}"/>

Refer to Data Binding docs for more information:

https://developer.android.com/topic/libraries/data-binding/index.html#includes

Upvotes: 0

Related Questions