Android Custom PIN Entry Widget

I am trying to create a custom pincode widget for Android as an alternative to just using a EditTextpassword with the inputType attribute. What I would like to display is a series of boxes, and each box is filled when the user enters his output.

Someone else did something like this, but it turned out to be a fixed number of views EditText, and there was a lot of ugly code to replace focus, because the characters were printed or deleted. This is NOT the approach I want to take; rather, I design mine to have a custom length (easy) and behave like a single-focus view (not so simple).

My concept so far is a hybrid between LinearLayout(for storing "boxes") and EditText(for storing user input).

This is the code so far ...

public class PinCodeView extends LinearLayout {
    protected static final int MAX_PIN_LENGTH = 10;
    protected static final int MIN_PIN_LENGTH = 1;

    protected int pinLength;
    protected EditText mText;

    public PinCodeView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PinCodeView);
        try {
            pinLength = a.getInt(R.styleable.PinCodeView_pinLength, 0);
        } finally {
            a.recycle();
        }

        pinLength = Math.min(pinLength, MAX_PIN_LENGTH);
        pinLength = Math.max(pinLength, MIN_PIN_LENGTH);

        setupViews();

        Log.d(TAG, "PinCodeView initialized with pinLength = " + pinLength);
    }

    private void setupViews() {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        for (int i = 0; i < pinLength; i++) {
            // inflate an ImageView and add it
            View child = inflater.inflate(R.layout.pin_box, null, false);
            addView(child);
        }
    }

    public CharSequence getText() {
        // TODO return pin code text instead
        return null;
    }

    public int length() {
        // TODO return length of typed pin instead
        return pinLength;
    }

    @Override
    public boolean onCheckIsTextEditor() {
        return true;
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        // TODO return an InputConnection
        return null;
    }
}

About these overrides: onCheckIsTextEditor () should return true and onCreateInputConnection (EditorInfo outAttrs) should return a new object InputConnectionto interact with InputMethod (keyboard), but that's all I know.

Does anyone know if I'm on the right track? Has anyone worked with InputConnectionbefore or made their own editable representations that can give directions?

(Edit 1) Having looked at this a little more, it seems that I should subclass BaseInputConnection and set as a target TextViewor EditText:

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        if (!onCheckIsTextEditor()) {
            return null;
        }
        return new BaseInputConnection(mText, true);
    }

, , - , ...

( 2) . , , . , / , , OnFocusChangedListener logcat.

, ?

+5
4

InputConnection. , BaseInputConnection getEditable(), . TextView, PinCodeView. PinCodeView , onKey[foo](), TextView. TextWatcher ImageView , .

. , , .

0

Looks nice. Something you might want to do is when the user enters a character into one EditText, find the link to the next EditText field and do requestFocus()it. This will move the text entry to the next square. Very simple.

+1
source

All Articles