Android attach TextWatcher to multiple EditText Views

TextWatcher is an type of object that if attached to an EditText will call its methods when the text changes. The following methods are available for a TextWatcher
  • afterTextChanged(Editable s)
    • This method is called to notify you that, somewhere within s, the text has been changed.
  • beforeTextChanged(CharSequence s, int start, int count, int after)
    • This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after.
  • onTextChanged(CharSequence s, int start, int before, int count)
    • This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had length before.
In this example we create a ListView with each row having an EditText for a quantity input simulating an order entry application. The quantity input field in each row is then attached to the TextWatcher so that we can listen for changes. As the quantity changes so does the extended price and the shopping cart Total.
Android attach TextWatcher to multiple EditText Views
Android TextWatcher shopping cart application

Android Manifest

<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.as400samplecode"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Application Main Layout - activity_main.xml

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
 android:layout_height="match_parent">

 <TextView android:id="@+id/cartTotal" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:layout_alignParentRight="true"
  android:layout_alignParentTop="true" android:text="$ 0.00"
  android:textAppearance="?android:attr/textAppearanceMedium"
  android:textStyle="bold" />

 <TextView android:id="@+id/textView2" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:layout_alignParentTop="true"
  android:layout_toLeftOf="@+id/cartTotal" android:text="Shopping Cart Total: "
  android:textAppearance="?android:attr/textAppearanceMedium" />

 <ListView android:id="@+id/listView1" android:layout_width="match_parent"
  android:layout_height="wrap_content" android:layout_alignParentLeft="true"
  android:layout_below="@+id/textView2" android:layout_marginLeft="5dp"
  android:layout_marginTop="10dp" />

</RelativeLayout>

ListView Row Layout - my_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent" android:layout_height="wrap_content"
 android:orientation="vertical" android:padding="6dip">

 <EditText android:id="@+id/quantity" android:layout_width="50sp"
  android:layout_height="wrap_content" android:layout_alignParentLeft="true"
  android:layout_alignParentTop="true" android:ems="10" />

 <TextView android:id="@+id/itemNumber" android:layout_width="100sp"
  android:layout_height="wrap_content" android:layout_alignTop="@+id/quantity"
  android:layout_marginLeft="5dp" android:layout_toRightOf="@+id/quantity"
  android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" />

 <TextView android:id="@+id/price" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:layout_alignBaseline="@+id/itemNumber"
  android:layout_alignBottom="@+id/itemNumber" android:layout_toRightOf="@+id/itemNumber"
  android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" />

 <TextView android:id="@+id/ext" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:layout_alignParentRight="true"
  android:layout_alignParentTop="true" android:text="Medium Text"
  android:textAppearance="?android:attr/textAppearanceMedium" />

 <TextView android:id="@+id/description" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:layout_alignLeft="@+id/itemNumber"
  android:layout_alignParentBottom="false" android:layout_below="@+id/itemNumber"
  android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

Shopping Cart POJO - Product.java

package com.as400samplecode;

public class Product {
 
 private String itemNumber = "";
 private String description = "";
 private Double price = 0.00;
 private int quantity = 0;
 private Double ext = 0.00;
 
 public Product(String itemNumber, String description, Double price) {
  super();
  this.itemNumber = itemNumber;
  this.description = description;
  this.price = price;
 }
 
 public String getItemNumber() {
  return itemNumber;
 }
 public void setItemNumber(String itemNumber) {
  this.itemNumber = itemNumber;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public Double getPrice() {
  return price;
 }
 public void setPrice(Double price) {
  this.price = price;
 }
 public int getQuantity() {
  return quantity;
 }
 public void setQuantity(int quantity) {
  this.quantity = quantity;
 }
 public Double getExt() {
  return ext;
 }
 public void setExt(Double ext) {
  this.ext = ext;
 }
 
}

Application Main Activity - MainActivity.java

package com.as400samplecode;

import java.text.DecimalFormat;
import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

