27

I am trying to replicate this answer: Setting attribute of child element of included layout

I have a simple custom_edit_text.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="hint123" type="String" />
    </data>
    <android.support.design.widget.TextInputLayout
        android:id="@+id/emailInputLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <android.support.v7.widget.AppCompatEditText
            android:id="@+id/emailField"
            android:layout_width="275dp"
            android:layout_height="wrap_content"
            android:paddingBottom="16dp"
            android:paddingTop="14dp"
            android:hint="@{hint123}"
            android:textCursorDrawable="@null"
            android:background="@drawable/edit_text_background"
            android:fontFamily="@font/eina_regular"
            android:textColor="@color/edit_text_color"
            android:textColorHint="@color/edit_text_color"
            android:textSize="15sp"
            />
    </android.support.design.widget.TextInputLayout>
</layout>

And I include it in another file:

<?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">
    <include
            layout="@layout/custom_edit_text"
            app:hint123="Email"/>
</layout>

However the project refuses to compile after a clean & rebuild with the error:

AAPT: error: attribute hint123 (aka inc.company.appname:hint123) not found.

Any ideas?

I also have

dataBinding {
    enabled = true
}

enabled in the app level build.gradle

5
  • 1
    At a 10 second glance I would say you Android Studio/Operating System is old, would I be right ? Commented Mar 12, 2019 at 3:57
  • 1
    Up to date, running 3.3.2 :( good idea tho Commented Mar 12, 2019 at 4:14
  • os is newest version of macos Commented Mar 12, 2019 at 4:14
  • 4
    Rather than app:hint123="Email", pass like this app:hint123="@{Email}" in include layout. Commented Mar 12, 2019 at 4:57
  • 1
    @JeelVankhede that did it, it compiles! However, now when I pass a raw string value, it does not populate in the included view. Commented Mar 12, 2019 at 5:11

6 Answers 6

57

I think I've hit upon the solution. To activate data binding, you need to use a @{} expression, and what's in the braces must be valid Java code. So a literal string must be enclosed in quotes... which must be encoded as &quot; inside an XML attribute value. Put it all together and you get:

<include
    layout="@layout/custom_edit_text"
    app:hint123="@{&quot;Email&quot;}"/>

Data binding does work for include files, it's just that the syntax for a literal is a bit convoluted. I had the same issue and this form is working in my project.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot. This is a very strange behavior. I hope it will be fixed soon.
...or at least a descriptive error message that explains this simple issue
Excellent explanation of what's going on here. Not sure I would have ever come up with this solution. It's unfortunate that there are no examples of this usage in the layout and bindings expressions docs: developer.android.com/topic/libraries/data-binding/expressions.
I regret to inform everyone that this issue still persist. But it seems that you can do something like app:hint123='@{"Email"}' instead if you don't want/need to use &quot;
8

Bind the variables using @{ }

activity_main.xml

</layout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".simple.MainActivity">

        <include layout="@layout/content_main_data_binding"
            bind:name="@{ "Hello World" }" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

content_view.xml

</layout>

    <data>
    <variable
        name="name"
        type="String" />
    </data>

    <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{ name }"/>

 </layout>

GL

3 Comments

bind:name isn't working for me, 'Namespace: 'bind' is not bound'
Add xmlns:bind="http://schemas.android.com/tools" in your parent layout
Your binding expression is not valid xml
3

There are 2 alternatives to the quote-escaping solution @big_m provides.

You can single-quote the entire expression and use double-quotes around the string:

<include
    layout="@layout/custom_edit_text"
    app:hint123='@{"Email"}'/>

Or you can use backticks around the string:

<include
    layout="@layout/custom_edit_text"
    app:hint123="@{`Email`}"/>

1 Comment

Much easier on the eyes, @Christopher! I can't believe I didn't think of using the single quotes, but thanks for that! Is there a minimum version of the tools or Java where the backticks work? I looked for information on that format, as I hadn't seen it before, and everything I found said that Java ended up not adopting the backticks, but it does seem to work with the Android SDK 34 toolset.
0

I am using Android 3.1.1. And the following code is working for me, and if you can use it you will be able to reuse "hint" as you desired. I have a slightly altered layout file (custom_edit_text.xml) as follows.

<?xml version="1.0" encoding="utf-8"?>

<data>
    <variable name="cName" type="String" />
    <variable name="user" type="your.package.name.User" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.email}" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.mobile}" />

    <android.support.design.widget.TextInputLayout
        android:id="@+id/emailInputLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <android.support.v7.widget.AppCompatEditText
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:hint="@{cName.toString()}"
            android:paddingBottom="16dp"
            android:paddingTop="14dp"
            android:textSize="15sp" />

    </android.support.design.widget.TextInputLayout>
</LinearLayout>

Above the second "type" is package name + User class name.

I create the "User" class in a separate file as follows.

public class User {
String email;
String mobile;

User(String email, String mobile) {
    this.email = email;
    this.mobile = mobile;
}


public String getEmail() {
    return email;
}

public String getMobile() {
    return mobile;
}
}

Inside MainActivity inside onCreate() I create the user object create the string and bind them.

String email = "xyz@yahoo";
    String mobile = "9999";
    User user = new User(email,mobile);
    CustomEditTextBinding binding = DataBindingUtil.setContentView(this,R.layout.custom_edit_text) ;
    binding.setCName("Yam May");
    binding.setUser(user);

And I enabled binding in the app level build.gradle as you did.

A very detailed description about data binding can be found in https://www.vogella.com/tutorials/AndroidDatabinding/article.html

1 Comment

don't forget to add the dataBinding element to your build.gradle file in the app module android { ... dataBinding { enabled = true } }
0

Just in case anyone misses one detail like me: you must enclose your parent layout content and the included layout content within "" and "". Without that binding is not used in a layout. I had the same issue when I had not enclosed my parent layout with these tags.

Comments

0

This error can also occur when <layout> tag is not placed upon the calling layout.
(the xml within which we're using the <include> tag and setting a binding attribute value as bind:myvariable or app:myvariable)

PS: Not the case presented in this issue, but just something to be wary of.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.