Skip to content Skip to sidebar Skip to footer

Android - Edittext Length Filter Not Working As It Should

First I have to say I have read similar questions and answers here on SO and this question is basically a duplicate of this question and many others but the answers given to those

Solution 1:

I ended up using a TextWatcher instead. I'm not sure if it is the best way to do this but it does work with suggestions and it doesn't turn off gesture typing or change the font style. Here's how I did it (I'm quite new to android so if this needs improvement feel free to let me know).

I added an example in the comments to clarify what is going on.

Make these global variables:

privateboolean mWatcherIsBlocked = false;
privateString mBeforeChange;
privateString mFilteredString; 
privateint mCursorPosition = 0;

Then create the TextWatcher and add it to your EditText

finalintmaxLength=10; // desired length limit/** 
 * lets say our EditText is showing "abcdefgh". We select "cdef" from it and 
 * paste a new text "ijklmnop" in the middle. What we should get according to
 * our maxLength is this: 
 * (1) "ab" (0th up to the letter from before_change_text we were selecting) + 
 * (2) "ijklmn" (part of the text we pasted minus the number of letters the whole 
 *      after_change_text goes over the 10 letter limit) + 
 * (3) "gh" (last part of before_change_text that wasn't selected)
 * 
 * so the new text has to be "abijkmngh"
 */TextWatchertextWatcher=newTextWatcher() {
    @OverridepublicvoidbeforeTextChanged(CharSequence s, int start, int count, int after) {
        // get before_change_text if textWatcher isn't blockedif (!mWatcherIsBlocked) mBeforeChange = s.toString();
    }
    @OverridepublicvoidonTextChanged(CharSequence s, int start, int before, int count) {
        if (!mWatcherIsBlocked){
            // get after_change_text if textWatcher isn't blockedStringafter= s.toString();
            // if after_change_text's length is bigger than the limit if (after.length() > maxLength) {
                // see how much it goes over the limitintover= after.length() - maxLength;
                // add parts (1) and (2) like our example aboveStringst= mBeforeChange.substring(0, start) + // (1)
                            after.substring(start, start + count - over); // (2)// get where the cursor position should be after pasting (// = after the last letter we could paste = length of (1) + (2) )
                mCursorPosition = st.length();
                // now add part (3) of our text to the first two
                st += mBeforeChange.substring(
                          mBeforeChange.length() - (maxLength - st.length()), 
                          mBeforeChange.length());
                // now assign this new text to a global variable
                mFilteredString = st;
            } else { 
                // if after_change_text hasn't gone over the limit assign it // directly to our global variable
                mFilteredString = s.toString();
            }
        }
    }
    @OverridepublicvoidafterTextChanged(Editable s) {
        // if filtered text is not the same as unfiltered text // or textWatcher is not blockedif (!mFilteredString.equals(s.toString()) && !mWatcherIsBlocked) {
            // block textWatcher to avoid infinite loops created by setText // (this might not work as I well as I think!)
            mWatcherIsBlocked = true;
            // set new text to our EditText
            editText.setText(mFilteredString);
            // set its cursor position 
            editText.setSelection(mCursorPosition);
            // unblock the textWatcher
            mWatcherIsBlocked = false;
        }
    }
};

// add the TextWatcher to our EditText
editText.addTextChangedListener(textWatcher);

Post a Comment for "Android - Edittext Length Filter Not Working As It Should"