8

EditTextパスワードinputType属性を使用する代わりに、Android用のカスタムPINコードウィジェットを作成しようとしています。表示したいのはボックスの行で、ユーザーがピンを入力すると各ボックスが埋められます。

他の誰かがこのようなことをしましたが、固定数のビューであることが判明し、文字が入力または削除されたときにフォーカスを切り替えるための醜い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;
    }
}

これらのオーバーライドについて: 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) そこで、このカスタム ビューをテスト用の画面に追加しました。ボックスの数が表示され、ビュー全体がフォーカス可能ですが、キーボードがポップアップすることはありません。ボックスが適切に強調表示され、OnFocusChangedListenerlogcat に書き込むように設定されているため、フォーカスが得られたり失われたりすることがわかっています。

編集可能なビューがフォーカスされたときに実際のキーボードが表示されるのはなぜですか?

4

5 に答える 5

4

ピン エントリ ビュー/ウィジェットのような 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

私には大丈夫に見えます。ユーザーが 1 つのEditTextボックスに文字を入力したときに、次の EditText ボックスへの参照を見つけて、それに対して を実行したい場合がありrequestFocus()ます。これにより、テキスト エントリが次のボックスに移動します。とてもシンプルです。

于 2012-05-10T07:40:08.737 に答える
0

私はこれについてかなりの進歩を遂げており、InputConnection のサポートはもう必要ありません。つまり、編集可能を返すように拡張BaseInputConnectionおよびオーバーライドします。getEditable()この場合、TextViewによって内部的に使用されるプライベートを返していPinCodeViewます。また、呼び出しを internal に転送するPinCodeViewなどのいくつかのメソッドをオーバーライドしています。残りは、テキストが変更されるたびに a を使用して子の 1 つを更新するだけです。onKey[foo]()TextViewTextWatcherImageView

それは本当にうまくいきます。磨き上げるためにいくつかの小さな問題が残っていますが、それらは別の質問として扱い、ここで締めくくります。

于 2012-05-12T02:45:36.593 に答える