Masked Input Using Edittext Widget in Android

Masked Input Using EditText Widget in Android

Try using an InputFilter rather than an OnKeyListener. This means you don't have worry about tracking individual key presses and it will also handle things like pasting into a field which would be painful to handle with an OnKeyListener.

You could have a look at the source of the InputFilter implementations that come with Android to give you a starting point for writing your own.

How to mask an EditText to show the dd/mm/yyyy date format

I wrote this TextWatcher for a project, hopefully it will be helpful to someone. Note that it does not validate the date entered by the user, and you should handle that when the focus changes, since the user may not have finished entering the date.

Update 25/06 Made it a wiki to see if we reach a better final code.

Update 07/06
I finally added some sort of validation to the watcher itself. It will do the following with invalid dates:

  • If the month is greater than 12, it will be 12 (December)
  • If the date is greater than the one for the month selected, make it the max for that month.
  • If the year is not in the range 1900-2100, change it to be in the range

This validation fits my needs, but some of you may want to change it a little bit, ranges are easily changeable and you could hook this validations to Toast message for instance, to notify the user that we've modified his/her date since it was invalid.

In this code, I will be assuming that we have a reference to our EditText called date that has this TextWatcher attached to it, this can be done something like this:

EditText date;
date = (EditText)findViewById(R.id.whichdate);
date.addTextChangedListener(tw);

TextWatcher tw = new TextWatcher() {
private String current = "";
private String ddmmyyyy = "DDMMYYYY";
private Calendar cal = Calendar.getInstance();

When user changes text of the EditText

    @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().equals(current)) {
String clean = s.toString().replaceAll("[^\\d.]|\\.", "");
String cleanC = current.replaceAll("[^\\d.]|\\.", "");

int cl = clean.length();
int sel = cl;
for (int i = 2; i <= cl && i < 6; i += 2) {
sel++;
}
//Fix for pressing delete next to a forward slash
if (clean.equals(cleanC)) sel--;

if (clean.length() < 8){
clean = clean + ddmmyyyy.substring(clean.length());
}else{
//This part makes sure that when we finish entering numbers
//the date is correct, fixing it otherwise
int day = Integer.parseInt(clean.substring(0,2));
int mon = Integer.parseInt(clean.substring(2,4));
int year = Integer.parseInt(clean.substring(4,8));

mon = mon < 1 ? 1 : mon > 12 ? 12 : mon;
cal.set(Calendar.MONTH, mon-1);
year = (year<1900)?1900:(year>2100)?2100:year;
cal.set(Calendar.YEAR, year);
// ^ first set year for the line below to work correctly
//with leap years - otherwise, date e.g. 29/02/2012
//would be automatically corrected to 28/02/2012

day = (day > cal.getActualMaximum(Calendar.DATE))? cal.getActualMaximum(Calendar.DATE):day;
clean = String.format("%02d%02d%02d",day, mon, year);
}

clean = String.format("%s/%s/%s", clean.substring(0, 2),
clean.substring(2, 4),
clean.substring(4, 8));

sel = sel < 0 ? 0 : sel;
current = clean;
date.setText(current);
date.setSelection(sel < current.length() ? sel : current.length());
}
}

We also implement the other two functions because we have to

    @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

@Override
public void afterTextChanged(Editable s) {}
};

This produces the following effect, where deleting or inserting characters will reveal or hide the dd/mm/yyyy mask. It should be easy to modify to fit other format masks since I tried to leave the code as simple as possible.

Sample Image

Edittext - Mask with date format

Library author here.

input-mask-android is about text formatting, but your question looks more layout-related.

Three EditText components plus two / labels between them might do the trick. setOnEditorActionListener and TextWatcher listeners will help with cursor movement.

Or you could just put a couple of spaces within curly brackets and call it a day: [00]{ / }[00]{ / }[9900]

I'd also suggest reading more about our affine masks, and then use a couple of patterns for the sake of year correctness:

  • [00]{ / }[00]{ / }[00]
  • [00]{ / }[00]{ / }[0000]

from 1st edittext going to 2nd edittext, input mask not working

try this way

xml

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">

<EditText
android:id="@+id/otp_first_et"
android:layout_width="45sp"
android:layout_height="45sp"
android:layout_marginBottom="10dp"
android:digits="0123456789"
android:drawablePadding="7dp"
android:gravity="center"
android:inputType="number"
android:maxLength="1"
android:paddingLeft="10dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:textCursorDrawable="@drawable/bg_edit_text_cursor" />

