9

I've been searching this a lot today and only found some unclear answers regarding this question.

I'm having multiple TextView and EditText in a form, all of them being customised by my theme and i'd like to reuse the same included layout each time, but having parameters to it like the text inside the TextView or hint inside the EditText.

My form.xml right now:

<LinearLayout android: orientation="horizontal">
     <TextView android:text="Username"/>
     <EditText android:id="edittext_username"
               android:hint="Enter username..."
               android:inputType="text"/>
</LinearLayout>

<LinearLayout android: orientation="horizontal">
     <TextView android:text="Password"/>
     <EditText android:id="edittext_password"
               android:hint="Enter password..."
               android:inputType="password"/>
</LinearLayout>

... other fields ...

What i'd like in the main form.xml:

<LinearLayout android:orientation="vertical" ...>
     <include layout="form_edittext" 
            app:textview_text="@{`Username`}"
            app:edittext_hint="@{`Enter username...`}"
            ... other parameters ...
 />
     <include layout="form_edittext"
            app:textview_text="@{`Password`}"
            app:edittext_hint="@{`Enter password...`}"
            ... other parameters ...
 />
</LinearLayout>

also the form_edittext.xml:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable name="textview_text" type="java.lang.String"/>
        <variable name="edittext_id" type="java.lang.String"/>
        <variable name="edittext_inputType" type="java.lang.String"/>
        <variable name="edittext_hint" type="java.lang.String"/>
    </data>

    <TextView android:text="@{textview_text}"/>
    <EditText android:id="@{edittext_id}"
                   android:hint="@{edittext_hint}"
                   android:inputType="@{edittext_inputType}"/>
</layout>

I'm still a beginner and i do not know if this is possible. On this post, the guy replied he used data binding (as in example shown by me) How to Re-using Layouts with <include/> with parameters? (you may see the first answer).

However, using this method give me the error of XML not recognizing identifiers like "textview_text" (the variables that i'm accessing via @{...}. If you got other solutions i'd appreciate if you share them. Cheers!

UPDATE on iCantC's answer: (but the textview's text and the hint remain empty). Main layout:

<?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"
    xmlns:tools="http://schemas.android.com/tools">

 ...
            <include layout="@layout/activity_login_layout_input"
                android:id="@+id/activity_login_layout_input_emailAddress"
                app:textviewt="@{@string/email}"     //the string is "Email Address"
                app:edittexth="@{@string/emailhint}" />     //the string is "Your email address..."

 ...
</layout>

Included layout:

<layout>

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

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:showDividers="middle">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{textviewt}"
            android:textColor="@color/c1"
            android:textSize="12sp"/>

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingEnd="26dp">

            <androidx.appcompat.widget.AppCompatEditText
                android:id="@+id/edittext"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center|start"
                android:layout_marginStart="26dp"
                android:background="@drawable/activity_login_background"
                android:hint="@{edittexth}"
                android:padding="6dp"
                android:textAlignment="center"
                android:textColor="@color/c2"
                android:textColorHint="@color/grey"
                android:textSize="14sp"/>

            <androidx.appcompat.widget.AppCompatImageView
                android:layout_width="36dp"
                android:layout_height="36dp"
                android:layout_gravity="start"
                android:adjustViewBounds="true"
                android:src="@drawable/activity_login_edittext_drawable" />

        </FrameLayout>

    </LinearLayout>

</layout>
1
  • how it would work for imageview in included layout? Commented May 24, 2022 at 13:15

1 Answer 1

14

It seems like you want to include a common layout and then pass dynamic parameters from the main layout to included layout, here are the steps,

Step 1: Enable DataBinding in your project

//In the build.gradle file in the app module, add this 

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

Step 2: Create your common_layout_included.xml

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

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

<LinearLayout
        ..
        >

<TextView
    android:id="@+id/tv_username"
    android:text="@{username}"/> 

   </LinearLayout>

</layout>

Step 3: Include common_layout_included.xml in your main_layout.xml

<?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">

    <LinearLayout
        ..
        >

        <include
            android:id="@+id/includedLayout"
            layout="@layout/common_layout_included"
            app:username="@{@string/username}" // here we pass any String 
            />

    </LinearLayout>
</layout>

Step 4: Make sure you inflate the layout using DataBinding way

//In the onCreate of your Activity

val binding = DataBindingUtil.setContentView(this,R.layout.main_layout)

That's it, you are good to go. If still some error appears just do File -> Invalidate Caches/Restart

One last thing, I saw that you are assigning the id's to the view's dynamically android:id="@{edittext_id}", in all of my experience, I never really encountered a use case where I would be motivated to do this. I don't even know if it's possible and even if possible I doubt it's a good practice.

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

5 Comments

Hi, i've been following every step. I'm not receving any compile errors, but even if i pass the username string "johnny" for example in include, "johnny" won't appear in the included layout's textview's text at runtime, the text remains empty. Why so?
Can you add both updated layouts? I'll have a look at it.
Please look on the main question. I've put my updated code that doesn't yet work in the end. I'm trying to set the textview's text to "Email Address" and the edittext's hint to "Your email addres...", both strings in my string.xml. However, both fields remain empty at runtime.
Let's continue our chat in this room chat.stackoverflow.com/rooms/214066/databinding-issue
Thank you, i forget to use: val binding = DataBindingUtil.setContentView(this,R.layout.main_layout)

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.