8

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

其他人做了类似的事情,但结果是固定数量的EditText视图,并且有很多丑陋的代码用于在输入或删除字符时交换焦点。这不是我想要采取的方法;相反,我将我的设计设计为具有可定制的长度(容易)并表现为单个可聚焦的视图(不太容易)。

LinearLayout到目前为止,我的概念是 a (保存“盒子”)和 an 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;
    }
}

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

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

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

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

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

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

当可编辑视图获得焦点时,是什么让实际的键盘出现?

4

5 回答 5

4

看起来您可能正在尝试创建一个类似 pin 条目视图/小部件的 iOS。

这是一个很好的示例代码,您可能会发现它很有用。然而,它是固定长度的,但对某些人来说仍然可能有用。

https://github.com/chinloong/Android-PinView

http://madeveloper.blogspot.com/2013/02/android-ios-like-pin-entrychallenge.html

于 2013-02-08T06:59:21.740 回答
2

我知道这已经得到了回答,但由于它的实现不是共享的,我找到了一个类似的开源库。它看起来不错,所有徘徊的人都可以尝试一下

https://github.com/Philio/PinEntryView

于 2016-12-08T15:58:31.227 回答
1

在我看来还可以。您可能想要做的事情是,当用户在一个EditText框中键入一个字符时,找到对下一个 EditText 框的引用并requestFocus()对其执行操作。这会将文本条目移动到下一个框。非常简单。

于 2012-05-10T07:40:08.737 回答
0

我在这方面取得了相当大的进展,不再需要 InputConnection 的帮助。简而言之,您扩展BaseInputConnection并覆盖getEditable()以返回可编辑的。在这种情况下,我将返回一个TextViewPinCodeView. PinCodeView还覆盖了几种方法,例如onKey[foo]()并将调用转发到 internal TextView。其余的只是在文本更改时使用 aTextWatcher来更新其中一个子s。ImageView

它真的很好用。还有一些小问题需要完善,但我会将这些问题作为单独的问题解决并在此处关闭。

于 2012-05-12T02:45:36.593 回答
0
implementation 'com.alimuzaffar.lib:pinentryedittext:1.3.10'

将此依赖项放入您的应用程序模块 Gradle 文件并同步。

    <com.alimuzaffar.lib.pin.PinEntryEditText

                    android:inputType="number"
                    android:id="@+id/Pin_Et"
                    android:maxLength="6"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

将此代码放在 XML(布局文件)中。
它完美地工作我使用这个代码

于 2020-03-20T07:04:42.717 回答