Tutorial: PIN input view in Android

Hi, guys!

Today’s post will be about PIN-like view in Android. I’m sure that many Android developers would like to have it by default, me included. And so I wanted to show you how I handled the problem caused by lack of such view. But first, how should it look like? Well, it should like an input field where every character has it’s own box and while typing, characters should automatically populate those boxes. Sounds pretty easy, isn’t it? But later, when you think about all of the aspects, you will realize it’s not that simple at all…

First, I wanted to mention that this particular example is for text passwords (or text pin). The code for just numerical PIN view would be much easier. But it wasn’t the case with the app I was writing and I definitely needed the default keyboard. Because I could change my soft keyboard from text to numerical at any point of typing, I couldn’t have a collection of EditTexts because switching from one to another would have changed a keyboard either to text or numerical and I didn’t want that.

So, I had to think of something more flexible. And what I’ve done is created a collection of EditTexts AND another one which user wouldn’t normally see but which will actually take a focus and basically do the job for us.

OK, lets see some code!

Here’s the main.xml layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pin_content_layout" 
  android:orientation="vertical" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:padding="@dimen/pin_content_layout_padding" > 

    <TextView android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/pin_label_text" 
      android:textStyle="bold" 
      android:gravity="center_horizontal" 
      android:layout_gravity="center_horizontal" 
      android:layout_marginBottom="@dimen/pin_label_margin" /> 

    <LinearLayout android:id="@+id/pin_layout" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal" 
      android:gravity="center_horizontal" 
      android:layout_gravity="center_horizontal"> 

        <EditText android:id="@+id/pin_first_edittext" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:contentDescription="@string/pin_content_desc" 
          style="@style/pin_edittext_style" /> 

        <EditText android:id="@+id/pin_second_edittext" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:contentDescription="@string/pin_content_desc" 
          style="@style/pin_edittext_style" /> 

        <EditText android:id="@+id/pin_third_edittext" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:contentDescription="@string/pin_content_desc" 
          style="@style/pin_edittext_style" /> 

        <EditText android:id="@+id/pin_forth_edittext" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:contentDescription="@string/pin_content_desc" 
          style="@style/pin_edittext_style" /> 

        <EditText android:id="@+id/pin_fifth_edittext" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:contentDescription="@string/pin_content_desc" 
          style="@style/pin_edittext_style" />
    </LinearLayout> 

    <EditText android:id="@+id/pin_hidden_edittext" 
      android:layout_width="1dp" 
      android:layout_height="1dp" 
      android:gravity="center_horizontal" 
      android:layout_gravity="center_horizontal" 
      android:background="@null" 
      android:cursorVisible="false" 
      android:password="true" 
      android:maxLength="5" 
      android:textColor="#00000000" 
      android:contentDescription="@string/pin_content_desc" />
</LinearLayout> 

What you can see here is just a LinearLayout with some text label, five edit texts and one hidden below.
It is not even hidden, just a transparent 1dp width and height EditText. Edit texts for pin have its own style.

styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="pin_edittext_style">
       <item name="android:gravity">center</item>
       <item name="android:cursorVisible">false</item>
       <item name="android:maxLength">1</item>
       <item name="android:minEms">2</item>
       <item name="android:inputType">textPassword</item>
       <item name="android:focusable">true</item>
       <item name="android:focusableInTouchMode">true</item>
    </style>
</resources>

We want our characters aligned to center, cursor won’t be visible as we won’t edit one character separately but the whole PIN view at once. Max length each of those PIN inputs should be 1. minEms with value of 2 ensures the width of input won’t shrink or expand depending on character width.

Strings for this example project:

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
       <string name="app_name">PinProject</string>
       <string name="pin_content_desc">PIN input field</string>
       <string name="pin_label_text">PIN</string>
</resources>

Some dimentions:

dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
       <dimen name="pin_content_layout_padding">40dp</dimen>
       <dimen name="pin_label_margin">10dp</dimen>
       <dimen name="pin_min_width">32dp</dimen>
</resources>

And AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.lomza.pinproject"
     android:versionCode="1"
     android:versionName="1.0">

       <uses-sdk
           android:minSdkVersion="14"
           android:targetSdkVersion="18"/>
       <application
           android:label="@string/app_name"
           android:icon="@drawable/ic_launcher"
           android:theme="@android:style/Theme.Holo.Light">
       <activity
           android:name="MainActivity"
           android:label="@string/app_name">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN"/>
                  <category android:name="android.intent.category.LAUNCHER"/>
              </intent-filter>
       </activity>
       </application>
</manifest>

This project wasn’t tested on Android 2.x.x, so I just put a min SDK version to 14 (which is Android 4.0). You can try to run it on lower versions.

I have also used Theme.Holo.Light. It could have been any other theme, it’s just that I need EditText focusable and default backgrounds and they were adjusted for the Light theme. Why bother about those backgrounds? Because we will set it programmatically depending on focus and on characters typed in our PIN view. You will see when you will actually run this project 🙂 Just remeber, you need to have some gfx files 😉

OK, so the most interesting part is the code!

Here’s MainActivity.java


/**
 * This activity holds view with a custom 5-digit PIN EditText.
 */