 private MyCustomAdapter dataAdapter = null;
 private Double orderTotal = 0.00;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //Generate list View from ArrayList
        displayListView();
  
    }
    
    private void displayListView() {

  //Array list of products
  ArrayList<Product> productList = new ArrayList<Product>();
  Product product = new Product("A001","Small Chair",10.00);
  productList.add(product);
  product = new Product("A002","Medium Chair",12.00);
  productList.add(product);
  product = new Product("A003","Large Chair",15.00);
  productList.add(product);
  product = new Product("B001","Small Table",50.00);
  productList.add(product);
  product = new Product("B002","Medium Table",60.00);
  productList.add(product);
  product = new Product("B003","Large Table",70.00);
  productList.add(product);
  

  //create an ArrayAdaptar from the String Array
  dataAdapter = new MyCustomAdapter(this,R.layout.my_row, productList);
  ListView listView = (ListView) findViewById(R.id.listView1);
  // Assign adapter to ListView
  listView.setAdapter(dataAdapter);

 }
    
    private class MyCustomAdapter extends ArrayAdapter<Product> {

  private ArrayList<Product> productList;
  
  public MyCustomAdapter(Context context, int textViewResourceId, 
    ArrayList<Product> productList) {
   super(context, textViewResourceId, productList);
   this.productList = new ArrayList<Product>();
   this.productList.addAll(productList);
  }

  @Override
  public View getView(int position, View view, ViewGroup parent) {

   DecimalFormat df = new DecimalFormat("0.00##");
   Product product = productList.get(position);
   
   if (view == null) {
    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = vi.inflate(R.layout.my_row, null);
    EditText quantity = (EditText) view.findViewById(R.id.quantity);
    //attach the TextWatcher listener to the EditText
    quantity.addTextChangedListener(new MyTextWatcher(view));
    if(position % 2 == 0){
     view.setBackgroundColor(Color.rgb(238, 233, 233));
    }
   }
  
   EditText quantity = (EditText) view.findViewById(R.id.quantity);
   quantity.setTag(product);
   if(product.getQuantity() != 0){
    quantity.setText(String.valueOf(product.getQuantity()));
   }
   else {
    quantity.setText("");
   }
   
   TextView itemNumber = (TextView) view.findViewById(R.id.itemNumber);
   itemNumber.setText(product.getItemNumber());
   TextView description = (TextView) view.findViewById(R.id.description);
   description.setText(product.getDescription());
   TextView price = (TextView) view.findViewById(R.id.price);
   price.setText("$" + df.format(product.getPrice()));
   TextView ext = (TextView) view.findViewById(R.id.ext);
   if(product.getQuantity() != 0){
    ext.setText("$" + df.format(product.getExt()));
   }
   else {
    ext.setText("");
   }

   return view;

  }

 }
    
    private class MyTextWatcher implements TextWatcher{

  private View view;
  private MyTextWatcher(View view) {
   this.view = view;
  }

  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
   //do nothing
  }
  public void onTextChanged(CharSequence s, int start, int before, int count) { 
   //do nothing
  }
  public void afterTextChanged(Editable s) {
   
   DecimalFormat df = new DecimalFormat("0.00##");
   String qtyString = s.toString().trim();
   int quantity = qtyString.equals("") ? 0:Integer.valueOf(qtyString);
   
   EditText qtyView = (EditText) view.findViewById(R.id.quantity);
   Product product = (Product) qtyView.getTag();
   
   if(product.getQuantity() != quantity){

    Double currPrice = product.getExt();
    Double extPrice = quantity * product.getPrice();
    Double priceDiff = Double.valueOf(df.format(extPrice - currPrice));

    product.setQuantity(quantity);
    product.setExt(extPrice);
    
    TextView ext = (TextView) view.findViewById(R.id.ext);
    if(product.getQuantity() != 0){
     ext.setText("$" + df.format(product.getExt()));
    }
    else {
     ext.setText("");
    }
    
    if(product.getQuantity() != 0){
     qtyView.setText(String.valueOf(product.getQuantity()));
    }
    else {
     qtyView.setText("");
    }
    
    orderTotal += priceDiff;
    TextView cartTotal = (TextView) findViewById(R.id.cartTotal);
    cartTotal.setText(df.format(orderTotal));
   
   }
   
   return;
  }
 }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

References

No comments:

Post a Comment

NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.