Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass data to <include> layout using Databinding

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>
like image 455
MST Avatar asked May 17 '26 12:05

MST


1 Answers

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.

like image 125
iCantC Avatar answered May 19 '26 02:05

iCantC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!