Unable to display that the maximum characters exceeded

1.4k views Asked by At

I am developing an Android application in which I would like to set Input filter to allow only 21 characters in the EditText.

The XML code snippet I have used is follows

                             <EditText
                                android:id="@+id/screen_name"
                                android:layout_width="300dp"
                                android:layout_height="match_parent"
                                android:background="#00000000"
                                android:enabled="false"
                                android:gravity="center"
                                android:hint="Enter your screen name"
                                android:maxLength="21"
                                android:text="Raghunathan KE"
                                android:textColor="#fff"
                                android:textSize="24sp"
                                android:textStyle="bold"
                                android:inputType="text"
                                android:isScrollContainer="true"
                                android:focusable="true"/>

And,In Activity,

   InputFilter lengthFilter = new InputFilter.LengthFilter(21) {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (dest.length() > getMax()) {
                Toast.makeText(Profile.this, "Screen name should not exceed more than 21 characters", Toast.LENGTH_LONG).show();
            }

            return super.filter(source, start, end, dest, dstart, dend);
        }

        @Override
        public int getMax() {
            return super.getMax();
        }
    };

screenname.setInputFilters(new InputFilter[]{lengthFilter});

It does not allow to enter more than 21 characters but I am unable to intimate the user that the length must not exceed more than 21 characters because the Toast message inside filter callback is not displayed.

I have tried using TextWatcher but it is not getting invoked after 21st character as I have set the limit to 21 using InputFilter.

Anyone, Please help me find the solution.

2

There are 2 answers

3
Rahul Singh Chandrabhan On

Try this code, also keep the max length of your edittext to 21 in xml

yourEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if(count >= 21){
                    Toast.makeText(context, "Your Alert", 
              Toast.LENGTH_SHORT).show();
                }
            }

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


            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
0
Rakesh L On

Thanks for all of your responses. I have finally found the workaround with the help of ADM's Comment.

Just changed dest.length() > getMax() to dest.length() == getMax()

After the above modification, the toast was still displayed when I cleared a character using backspace.

After few analysis , I came to know that source returns the character the user keyed in and dest returns the characters being displayed in the EditText. As InputFilter is invoked before TextWatcher, the dest returns the same length when the user selecting backspace.

It is resolved by adding another validation to check if the length of the source is greater than the length of destination

dest.length() == getMax() && dest.toString().length() < source.toString().length()

Finally, the code snippet becomes

InputFilter lengthFilter = new InputFilter.LengthFilter(21) {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
           if (dest.length() == getMax() && dest.toString().length() < source.toString().length()) {
                Toast.makeText(Profile.this, "Screen name should not exceed more than 21 characters", Toast.LENGTH_SHORT).show();
            }
            return super.filter(source, start, end, dest, dstart, dend);
        }

        @Override
        public int getMax() {
            return super.getMax();
        }
    };

Update : There was a strange behavior when the numbers in the dest is high Ex:testname123456testname. The source is sometimes returning only the character I have keyed-in when it has zero or lesser length of numbers in it.otherwise, it returns full characters along with the one I have just keyed-in.

dest.toString().length() < source.toString().length() returns false in the second case.

So, the code is updated as

 private InputFilter.LengthFilter lengthFilter = new InputFilter.LengthFilter(maxLengthOfScreenName) {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            String numbers = dest.toString().replaceAll("[^0-9]", "");
            if (dest.toString().length() == maxLengthOfScreenName && ((dest.toString().length() < source.toString().length())
                    || (source.toString().length() == 1 && numbers.length() > 1))) {
                Toast.makeText(Profile.this,
                        "Screen name should not exceed more than " + maxLengthOfScreenName + " characters",
                        Toast.LENGTH_SHORT).show();

            }
            return super.filter(source, start, end, dest, dstart, dend);
        }
    };

Hope this will help someone else.