How to use Text Watcher to get values from a List View with multiple Edit Texts
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.
- 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)
In this tutorial we’re going to create following files
- my_fragment_ui.xml
- MyFragment.java
- my_fragment_adapter_ui.xml
- MyFragmentAdapter.java
3. Let’s Start
Step1: create the my_fragment.xml (UI for the main Fragment):
Step2: create MyFragment.java class
- * 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)
- * make sure you set correct input type attribute value for your
EditText
!!! I have used input type -number
for the Received QtyEditText
(Quantity should be a positive integer value ) andnumberDecimal
for the Unit CostEditText
element (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"
...
/>
Step4: Create MyFragmentAdapter.java class
- * That’s It ! You have created a List View with two
EditText
in every List Item. Now you have addedaddTextChangedListener()
for eachEditText
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 !!!