public class MainActivity extends Activity implements View.OnFocusChangeListener, View.OnKeyListener, TextWatcher {
    private EditText mPinFirstDigitEditText;
    private EditText mPinSecondDigitEditText;
    private EditText mPinThirdDigitEditText;
    private EditText mPinForthDigitEditText;
    private EditText mPinFifthDigitEditText;
    private EditText mPinHiddenEditText;

    @Override
    public void afterTextChanged(Editable s) {
    }

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

    /**
     * Hides soft keyboard.
     *
     * @param editText EditText which has focus
     */
    public void hideSoftKeyboard(EditText editText) {
        if (editText == null)
            return;

        InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    }

    /**
     * Initialize EditText fields.
     */
    private void init() {
        mPinFirstDigitEditText = (EditText) findViewById(R.id.pin_first_edittext);
        mPinSecondDigitEditText = (EditText) findViewById(R.id.pin_second_edittext);
        mPinThirdDigitEditText = (EditText) findViewById(R.id.pin_third_edittext);
        mPinForthDigitEditText = (EditText) findViewById(R.id.pin_forth_edittext);
        mPinFifthDigitEditText = (EditText) findViewById(R.id.pin_fifth_edittext);
        mPinHiddenEditText = (EditText) findViewById(R.id.pin_hidden_edittext);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MainLayout(this, null));