<EditText
android:id="@+id/otp_second_et"
android:layout_width="45sp"
android:layout_height="45sp"
android:layout_marginBottom="10dp"
android:digits="0123456789"
android:drawablePadding="7dp"
android:gravity="center"
android:inputType="number"
android:maxLength="1"
android:paddingLeft="10dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:textCursorDrawable="@drawable/bg_edit_text_cursor" />

<EditText
android:id="@+id/otp_third_et"
android:layout_width="45sp"
android:layout_height="45sp"
android:layout_marginBottom="10dp"
android:digits="0123456789"
android:drawablePadding="7dp"
android:gravity="center"
android:inputType="number"
android:maxLength="1"
android:paddingLeft="10dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:textCursorDrawable="@drawable/bg_edit_text_cursor" />

<EditText
android:id="@+id/otp_fourth_et"
android:layout_width="45sp"
android:layout_height="45sp"
android:layout_marginBottom="10dp"
android:digits="0123456789"
android:drawablePadding="7dp"
android:gravity="center"
android:imeOptions="actionDone"
android:inputType="number"
android:maxLength="1"
android:paddingLeft="10dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:textCursorDrawable="@drawable/bg_edit_text_cursor" />
</LinearLayout>

java

EditText otpEditTextFirst, otpEditTextSecond, otpEditTextThird, otpEditTextFourth;

otpEditTextFirst = (EditText) findViewById(R.id.otp_first_et);
otpEditTextSecond = (EditText) findViewById(R.id.otp_second_et);
otpEditTextThird = (EditText) findViewById(R.id.otp_third_et);
otpEditTextFourth = (EditText) findViewById(R.id.otp_fourth_et);

otpEditTextFirst.addTextChangedListener(new GenericTextWatcher(otpEditTextFirst));
otpEditTextSecond.addTextChangedListener(new GenericTextWatcher(otpEditTextSecond));
otpEditTextThird.addTextChangedListener(new GenericTextWatcher(otpEditTextThird));
otpEditTextFourth.addTextChangedListener(new GenericTextWatcher(otpEditTextFourth));

class GenericTextWatcher implements TextWatcher {
private View view;

private GenericTextWatcher(View view) {
this.view = view;
}

@Override
public void afterTextChanged(Editable editable) {
// TODO Auto-generated method stub
String text = editable.toString();
switch (view.getId()) {

case R.id.otp_first_et:

if (text.length() == 1)
otpEditTextSecond.requestFocus();

break;
case R.id.otp_second_et:

if (text.length() == 1)
otpEditTextThird.requestFocus();

else
otpEditTextFirst.requestFocus();
break;
case R.id.otp_third_et:

if (text.length() == 1)
otpEditTextFourth.requestFocus();

else
otpEditTextSecond.requestFocus();
break;
case R.id.otp_fourth_et:
if (text.length() == 0)
otpEditTextThird.requestFocus();

break;
}
}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
}

Mask an EditText with Phone Number Format NaN like in PhoneNumberUtils

Easiest way to do this is to use the built in Android PhoneNumberFormattingTextWatcher.

So basically you get your EditText in code and set your text watcher like this...

EditText inputField = (EditText) findViewById(R.id.inputfield);
inputField.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

Nice thing about using PhoneNumberFormattingTextWatcher is that it will format your number entry correctly based on your locale.

How to use EditTextPreference as a masked Password text field?

Here is a short example using xml:

<EditTextPreference
android:key="@string/key"
android:title="@string/title"
android:summary="@string/summary"
android:inputType="textPassword" />

Or you can use numberPassword instead of textPassword.

How to make editText insert some look

So i find a solution tenx to Philip coment. U have to use filter to do so. My code is now this:

   InputFilter filter = new InputFilter() {

@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {

if(end==0){
if(is_minus){jis_minus=false;}
else number--;
}
for (int i = start; i < end; i++) {

if (!Character.isDigit(source.charAt(i))) {
return "";
}
else{
number++;
}
if(number==5)
{
is_minus=true;
return (source.charAt(i)+"-");
}

}
return null;
}
};

After that u just apend filter to the textbox u want...



Related Topics



Leave a reply



Submit