简体   繁体   中英

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
    }
    ...
}

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);
    }
    ...
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM