"DataBinding" How to check if editText isEmpty and setError from onClick of the button in xml

853 Views Asked by At

I am trying to implement lesson ViewModel and data binding, in the below xml, I want to use TextUtils.isEmpty() method to check if editText is empty then set error, while I searching for this I found this question I added importing TextUtils in the tag, but I still cannot call editText "name_text" from button onClick to check it and setError

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

    <data>

        <import type="android.text.TextUtils"/>
        <import type="android.widget.EditText"/>
        <variable
            name="viewModel"
            type="com.anushka.roomdemo.SubscriberViewModel" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="15dp"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <EditText
            android:id="@+id/name_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:layout_marginBottom="5dp"
            android:ems="10"
            android:hint="Subscriber's name"
            android:inputType="textPersonName"
            android:text="@={viewModel.inputName}"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/email_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:ems="10"
            android:hint="Subscriber's email"
            android:inputType="textEmailAddress"
            android:text="@={viewModel.inputEmail}"
            android:textStyle="bold" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/save_or_update_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="@{
                 ()->
               TextUtils.isEmpty(name_text.getText().toString())
                   ? name_text.setError("cannot be empty") 
                }"
                android:text="@={viewModel.saveOrUpdateButtonText}"
                android:textSize="18sp"
                android:textStyle="bold" />

            <Button
                android:id="@+id/clear_all_or_delete_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="@{()->viewModel.clearAll()}"
                android:text="@={viewModel.clearAllOrDeleteButtonText}"
                android:textSize="18sp"
                android:textStyle="bold" />


        </LinearLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/subscriber_recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
    </LinearLayout>
</layout>

Edit:

I edited the onClick attr like this, and there's no errors in xml butI cannot pass the message to setError("Cannot be empty") method

android:onClick="@{
                (nameText)-> TextUtils.isEmpty(nameText.text.toString())
                ? nameText.setError() : viewModel.saveOrUpdate()}"
2

There are 2 best solutions below

0
Maksim Raha On

Create observablefield in view model for your edit text. You can pass parameter to it from xml.

 android:onTextChanged="@{viewModel.editTextContent}

On click just check if it is empty. https://developer.android.com/reference/android/databinding/ObservableField

2
dominicoder On

I would strongly advise you avoid putting logic in your XML. This should go in the view model where you can test it.

So the xml just binds to a function on the view model:

android:onClick="@{viewModel.saveOrUpdate()}"

And the error state on the name field:

    <EditText
        android:id="@+id/name_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:layout_marginBottom="5dp"
        android:ems="10"
        android:error="@{viewModel.inputNameError}" // <-----
        android:hint="Subscriber's name"
        android:inputType="textPersonName"
        android:text="@={viewModel.inputName}"
        android:textStyle="bold" />

Then your view model handles logic:

fun saveOrUpdate {
    // Updating this field will set the value on the bound text field
    inputNameError = if (inputName.isNullOrEmpty()} "cannot be empty" else null
    // Do other stuff to save or update
}