自定义Android pin码输入小部件

Kar*_*uri 5 android widget

我正在尝试为android创建一个自定义pin代码小部件,作为仅使用EditText带有密码inputType属性的替代方法.我想要显示的是一排盒子,并在用户键入其针脚时填充每个盒子.

其他人做了类似这样的事情,但事实证明这是一个固定数量的EditText视图,并且当字符被输入或删除时,有很多丑陋的代码用于交换焦点.这不是我想采取的方法; 相反,我正在设计我的可定制长度(简单)并且表现为单一的可聚焦视图(不那么容易).

到目前为止,我的概念是LinearLayout(保持"盒子")和EditText(存储用户输入)之间的某种混合.

到目前为止这是代码......

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

关于那些覆盖:onCheckIsTextEditor()应该返回true并且onCreateInputConnection(EditorInfo outAttrs)应该返回一个InputConnection与InputMethod(键盘)交互的新对象,但这就是我所知道的.

有谁知道我是否走在正确的轨道上?有没有人InputConnection以前做过工作或制作自己的可编辑视图能够提供指导?

(编辑1)在看了这个之后,似乎我应该继承BaseInputConnection并提供一个TextViewEditText作为其目标:

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

假设这确实存储了键入的文本,我仍然需要一些方法来更新视图以反映内容更改...

(编辑2)所以我将这个自定义视图添加到屏幕进行测试.它显示了盒子的数量,整个视图是可聚焦的,但键盘永远不会弹出.我知道它获得/失去焦点,因为框显示适当的突出显示,我设置了OnFocusChangedListener写入logcat.

当可编辑视图成为焦点时,实际键盘出现的原因是什么?

Kar*_*uri 0

我在这方面已经取得了相当大的进步,不再需要输入连接方面的帮助。简而言之,您扩展BaseInputConnection并重写getEditable()以返回可编辑的。在本例中,我TextView返回PinCodeView. PinCodeView还重写了几个方法,例如onKey[foo]()并将调用转发到内部TextView。剩下的就是在文本发生变化时使用 aTextWatcher来更新其中一个子级。ImageView

效果非常好。仍有一些小问题需要完善,但我将把这些问题作为单独的问题来解决,并在此结束。

  • 如果您觉得慷慨,那么如果将此代码发布到 github 上就太好了。感谢您发帖! (7认同)