        init();
        setPINListeners();
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        final int id = v.getId();
        switch (id) {
            case R.id.pin_first_edittext:
                if (hasFocus) {
                    setFocus(mPinHiddenEditText);
                    showSoftKeyboard(mPinHiddenEditText);
                }
                break;

            case R.id.pin_second_edittext:
                if (hasFocus) {
                    setFocus(mPinHiddenEditText);
                    showSoftKeyboard(mPinHiddenEditText);
                }
                break;

            case R.id.pin_third_edittext:
                if (hasFocus) {
                    setFocus(mPinHiddenEditText);
                    showSoftKeyboard(mPinHiddenEditText);
                }
                break;

            case R.id.pin_forth_edittext:
                if (hasFocus) {
                    setFocus(mPinHiddenEditText);
                    showSoftKeyboard(mPinHiddenEditText);
                }
                break;

            case R.id.pin_fifth_edittext:
                if (hasFocus) {
                    setFocus(mPinHiddenEditText);
                    showSoftKeyboard(mPinHiddenEditText);
                }
                break;
            default:
                break;
        }
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            final int id = v.getId();
            switch (id) {
                case R.id.pin_hidden_edittext:
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        if (mPinHiddenEditText.getText().length() == 5)
                            mPinFifthDigitEditText.setText("");
                        else if (mPinHiddenEditText.getText().length() == 4)
                            mPinForthDigitEditText.setText("");
                        else if (mPinHiddenEditText.getText().length() == 3)
                            mPinThirdDigitEditText.setText("");
                        else if (mPinHiddenEditText.getText().length() == 2)
                            mPinSecondDigitEditText.setText("");
                        else if (mPinHiddenEditText.getText().length() == 1)
                            mPinFirstDigitEditText.setText("");

                        if (mPinHiddenEditText.length() > 0)
                            mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() - 1));

                        return true;
                    }

                    break;

                default:
                    return false;
            }
        }

        return false;
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        setDefaultPinBackground(mPinFirstDigitEditText);
        setDefaultPinBackground(mPinSecondDigitEditText);
        setDefaultPinBackground(mPinThirdDigitEditText);
        setDefaultPinBackground(mPinForthDigitEditText);
        setDefaultPinBackground(mPinFifthDigitEditText);

        if (s.length() == 0) {
            setFocusedPinBackground(mPinFirstDigitEditText);
            mPinFirstDigitEditText.setText("");
        } else if (s.length() == 1) {
            setFocusedPinBackground(mPinSecondDigitEditText);
            mPinFirstDigitEditText.setText(s.charAt(0) + "");
            mPinSecondDigitEditText.setText("");
            mPinThirdDigitEditText.setText("");
            mPinForthDigitEditText.setText("");
            mPinFifthDigitEditText.setText("");
        } else if (s.length() == 2) {
            setFocusedPinBackground(mPinThirdDigitEditText);
            mPinSecondDigitEditText.setText(s.charAt(1) + "");
            mPinThirdDigitEditText.setText("");
            mPinForthDigitEditText.setText("");
            mPinFifthDigitEditText.setText("");
        } else if (s.length() == 3) {
            setFocusedPinBackground(mPinForthDigitEditText);
            mPinThirdDigitEditText.setText(s.charAt(2) + "");
            mPinForthDigitEditText.setText("");
            mPinFifthDigitEditText.setText("");
        } else if (s.length() == 4) {
            setFocusedPinBackground(mPinFifthDigitEditText);
            mPinForthDigitEditText.setText(s.charAt(3) + "");
            mPinFifthDigitEditText.setText("");
        } else if (s.length() == 5) {
            setDefaultPinBackground(mPinFifthDigitEditText);
            mPinFifthDigitEditText.setText(s.charAt(4) + "");

            hideSoftKeyboard(mPinFifthDigitEditText);
        }
    }

    /**
     * Sets default PIN background.
     *
     * @param editText edit text to change
     */
    private void setDefaultPinBackground(EditText editText) {
        setViewBackground(editText, getResources().getDrawable(R.drawable.textfield_default_holo_light));
    }

    /**
     * Sets focus on a specific EditText field.
     *
     * @param editText EditText to set focus on
     */
    public static void setFocus(EditText editText) {
        if (editText == null)
            return;

        editText.setFocusable(true);
        editText.setFocusableInTouchMode(true);
        editText.requestFocus();
    }

    /**
     * Sets focused PIN field background.
     *
     * @param editText edit text to change
     */
    private void setFocusedPinBackground(EditText editText) {
        setViewBackground(editText, getResources().getDrawable(R.drawable.textfield_focused_holo_light));
    }

    /**
     * Sets listeners for EditText fields.
     */
    private void setPINListeners() {
        mPinHiddenEditText.addTextChangedListener(this);

        mPinFirstDigitEditText.setOnFocusChangeListener(this);
        mPinSecondDigitEditText.setOnFocusChangeListener(this);
        mPinThirdDigitEditText.setOnFocusChangeListener(this);
        mPinForthDigitEditText.setOnFocusChangeListener(this);
        mPinFifthDigitEditText.setOnFocusChangeListener(this);

        mPinFirstDigitEditText.setOnKeyListener(this);
        mPinSecondDigitEditText.setOnKeyListener(this);
        mPinThirdDigitEditText.setOnKeyListener(this);
        mPinForthDigitEditText.setOnKeyListener(this);
        mPinFifthDigitEditText.setOnKeyListener(this);
        mPinHiddenEditText.setOnKeyListener(this);
    }

    /**
     * Sets background of the view.
     * This method varies in implementation depending on Android SDK version.
     *
     * @param view       View to which set background
     * @param background Background to set to view
     */
    @SuppressWarnings("deprecation")
    public void setViewBackground(View view, Drawable background) {
        if (view == null || background == null)
            return;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackground(background);
        } else {
            view.setBackgroundDrawable(background);
        }
    }

    /**
     * Shows soft keyboard.
     *
     * @param editText EditText which has focus
     */
    public void showSoftKeyboard(EditText editText) {
        if (editText == null)
            return;

        InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
        imm.showSoftInput(editText, 0);
    }

    /**
     * Custom LinearLayout with overridden onMeasure() method
     * for handling software keyboard show and hide events.
     */
    public class MainLayout extends LinearLayout {

        public MainLayout(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            inflater.inflate(R.layout.main, this);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
            final int actualHeight = getHeight();

            Log.d("TAG", "proposed: " + proposedHeight + ", actual: " + actualHeight);

            if (actualHeight >= proposedHeight) {
                // Keyboard is shown
                if (mPinHiddenEditText.length() == 0)
                    setFocusedPinBackground(mPinFirstDigitEditText);
                else
                    setDefaultPinBackground(mPinFirstDigitEditText);
            }

            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

Wow, a lot of code you might say! And yet, there’s is just enough for correct functioning 😉

We have init() method in which our edit texts are initialized, then we have onFocusChange() method. If user touches any of our pin edit texts, we should catch the focus of our hidden EditText and show soft keyboard. onKey() method checks if DEL key was pressed, then checks how many characters were typed and based on that sets our edit texts to empty. onTextChanged() method sets correct background based on text length and also sets characters we typed.

The last interesting thing here is MainLayout which is just a LinearLayout with overridden onMeasure() method. Why do you need this? Because when the keyboard is shown, we need to highlight the first PIN box (if it is not empty). This is just for a better UX, nothing more I guess…

PIN view

 

And that’s all! A lot of code but the idea is quite clear. We have one EditText, which catches the focus and characters we type, everything else is just a programmatic trick 😉

Thanks for reading!

Like and share:

Published by

Tonia Tkachuk

I'm an Android Developer, writing code for living and for fun. Love beautiful apps with a clean code inside. Enjoy travelling and reading.

19 thoughts on “Tutorial: PIN input view in Android”

  1. There is one bug. If you insert all digit then erase few of them then enter remaining. out put is different. I fixed by add following lines in onKey method.

    if (mPinHiddenEditText.length() > 0) {
    mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));
    mPinHiddenEditText.post(new Runnable() {
    @Override
    public void run() {
    mPinHiddenEditText.setSelection(mPinHiddenEditText.getText().toString().length());
    }
    });
    }

      1. at the end.
        edit text only accept string values how can i change to integer .. i want to compare with an otp, am new to android please help me

        1. If you want to have a number field, just add android:inputType=”number” to EditText in xml. You get values by calling editText.getText().toString() and can convert it to integer as Integer.valueOf(“your string”)

          1. i already tried , inputType=”number” but it not accept integer , how can i solve

            number
            please help me

          2. You have to share your code here, otherwise I can’t help you. It should accept integers, like editText.setText(123)

          3. i will

            please find out the error

            style.xml

            center
            false
            1
            2
            number
            true
            true

            activityXML

            Activity.java

            public class OTPActivity extends Activity implements View.OnFocusChangeListener, View.OnKeyListener, TextWatcher {
            private EditText mPinFirstDigitEditText;
            private EditText mPinSecondDigitEditText;
            private EditText mPinThirdDigitEditText;
            private EditText mPinForthDigitEditText;
            private EditText mPinFifthDigitEditText;
            private EditText mPinHiddenEditText;
            String a,b,c,d,e,otp;
            TextView otphead;
            ImageView img;
            String a1=”One Time Password(OTP) has been sent to your mobile ******1234,please enter the same here to login.”;
            @Override
            public void afterTextChanged(Editable s) {
            }

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

            /**
            * Hides soft keyboard.
            *
            * @param editText EditText which has focus
            */
            public void hideSoftKeyboard(EditText editText) {
            if (editText == null)
            return;

            InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

            }

            /**
            * Initialize EditText fields.
            */
            private void init() {
            mPinFirstDigitEditText = (EditText) findViewById(R.id.pin_first_edittext);
            mPinSecondDigitEditText = (EditText) findViewById(R.id.pin_second_edittext);
            mPinThirdDigitEditText = (EditText) findViewById(R.id.pin_third_edittext);
            mPinForthDigitEditText = (EditText) findViewById(R.id.pin_forth_edittext);
            mPinFifthDigitEditText = (EditText) findViewById(R.id.pin_fifth_edittext);
            mPinHiddenEditText = (EditText) findViewById(R.id.pin_hidden_edittext);
            otphead=(TextView) findViewById(R.id.otpid);
            img=(ImageView) findViewById(R.id.imageView2);
            mPinFirstDigitEditText.setInputType(InputType.TYPE_CLASS_NUMBER);
            }

            @Override
            public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new MainLayout(this, null));
            init();
            setPINListeners();
            otphead.setText(a1);
            img.setBackground( getResources().getDrawable(R.drawable.otppic));
            }

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
            final int id = v.getId();
            switch (id) {
            case R.id.pin_first_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_second_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_third_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_forth_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_fifth_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);

            }
            break;
            default:
            break;
            }
            }

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (mPinHiddenEditText.length() > 0) {
            mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));
            mPinHiddenEditText.post(new Runnable() {
            @Override
            public void run() {
            mPinHiddenEditText.setSelection(mPinHiddenEditText.getText().toString().length());

            }
            });
            }
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
            final int id = v.getId();
            switch (id) {
            case R.id.pin_hidden_edittext:
            if (keyCode == KeyEvent.KEYCODE_DEL) {
            if (mPinHiddenEditText.getText().length() == 5)
            mPinFifthDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 4)
            mPinForthDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 3)
            mPinThirdDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 2)
            mPinSecondDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 1)
            mPinFirstDigitEditText.setText(“”);

            if (mPinHiddenEditText.length() > 0)
            mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));

            return true;
            }

            break;

            default:
            return false;
            }
            }

            return false;
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            setDefaultPinBackground(mPinFirstDigitEditText);
            setDefaultPinBackground(mPinSecondDigitEditText);
            setDefaultPinBackground(mPinThirdDigitEditText);
            setDefaultPinBackground(mPinForthDigitEditText);
            setDefaultPinBackground(mPinFifthDigitEditText);

            if (s.length() == 0) {
            setFocusedPinBackground(mPinFirstDigitEditText);
            mPinFirstDigitEditText.setText(“”);

            } else if (s.length() == 1) {
            setFocusedPinBackground(mPinSecondDigitEditText);
            mPinFirstDigitEditText.setText(s.charAt(0) + “”);
            mPinSecondDigitEditText.setText(“”);
            mPinThirdDigitEditText.setText(“”);
            mPinForthDigitEditText.setText(“”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 2) {
            setFocusedPinBackground(mPinThirdDigitEditText);
            mPinSecondDigitEditText.setText(s.charAt(1) + “”);
            mPinThirdDigitEditText.setText(“”);
            mPinForthDigitEditText.setText(“”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 3) {
            setFocusedPinBackground(mPinForthDigitEditText);
            mPinThirdDigitEditText.setText(s.charAt(2) + “”);
            mPinForthDigitEditText.setText(“”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 4) {
            setFocusedPinBackground(mPinFifthDigitEditText);
            mPinForthDigitEditText.setText(s.charAt(3) + “”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 5) {
            setDefaultPinBackground(mPinFifthDigitEditText);
            mPinFifthDigitEditText.setText(s.charAt(4) + “”);

            hideSoftKeyboard(mPinFifthDigitEditText);

            a=mPinFirstDigitEditText.getText().toString();
            b=mPinSecondDigitEditText.getText().toString();
            c=mPinThirdDigitEditText.getText().toString();
            d=mPinForthDigitEditText.getText().toString();
            e=mPinFifthDigitEditText.getText().toString();

            otp=a+b+c+d+e;
            Toast.makeText(OTPActivity.this,otp,Toast.LENGTH_LONG).show();
            Toast.makeText(OTPActivity.this, “OTP is:”+mPinHiddenEditText.getText(),Toast.LENGTH_LONG).show();

            }

            }

            /**
            * Sets default PIN background.
            *
            * @param editText edit text to change
            */
            private void setDefaultPinBackground(EditText editText) {
            // setViewBackground(editText, getResources().getDrawable(R.drawable.textfield_default_holo_light));
            }

            /**
            * Sets focus on a specific EditText field.
            *
            * @param editText EditText to set focus on
            */
            public static void setFocus(EditText editText) {
            if (editText == null)
            return;

            editText.setFocusable(true);
            editText.setFocusableInTouchMode(true);
            editText.requestFocus();
            }

            /**
            * Sets focused PIN field background.
            *
            * @param editText edit text to change
            */
            private void setFocusedPinBackground(EditText editText) {
            // setViewBackground(editText, getResources().getDrawable(R.drawable.textfield_focused_holo_light));
            }

            /**
            * Sets listeners for EditText fields.
            */
            private void setPINListeners() {
            mPinHiddenEditText.addTextChangedListener(this);

            mPinFirstDigitEditText.setOnFocusChangeListener(this);
            mPinSecondDigitEditText.setOnFocusChangeListener(this);
            mPinThirdDigitEditText.setOnFocusChangeListener(this);
            mPinForthDigitEditText.setOnFocusChangeListener(this);
            mPinFifthDigitEditText.setOnFocusChangeListener(this);

            mPinFirstDigitEditText.setOnKeyListener(this);
            mPinSecondDigitEditText.setOnKeyListener(this);
            mPinThirdDigitEditText.setOnKeyListener(this);
            mPinForthDigitEditText.setOnKeyListener(this);
            mPinFifthDigitEditText.setOnKeyListener(this);
            mPinHiddenEditText.setOnKeyListener(this);

            }

            /**
            * Sets background of the view.
            * This method varies in implementation depending on Android SDK version.
            *
            * @param view View to which set background
            * @param background Background to set to view
            */
            @SuppressWarnings(“deprecation”)
            public void setViewBackground(View view, Drawable background) {
            if (view == null || background == null)
            return;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackground(background);
            } else {
            view.setBackgroundDrawable(background);
            }
            }

            /**
            * Shows soft keyboard.
            *
            * @param editText EditText which has focus
            */
            public void showSoftKeyboard(EditText editText) {
            if (editText == null)
            return;

            InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
            imm.showSoftInput(editText, 0);
            }

            /**
            * Custom LinearLayout with overridden onMeasure() method
            * for handling software keyboard show and hide events.
            */
            public class MainLayout extends LinearLayout {

            public MainLayout(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            inflater.inflate(R.layout.activity_otp, this);

            }

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
            final int actualHeight = getHeight();

            Log.d(“TAG”, “proposed: ” + proposedHeight + “, actual: ” + actualHeight);

            if (actualHeight >= proposedHeight) {
            // Keyboard is shown
            if (mPinHiddenEditText.length() == 0)
            setFocusedPinBackground(mPinFirstDigitEditText);
            else
            setDefaultPinBackground(mPinFirstDigitEditText);
            }

            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
            }
            }

          4. import android.app.Activity;
            import android.app.Service;
            import android.content.Context;
            import android.graphics.drawable.Drawable;
            import android.os.Build;
            import android.support.v7.app.AppCompatActivity;
            import android.os.Bundle;
            import android.text.Editable;
            import android.text.InputType;
            import android.text.TextWatcher;
            import android.util.AttributeSet;
            import android.util.Log;
            import android.view.KeyEvent;
            import android.view.LayoutInflater;
            import android.view.View;
            import android.view.inputmethod.InputMethodManager;
            import android.widget.EditText;
            import android.widget.ImageView;
            import android.widget.LinearLayout;
            import android.widget.TextView;
            import android.widget.Toast;

            public class OTPActivity extends Activity implements View.OnFocusChangeListener, View.OnKeyListener, TextWatcher {
            private EditText mPinFirstDigitEditText;
            private EditText mPinSecondDigitEditText;
            private EditText mPinThirdDigitEditText;
            private EditText mPinForthDigitEditText;
            private EditText mPinFifthDigitEditText;
            private EditText mPinHiddenEditText;
            String a,b,c,d,e,otp;
            TextView otphead;
            ImageView img;
            String a1=”One Time Password(OTP) has been sent to your mobile ******1234,please enter the same here to login.”;
            @Override
            public void afterTextChanged(Editable s) {
            }

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

            /**
            * Hides soft keyboard.
            *
            * @param editText EditText which has focus
            */
            public void hideSoftKeyboard(EditText editText) {
            if (editText == null)
            return;

            InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

            }

            /**
            * Initialize EditText fields.
            */
            private void init() {
            mPinFirstDigitEditText = (EditText) findViewById(R.id.pin_first_edittext);
            mPinSecondDigitEditText = (EditText) findViewById(R.id.pin_second_edittext);
            mPinThirdDigitEditText = (EditText) findViewById(R.id.pin_third_edittext);
            mPinForthDigitEditText = (EditText) findViewById(R.id.pin_forth_edittext);
            mPinFifthDigitEditText = (EditText) findViewById(R.id.pin_fifth_edittext);
            mPinHiddenEditText = (EditText) findViewById(R.id.pin_hidden_edittext);
            otphead=(TextView) findViewById(R.id.otpid);
            img=(ImageView) findViewById(R.id.imageView2);
            mPinFirstDigitEditText.setInputType(InputType.TYPE_CLASS_NUMBER);
            }

            @Override
            public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new MainLayout(this, null));
            init();
            setPINListeners();
            otphead.setText(a1);
            img.setBackground( getResources().getDrawable(R.drawable.otppic));
            }

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
            final int id = v.getId();
            switch (id) {
            case R.id.pin_first_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_second_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_third_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_forth_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);
            }
            break;

            case R.id.pin_fifth_edittext:
            if (hasFocus) {
            setFocus(mPinHiddenEditText);
            showSoftKeyboard(mPinHiddenEditText);

            }
            break;
            default:
            break;
            }
            }

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (mPinHiddenEditText.length() > 0) {
            mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));
            mPinHiddenEditText.post(new Runnable() {
            @Override
            public void run() {
            mPinHiddenEditText.setSelection(mPinHiddenEditText.getText().toString().length());

            }
            });
            }
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
            final int id = v.getId();
            switch (id) {
            case R.id.pin_hidden_edittext:
            if (keyCode == KeyEvent.KEYCODE_DEL) {
            if (mPinHiddenEditText.getText().length() == 5)
            mPinFifthDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 4)
            mPinForthDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 3)
            mPinThirdDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 2)
            mPinSecondDigitEditText.setText(“”);
            else if (mPinHiddenEditText.getText().length() == 1)
            mPinFirstDigitEditText.setText(“”);

            if (mPinHiddenEditText.length() > 0)
            mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));

            return true;
            }

            break;

            default:
            return false;
            }
            }

            return false;
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            setDefaultPinBackground(mPinFirstDigitEditText);
            setDefaultPinBackground(mPinSecondDigitEditText);
            setDefaultPinBackground(mPinThirdDigitEditText);
            setDefaultPinBackground(mPinForthDigitEditText);
            setDefaultPinBackground(mPinFifthDigitEditText);

            if (s.length() == 0) {
            setFocusedPinBackground(mPinFirstDigitEditText);
            mPinFirstDigitEditText.setText(“”);

            } else if (s.length() == 1) {
            setFocusedPinBackground(mPinSecondDigitEditText);
            mPinFirstDigitEditText.setText(s.charAt(0) + “”);
            mPinSecondDigitEditText.setText(“”);
            mPinThirdDigitEditText.setText(“”);
            mPinForthDigitEditText.setText(“”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 2) {
            setFocusedPinBackground(mPinThirdDigitEditText);
            mPinSecondDigitEditText.setText(s.charAt(1) + “”);
            mPinThirdDigitEditText.setText(“”);
            mPinForthDigitEditText.setText(“”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 3) {
            setFocusedPinBackground(mPinForthDigitEditText);
            mPinThirdDigitEditText.setText(s.charAt(2) + “”);
            mPinForthDigitEditText.setText(“”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 4) {
            setFocusedPinBackground(mPinFifthDigitEditText);
            mPinForthDigitEditText.setText(s.charAt(3) + “”);
            mPinFifthDigitEditText.setText(“”);

            } else if (s.length() == 5) {
            setDefaultPinBackground(mPinFifthDigitEditText);
            mPinFifthDigitEditText.setText(s.charAt(4) + “”);

            hideSoftKeyboard(mPinFifthDigitEditText);

            a=mPinFirstDigitEditText.getText().toString();
            b=mPinSecondDigitEditText.getText().toString();
            c=mPinThirdDigitEditText.getText().toString();
            d=mPinForthDigitEditText.getText().toString();
            e=mPinFifthDigitEditText.getText().toString();

            otp=a+b+c+d+e;
            Toast.makeText(OTPActivity.this,otp,Toast.LENGTH_LONG).show();
            Toast.makeText(OTPActivity.this, “OTP is:”+mPinHiddenEditText.getText(),Toast.LENGTH_LONG).show();

            }

            }

            /**
            * Sets default PIN background.
            *
            * @param editText edit text to change
            */
            private void setDefaultPinBackground(EditText editText) {
            // setViewBackground(editText, getResources().getDrawable(R.drawable.textfield_default_holo_light));
            }

            /**
            * Sets focus on a specific EditText field.
            *
            * @param editText EditText to set focus on
            */
            public static void setFocus(EditText editText) {
            if (editText == null)
            return;

            editText.setFocusable(true);
            editText.setFocusableInTouchMode(true);
            editText.requestFocus();
            }

            /**
            * Sets focused PIN field background.
            *
            * @param editText edit text to change
            */
            private void setFocusedPinBackground(EditText editText) {
            // setViewBackground(editText, getResources().getDrawable(R.drawable.textfield_focused_holo_light));
            }

            /**
            * Sets listeners for EditText fields.
            */
            private void setPINListeners() {
            mPinHiddenEditText.addTextChangedListener(this);

            mPinFirstDigitEditText.setOnFocusChangeListener(this);
            mPinSecondDigitEditText.setOnFocusChangeListener(this);
            mPinThirdDigitEditText.setOnFocusChangeListener(this);
            mPinForthDigitEditText.setOnFocusChangeListener(this);
            mPinFifthDigitEditText.setOnFocusChangeListener(this);

            mPinFirstDigitEditText.setOnKeyListener(this);
            mPinSecondDigitEditText.setOnKeyListener(this);
            mPinThirdDigitEditText.setOnKeyListener(this);
            mPinForthDigitEditText.setOnKeyListener(this);
            mPinFifthDigitEditText.setOnKeyListener(this);
            mPinHiddenEditText.setOnKeyListener(this);

            }

            /**
            * Sets background of the view.
            * This method varies in implementation depending on Android SDK version.
            *
            * @param view View to which set background
            * @param background Background to set to view
            */
            @SuppressWarnings(“deprecation”)
            public void setViewBackground(View view, Drawable background) {
            if (view == null || background == null)
            return;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackground(background);
            } else {
            view.setBackgroundDrawable(background);
            }
            }

            /**
            * Shows soft keyboard.
            *
            * @param editText EditText which has focus
            */
            public void showSoftKeyboard(EditText editText) {
            if (editText == null)
            return;

            InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
            imm.showSoftInput(editText, 0);
            }

            /**
            * Custom LinearLayout with overridden onMeasure() method
            * for handling software keyboard show and hide events.
            */
            public class MainLayout extends LinearLayout {

            public MainLayout(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            inflater.inflate(R.layout.activity_otp, this);

            }

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
            final int actualHeight = getHeight();

            Log.d(“TAG”, “proposed: ” + proposedHeight + “, actual: ” + actualHeight);

            if (actualHeight >= proposedHeight) {
            // Keyboard is shown
            if (mPinHiddenEditText.length() == 0)
            setFocusedPinBackground(mPinFirstDigitEditText);
            else
            setDefaultPinBackground(mPinFirstDigitEditText);
            }

            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
            }
            }

          5. You have over-complified the code 🙂 Please return to the code from this post and just make these modifications:

            center
            false
            1
            2
            number
            true
            true

            And

            in xml layout. This worked for me.

          6. i made these changes (comment) these two classes so its works fine

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
            // if (mPinHiddenEditText.length() > 0) {
            // mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));
            // mPinHiddenEditText.post(new Runnable() {
            // @Override
            // public void run() {
            // mPinHiddenEditText.setSelection(mPinHiddenEditText.getText().toString().length());
            //
            // }
            // });
            // }
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
            // final int id = v.getId();
            // switch (id) {
            // case R.id.pin_hidden_edittext:
            // if (keyCode == KeyEvent.KEYCODE_DEL) {
            // if (mPinHiddenEditText.getText().length() == 5)
            // mPinFifthDigitEditText.setText(“”);
            // else if (mPinHiddenEditText.getText().length() == 4)
            // mPinForthDigitEditText.setText(“”);
            // else if (mPinHiddenEditText.getText().length() == 3)
            // mPinThirdDigitEditText.setText(“”);
            // else if (mPinHiddenEditText.getText().length() == 2)
            // mPinSecondDigitEditText.setText(“”);
            // else if (mPinHiddenEditText.getText().length() == 1)
            // mPinFirstDigitEditText.setText(“”);
            //
            // if (mPinHiddenEditText.length() > 0)
            // mPinHiddenEditText.setText(mPinHiddenEditText.getText().subSequence(0, mPinHiddenEditText.length() – 1));
            //
            // return true;
            // }
            //
            // break;
            //
            // default:
            // return false;
            // }
            }

            return false;
            }

  2. i have confirm mpin screen where i have eight edit text. i have done the same code for next four confirm mpin edit text but

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
    final int id = v.getId();
    switch (id) {
    case R.id.setpin_first_edittext:
    if (hasFocus) {
    setFocus(setPinHiddenEditText);
    showSoftKeyboard(setPinHiddenEditText);
    }
    break;

    case R.id.setpin_second_edittext:
    if (hasFocus) {
    setFocus(setPinHiddenEditText);
    showSoftKeyboard(setPinHiddenEditText);
    }
    break;

    case R.id.setpin_third_edittext:
    if (hasFocus) {
    setFocus(setPinHiddenEditText);
    showSoftKeyboard(setPinHiddenEditText);
    }
    break;

    case R.id.setpin_forth_edittext:
    if (hasFocus) {
    setFocus(setPinHiddenEditText);
    showSoftKeyboard(setPinHiddenEditText);
    }
    break;

    case R.id.cnf_pin_first_edittext:
    if (hasFocus) {
    setFocus(cnfSetPinHiddenEditText);
    showSoftKeyboard(cnfSetPinHiddenEditText);
    }
    break;

    case R.id.cnf_pin_second_edittext:
    if (hasFocus) {
    setFocus(cnfSetPinHiddenEditText);
    showSoftKeyboard(cnfSetPinHiddenEditText);
    }
    break;

    case R.id.cnf_pin_third_edittext:
    if (hasFocus) {
    setFocus(cnfSetPinHiddenEditText);
    showSoftKeyboard(cnfSetPinHiddenEditText);
    }
    break;

    case R.id.cnf_pin_forth_edittext:
    if (hasFocus) {
    setFocus(cnfSetPinHiddenEditText);
    showSoftKeyboard(cnfSetPinHiddenEditText);
    }
    break;
    default:
    break;
    }
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
    final int id = v.getId();
    switch (id) {
    case R.id.setpin_hidden_edittext:
    if (keyCode == KeyEvent.KEYCODE_DEL) {
    if (setPinHiddenEditText.getText().length() == 4)
    setPinForthDigitEditText.setText(“”);
    else if (setPinHiddenEditText.getText().length() == 3)
    setPinThirdDigitEditText.setText(“”);
    else if (setPinHiddenEditText.getText().length() == 2)
    setPinSecondDigitEditText.setText(“”);
    else if (setPinHiddenEditText.getText().length() == 1)
    setPinFirstDigitEditText.setText(“”);

    if (setPinHiddenEditText.length() > 0)

    setPinHiddenEditText.setText(setPinHiddenEditText.getText().subSequence(0,
    setPinHiddenEditText.length() – 1));

    return true;
    }

    case R.id.cnf_pin_hidden_edittext:
    if (keyCode == KeyEvent.KEYCODE_DEL) {
    if (cnfSetPinHiddenEditText.getText().length() == 4)
    cnfSetPinForthDigitEditText.setText(“”);
    else if (cnfSetPinHiddenEditText.getText().length() == 3)
    cnfSetPinThirdDigitEditText.setText(“”);
    else if (cnfSetPinHiddenEditText.getText().length() == 2)
    cnfSetPinSecondDigitEditText.setText(“”);
    else if (cnfSetPinHiddenEditText.getText().length() == 1)
    cnfSetPinFirstDigitEditText.setText(“”);

    if (cnfSetPinHiddenEditText.length() > 0)

    cnfSetPinHiddenEditText.setText(cnfSetPinHiddenEditText.getText().subSequence(0,
    cnfSetPinHiddenEditText.length() – 1));

    return true;
    }
    break;

    default:
    return false;
    }
    }

    return false;
    }

    @Override
    public void onTextChanged(final CharSequence s, int start, int before, int count) {
    String strLen = setPinHiddenEditText.getText().toString();

    if (s.length() == 0) {
    setFocusedPinBackground(setPinFirstDigitEditText);
    setPinFirstDigitEditText.setText(“”);
    String a = setPinHiddenEditText.getText().toString();
    Log.d(“setPinFirstDigit.”, a);
    } else if (s.length() == 1) {
    setFocusedPinBackground(setPinSecondDigitEditText);
    setPinFirstDigitEditText.setText(s.charAt(0) + “”);
    setPinSecondDigitEditText.setText(“”);
    setPinThirdDigitEditText.setText(“”);
    setPinForthDigitEditText.setText(“”);
    String a = setPinHiddenEditText.getText().toString();
    Log.d(“setPinSecondDigit.”, a);
    } else if (s.length() == 2) {
    setFocusedPinBackground(setPinThirdDigitEditText);
    setPinSecondDigitEditText.setText(s.charAt(1) + “”);
    setPinThirdDigitEditText.setText(“”);
    setPinForthDigitEditText.setText(“”);
    String a = setPinHiddenEditText.getText().toString();
    Log.d(“setPinThirdDigit.”, a);
    } else if (s.length() == 3) {
    setFocusedPinBackground(setPinForthDigitEditText);
    setPinThirdDigitEditText.setText(s.charAt(2) + “”);
    String a = setPinHiddenEditText.getText().toString();
    Log.d(“setPinForthDigit.”, a);
    setPinForthDigitEditText.setText(“”);
    } else if (s.length() == 4) {
    setPinForthDigitEditText.setText(s.charAt(3) + “”);
    String a = setPinHiddenEditText.getText().toString();
    Log.d(“setPinHiddenEditText.”, a);
    }else if (s.length() == 5) {
    setFocusedPinBackground(cnfSetPinSecondDigitEditText);
    cnfSetPinFirstDigitEditText.setText(s.charAt(4) + “”);
    cnfSetPinSecondDigitEditText.setText(“”);
    cnfSetPinThirdDigitEditText.setText(“”);
    cnfSetPinForthDigitEditText.setText(“”);
    }else if (s.length() == 6) {
    setFocusedPinBackground(cnfSetPinThirdDigitEditText);
    cnfSetPinSecondDigitEditText.setText(s.charAt(5) + “”);
    cnfSetPinThirdDigitEditText.setText(“”);
    cnfSetPinForthDigitEditText.setText(“”);
    } else if (s.length() == 7) {
    setFocusedPinBackground(cnfSetPinForthDigitEditText);
    cnfSetPinThirdDigitEditText.setText(s.charAt(6) + “”);
    cnfSetPinForthDigitEditText.setText(“”);
    } else if (s.length() == 8) {
    cnfSetPinForthDigitEditText.setText(s.charAt(7) + “”);
    String a = cnfSetPinHiddenEditText.getText().toString();
    Log.v(“value…….”, a);
    }

    but its not working properly , Kindly guide me where i am missing.

Leave a Reply

Your email address will not be published.