4

I have an EditText implements TextWatcher but have a problem with Backspace key. The first 5 characters are clear one by one when hold on backspace, but the last 5 characters that convert to image cannot clear one by one when hold on backspace.

Look the image :

enter image description here

  1. MainActivity.java

    public class MainActivity extends AppCompatActivity {
    Spannable.Factory spannableFactory;
    
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    spannableFactory = Spannable.Factory
            .getInstance();
    
    final EditText editText = (EditText) findViewById(R.id.editText);
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
    
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            editText.removeTextChangedListener(this);
            if (s.length() >= 5) {
                editText.setText(getTextToIcon(getApplicationContext(), s));
            }
            if(count!=0){                               // != key delete
                if (s.length() - 1 > start) {
                    editText.setSelection(start + 1);
                } else {
                    editText.setSelection(s.length());
                }
            }else{                                      // = key delete
                editText.setSelection(start);
            }
    
            editText.addTextChangedListener(this);
        }
    
        @Override
        public void afterTextChanged(Editable s) {}
    });
    }
    
    
    public Spannable getTextToIcon(Context context, CharSequence text) {
    StringBuilder stringBuilder = new StringBuilder(text);
    Spannable spannable = spannableFactory.newSpannable(stringBuilder);
    int index = text.length() - 1;
    for(int i = 5; i<=index; i++){
        spannable.setSpan(new ImageSpan(context, android.R.drawable.star_on),
                i, i + 1,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    return spannable;
    }
    }
    
  2. activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:maxLength="10"
        android:inputType="number" />
    </LinearLayout>
    
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
Holi Boom
  • 1,346
  • 1
  • 12
  • 29
  • As you are converting text to icon therefor you are not able to clear it on back space, so you need to check and convert it back from icon to text on back space to clear it. – Vickyexpert Jun 16 '16 at 04:28
  • @Vickyexpert : I can clear it by press on backspace one by one and clear text one by one, but when i hold on backspace the text doesn't clear one by one. – Holi Boom Jun 16 '16 at 04:34
  • I think it's not because of convert it to icon, cause i use another method that i didn't convert it to icon, it doesn't work too. – Holi Boom Jun 16 '16 at 04:36
  • Then I think you need to handle long press on backspace key, first do one thing hold on another key like "1" or "2" and check if it is working properly then check same for backspace – Vickyexpert Jun 16 '16 at 04:49
  • @ JohnWatsonDev : yest thank you. but `getTextToIcon` is at the bottom, you can't see it? – Holi Boom Jun 17 '16 at 01:16

2 Answers2

5

Bro, the codes with bug is below:

if (s.length() >= 5) {
    editText.setText(getTextToIcon(getApplicationContext(), s));
}

You should change it to this:

if (count != 0 && s.length() >= 5) {
    // just set the text to the icon in input state instead of pressing delete key in soft method
    editText.setText(getTextToIcon(getApplicationContext(), s));
}

Hope it help.

JohnWatsonDev
  • 1,227
  • 9
  • 16
1

Now I found a solution from this link https://stackoverflow.com/a/10954719/5887320 Hope it will help other.

editText.addTextChangedListener( new TextWatcher() {
        boolean isEdiging;
        @Override public void onTextChanged(CharSequence s, int start, int before, int count) { }
        @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

        @Override public void afterTextChanged(Editable s) {
            if(isEdiging) return;
            isEdiging = true;

            String str = s.toString().replaceAll("[^\\d]", "");
            double s1 = 0;
            try {
                s1 = Double.parseDouble(str);
            }catch (NumberFormatException e){
                e.printStackTrace();
            }


            NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH);
            ((DecimalFormat)nf2).applyPattern("###,###.###");
            s.replace(0, s.length(), nf2.format(s1));

            isEdiging = false;
        }
    });
}
Community
  • 1
  • 1
Holi Boom
  • 1,346
  • 1
  • 12
  • 29