Sometimes requirement comes in a way when one needs to restrict characters to be entered in Edit Text. Scenario can be “username should be greater than 6 characters”, “accepts only decimal number with 2 digits after fraction”, etc.

In this regard, EditText’ setFilters works at its best. EditText’s setFilters method can be used while playing with length of characters to be entered or entering data in particular pattern in EditText. To freeze such requirement with quickest solution, I have written Custom EditText Locker. One can use this class file along with two lines of code in Main activity to suffice the purpose. If needed more patterns of accepting data in EditText can be added to same class file to make it more generic. For example to make custom locker I have added two EditTexts one which accepts any character with limit of 4 and another EditText which accepts decimal number with only two digits after fraction.

Code for EditTextLocker.java

package com . edittextlocker ; import android . text . Editable ; import android . text . InputFilter ; import android . text . Spanned ; import android . text . TextWatcher ; import android . view . KeyEvent ; import android . view . View ; import android . view . View . OnKeyListener ; import android . widget . EditText ; public class EditTextLocker { private EditText editText ; private int charactersLimit ; private int fractionLimit ; public EditTextLocker ( EditText editText ) { this . editText = editText ; editText . setOnKeyListener ( editTextOnKeyListener ) ; } private OnKeyListener editTextOnKeyListener = new OnKeyListener ( ) { @ Override public boolean onKey ( View v , int keyCode , KeyEvent event ) { if ( keyCode = = KeyEvent . KEYCODE_DEL ) { startStopEditing ( false ) ; } return false ; } } ; private TextWatcher editTextWatcherForCharacterLimits = new TextWatcher ( ) { @ Override public void onTextChanged ( CharSequence s , int start , int before , int count ) { if ( ! editText . getText ( ) . toString ( ) . equalsIgnoreCase ( "" ) ) { int editTextLength = editText . getText ( ) . toString ( ) . trim ( ) . length ( ) ; if ( editTextLength > = charactersLimit ) { startStopEditing ( true ) ; } } } @ Override public void beforeTextChanged ( CharSequence s , int start , int count , int after ) { } @ Override public void afterTextChanged ( Editable s ) { } } ; private TextWatcher editTextWatcherForFractionLimit = new TextWatcher ( ) { @ Override public void onTextChanged ( CharSequence s , int start , int before , int count ) { if ( ! editText . getText ( ) . toString ( ) . equalsIgnoreCase ( "" ) ) { String editTextString = editText . getText ( ) . toString ( ) . trim ( ) ; int decimalIndexOf = editTextString . indexOf ( "." ) ; if ( decimalIndexOf > = 0 ) { if ( editTextString . substring ( decimalIndexOf ) . length ( ) > fractionLimit ) { startStopEditing ( true ) ; } } } } @ Override public void beforeTextChanged ( CharSequence s , int start , int count , int after ) { } @ Override public void afterTextChanged ( Editable s ) { } } ; public void limitCharacters ( final int limit ) { this . charactersLimit = limit ; editText . addTextChangedListener ( editTextWatcherForCharacterLimits ) ; } public void limitFractionDigitsinDecimal ( int fractionLimit ) { this . fractionLimit = fractionLimit ; editText . addTextChangedListener ( editTextWatcherForFractionLimit ) ; } public void unlockEditText ( ) { startStopEditing ( false ) ; } public void startStopEditing ( boolean isLock ) { if ( isLock ) { editText . setFilters ( new InputFilter [ ] { new InputFilter ( ) { @ Override public CharSequence filter ( CharSequence source , int start , int end , Spanned dest , int dstart , int dend ) { return source . length ( ) < 1 ? dest . subSequence ( dstart , dend ) : "" ; } } } ) ; } else { editText . setFilters ( new InputFilter [ ] { new InputFilter ( ) { @ Override public CharSequence filter ( CharSequence source , int start , int end , Spanned dest , int dstart , int dend ) { return null ; } } } ) ; } } }

Code for Main.java

package com . edittextlocker ; import android . app . Activity ; import android . os . Bundle ; import android . widget . EditText ; public class Main extends Activity { private EditText editText ; private EditText decimalEditText ; @ Override public void onCreate ( Bundle savedInstanceState ) { super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . main ) ; editText = ( EditText ) findViewById ( R . id . edittext ) ; decimalEditText = ( EditText ) findViewById ( R . id . decimal_edittext ) ; EditTextLocker editTextLocker = new EditTextLocker ( editText ) ; editTextLocker . limitCharacters ( 4 ) ; EditTextLocker decimalEditTextLocker = new EditTextLocker ( decimalEditText ) ; decimalEditTextLocker . limitFractionDigitsinDecimal ( 2 ) ; } }

Code for main.xml

<? xml version = " 1.0 " encoding = " utf-8 " ?> < LinearLayout xmlns : android = " http : // schemas.android.com /apk/res/android " android:layout_width = " fill_parent " android:layout_height = " fill_parent " android:orientation = " vertical " > < EditText android:id = " @+id/edittext " android:layout_width = " fill_parent " android:layout_height = " wrap_content " android:hint = " Accepts any 4 characters " > </ EditText > < EditText android:id = " @+id/decimal_edittext " android:layout_width = " wrap_content " android:layout_height = " wrap_content " android:inputType = " numberDecimal " android:hint = " Accepts decimal with 2 fraction digits " /> </ LinearLayout >

You can download the complete source code for the project from here