Android TextWatcher for multiple editText in a list item???

How to use Text Watcher to get values from a List View with multiple Edit Texts

Nuwan Wickramasinghe
4 min readFeb 8, 2019

--

Hello,

I have tired many methods that I could find on internet to implement a fragment with a list view that has more than one editText field in a single list item and I needed to get the changed values of each editText separately. Wasting many hours and combining various solutions that I could find on Internet, finally learned how to do it.

  1. Understanding Basics

android.text.TextWatcher is used to keep track/watch on a EditText and to trigger when the user change the current value in the EditText. It allows us to track each character when value of the EditText is changed.

By using a TextWatcher you can keep an eye on user inputs and you don’t need to wait for a another user input like a button click to gather the changed values.

How to Implement the TextWatcher

Nothing fancy ! Just call the method addTextChangedListener() and pass the reference to TextWatcher instance. Then you can override the methods in TextWatcher class and make them do what ever you want when the value change on the EditText.

@Overridepublic void afterTextChanged(Editable editable) {}

This method is called when the text has been changed, because any changes you make will cause this method to call it self recursively. You have to be careful when using this method otherwise it could lead your program into a infinite loop !!!

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }

These two methods are not used in the following scenario because I wanted to get the value when the edit is finished by the user and move on to next EditText.

2. Get Into Action !

When you complete this tutorial your final output should look like this.. (But we’re going to focus on ‘Unit Cost’ & ‘Received Qty’ EditText Values in the list view)

Fraction of the Fragment UI with list view header & the ListView

In this tutorial we’re going to create following files

  1. my_fragment_ui.xml
  2. MyFragment.java
  3. my_fragment_adapter_ui.xml
  4. MyFragmentAdapter.java

3. Let’s Start

Step1: create the my_fragment.xml (UI for the main Fragment):

my_fragment_ui.xml
Android Design View of the Fragment UI

Step2: create MyFragment.java class

MyFragment.java
  • * I have used ButterKnife - an amazing tool for view binding. You can ignore ButterKnife and use the same old way to bind your UI elements into the fragment if you want. Just like this:
myTextView = (EditText) findViewById( R.id.my_edit_text_view_id );

Step3: create my_fragment_adapter_ui.xml (UI for the single list item)

my_fragment_adapter_ui.xml
  • * make sure you set correct input type attribute value for your EditText !!! I have used input type - number for the Received Qty EditText(Quantity should be a positive integer value ) and numberDecimal for the Unit Cost EditTextelement (Unit Cost should be a double value).
<EditText
android:id="@+id/po_listItem_heading_lbl7"
style="@style/product_main_ui_edittext"
android:inputType="number"
...
/>
<EditText
android:id="@+id/listItem_heading_lbl5"
style="@style/product_main_ui_edittext"
.....
android:inputType="numberDecimal"
...
/>
When you are trying to change the Received Qty Value of a list item it will allow Positive integer values only.

Step4: Create MyFragmentAdapter.java class

MyFragmentAdapter.java
  • * That’s It ! You have created a List View with two EditText in every List Item. Now you have added addTextChangedListener()for each EditText separately and instantiated. So you can use the override methods to behave as your requirement.

4. Summary

OK Let’s take a look at the important parts in this tutorial. Magic happens in MyFragmentAdapter.java class.

view.receivedQtyValue.addTextChangedListener(new TextWatcher() {

.....
@Override
public void afterTextChanged(Editable editable) {
String receiveQtyStr = editable.toString();
if (receiveQtyStr.equals(null) || receiveQtyStr.equals("")) {
receiveQtyStr = "0";
}
int receiveQty = Integer.parseInt(receiveQtyStr);
int displayReceivedQty = item.getOrderQty() - item.getDeleveryQty();
if (receiveQty < displayReceivedQty) {
item.setReceiveQty(receiveQty);
} else {
item.setReceiveQty(displayReceivedQty);
}

}
});

As you can see I have created a new instance of textWatcher for each EditText element, and addTextChangedListener() will listen until some change happens to the view that bind with the listener, then it will get the Editable value and pass it to the afterTextChanged(Editable editable) method. After that the value will be saved into the list item object. When we’re refreshing the listView it will automatically set the previously edited value as the current value for the property of the particular list item. So EditText will show user entered value as the default value in the editText.

So that’s it. If you have any questions, ask me !!!

--

--