mufazmi
mufazmi

Reputation: 1210

Remove addTextChangedListener() When the EditText values changed programmatically not manually

I was working on a website where I was changing the text on change of the text using Javascript.

  1. When user change the quantity I am changing the total price & sale price value.
  2. When user change the sale price I am changing the discount value.
  3. When user change the discount I am changing the sale price value.

enter image description here

Now same thing I want in my android application.

I have added Text Change Event Listener on every EditText.

Like

For Quantity EditText

    holder.inputSaleQuantity.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });

For Discount EditText.

holder.inputSaleDiscount.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
                Log.d("SocialCodia", "afterTextChanged: inputSaleDiscount Event Listener Called");
                int input = 0;
                if (editable.toString().trim().length() > 0) {
                    input = Integer.parseInt(editable.toString().trim());
                }
                    discountInputEvent(holder, input);
            }
        });

For Sale Price EditText.

holder.inputSalePrice.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                priceEvent(holder);
                Log.d("SocialCodia", "afterTextChanged: inputSalePrice Event Listener Called");
            }
        });

POSSIBILITIES WHY EXECUTING METHOD AGAIN AND AGAIN.

When I am changing the any EditText's value like, Changing the Quantities EditText's value, Its calling sale price edit text change listener as well.

Because on change of Quantity value I am changing the sell price value. So when the sell price value change there text change listener executing.

0

Methods which I am calling.

private void priceEvent(ViewHolder holder) {
        int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
        int sellPrice = Integer.parseInt(holder.inputSalePrice.getText().toString().trim());
        int discount = percentage(sellPrice, totalPrice);
        holder.inputSaleDiscount.setText(String.valueOf(discount));
    }

    private void discountInputEvent(ViewHolder holder, int input) {
        int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
        int price = percentageDec(totalPrice, input);
        holder.inputSalePrice.setText(String.valueOf(price));
    }

    private int percentage(int partialValue, int totalValue) {
        Double partial = (double) partialValue;
        Double total = (double) totalValue;
        Double per = (100 * partial) / total;
        Double p = 100 - per;
        return p.intValue();
    }

    private int percentageDec(int totalValue, int per) {
        if (per == 0 || String.valueOf(per).length() < 0)
            return totalValue;
        else {
            Double total = (double) totalValue;
            Double perc = (double) per;
            Double price = (total - ((perc / 100) * total));
            Integer p = price.intValue();
            return p;
        }
    }

CLEAR QUESTION IN SHORT :

I only want to use addTextChangeEventListener() When the value of EditText Change Manually. But when I am changing the value using script I don't want to use the addTextChangeEventListner().

How can I achieve this. or how can I solve this problem.

-Thanks

Upvotes: 0

Views: 584

Answers (2)

MajedEddin
MajedEddin

Reputation: 71

you can try this work around solution , first thing you should define a text watcher for every edit text like this :

private TextWatcher quantityWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    };

then add it to its edit text like this :

holder.inputSaleQuantity.addTextChangedListener(quantityWatcher);

so when you set text programmatically just remove the watcher from edit text and after set text you can set it again like this :

private void priceEvent(ViewHolder holder) {
        holder.inputSaleQuantity.removeTextChangedListener(quantityWatcher);

        int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
        int sellPrice = Integer.parseInt(holder.inputSalePrice.getText().toString().trim());
        int discount = percentage(sellPrice, totalPrice);
        holder.inputSaleDiscount.setText(String.valueOf(discount));

        holder.inputSaleQuantity.addTextChangedListener(quantityWatcher);

    }

Upvotes: 1

Zain
Zain

Reputation: 40830

Short Answer:

The TextWatcher's need to be defined non-anonymously (i.e. with variables), so that you can register them with addTextChangedListener(myWatcher) and whenever you want to cease them, you can un-register them with removeTextChangedListener(myWatcher) and then re-register them back again with addTextChangedListener(myWatcher) when you're done with script modification.

Long Answer

Building initial TextWatcher variables & register them to EditTexts

// Build variables for text watchers

TextWatcher quantityWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }
};

TextWatcher salePriceWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }
};

TextWatcher discountWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }
};

Initially register all the text watchers.

registerTextWatchers();

private void registerTextWatchers() {
    holder.inputSaleQuantity.addTextChangedListener(quantityWatcher);
    holder.inputSalePrice.addTextChangedListener(salePriceWatcher);
    holder.inputSaleDiscount.addTextChangedListener(discountWatcher);   
}

Unregister the watchers whenever you change the EditText programmatically and register them again when you're done

private void unregisterTextWatchers() {
    holder.inputSaleQuantity.removeTextChangedListener(quantityWatcher);
    holder.inputSalePrice.removeTextChangedListener(salePriceWatcher);
    holder.inputSaleDiscount.removeTextChangedListener(discountWatcher);    
}

private void priceEvent(ViewHolder holder) {
    //...
    
    unregisterTextWatchers();
    holder.inputSaleDiscount.setText(String.valueOf(discount));
    registerTextWatchers();
}

private void discountInputEvent(ViewHolder holder, int input) {
    //...
    
    unregisterTextWatchers();
    holder.inputSalePrice.setText(String.valueOf(price));
    registerTextWatchers();
}

Repeat the same whenever you change the EditText values programmatically

Upvotes: 1

Related Questions