Вопрос по android – Пользовательский виджет ввода пин-кода Android

5

Я пытаюсь создать собственный виджет пин-кода для Android в качестве альтернативы просто использоватьEditText с атрибутом ввода пароля типа. То, что я хотел бы отобразить, это ряд ячеек, и каждый из них должен быть заполнен, когда пользователь вводит свой пин-код.

Кто-то сделал что-то подобное, но оказалось, что это фиксированное числоEditText просмотров и там было многоugly код для смены фокуса при вводе или удалении символов. Это НЕ подход, который я хочу использовать; скорее я проектирую мой, чтобы иметьcustomizable length (легко) и вести себя какsingle focusable view (не просто).

Моя концепция до сих пор является своего рода гибридом междуLinearLayout (чтобы держать "коробки") иEditText (чтобы сохранить ввод пользователя).

Это код до сих пор ...

<code>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;
    }
}
</code>

О тех переопределениях:onCheckIsTextEditor () должен вернуть истину иonCreateInputConnection (EditorInfo outAttrs) должен вернуть новыйInputConnection объект для взаимодействия с InputMethod (клавиатурой), но это все, что я знаю.

Кто-нибудь знает, нахожусь ли я на правильном пути? Кто-нибудь сделал работу сInputConnection раньше или сделали свои собственные редактируемые представления способными дать руководство?

(Изменить 1) Посмотрев на это еще немного, кажется, я должен подкласс BaseInputConnection и предоставитьTextView или жеEditText как его цель:

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

Предполагая, что это сохраняет текст в том виде, в котором он напечатан, мне все еще нужен какой-то способ обновить представления, чтобы отразить изменение содержимого ...

(Изменить 2) Поэтому я добавил этот пользовательский вид на экран для тестирования. Он показывает количество блоков, и весь вид можно сфокусировать, но клавиатура никогда не всплывает. Я знаю, что он получает / теряет фокус, потому что поля показывают выделение соответствующим образом, и я установилOnFocusChangedListener написать в logcat.

Что заставляет настоящую клавиатуру появляться, когда редактируемый вид фокусируется?

Ваш Ответ

4   ответа
4

Вот хороший пример кода, который вам может пригодиться. Тем не менее, это фиксированная длина, но все же может быть полезно для некоторых людей.

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

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

Я ценю ваш вклад, и он может быть полезен для других, но я уже разработал решение самостоятельно. Мой обычайView, который инкапсулирует весь ряд блоков, взаимодействует с клавиатурой Android и управляет всей логикой. Это не требует целого действия с полным макетом кнопок и текстовых представлений. Karakuri
@ Karakuri Поскольку вы не предоставили исходный код или подробные инструкции, этот ответ для ввода пин-кода для меня более актуален. Gordon Freeman
1

когда пользователь вводит символ в одинEditText box, найдите ссылку на следующее окно EditText и сделайтеreq,uestFocus() в теме. Это переместит текстовую запись в следующее поле. Очень просто

Такого рода вещи я стараюсь избегать. Весь виджет должен быть фокусируемым, а не отдельные поля. Karakuri
Для того, чтобы в них напечатать, нужно сфокусировать отдельные поля. Кроме того, EditText, который находится в фокусе, будет иметь синюю линию вокруг него, показывая пользователю, что он может принимать данные. Без этой визуальной подсказки пользователь не будет знать, куда идут его набранные символы. James Cross
Возможно, это было неясно, но я НЕ использую строку EditTexts и НЕ хочу, чтобы каждое поле было фокусируемым по отдельности. Как я уже упоминал, я видел код для этого, и он грязный, безобразный и блеклый. Этот подход надувает ImageViews для блоков, и они будут иметь селектор, который можно нарисовать в качестве фона, и имеют duplicateParentState = "true", чтобы они отображали состояние фокусировки, когда виджет находится в фокусе. Но ключ в том, что ВЕСЬ виджет получает фокус, а не отдельные поля. Karakuri
Хорошо, честно. Я понятия не имею, почему вы хотели бы сделать это. Для Android я подумал, что когда у родителя есть сфокусированный дочерний элемент (т. Е. Один из полей EditText имеет фокус), то родительский элемент также считается сфокусированным. Кроме того, я не могу представить, что код для этого является грязным, я уверен, что для этого потребуется всего несколько строк. Удачи, и я думаю, что вы должны определить свой вопрос немного больше, чтобы не сбивать с толку. James Cross
Часть этого - эстетика, и часть этого - функция / поведение. Создание каждого фокуса означает, что пользователь может перейти к любому блоку, но это виджет пин-кода, поэтому фактическое содержимое в любом случае скрыто. Если хотите, я мог бы поделиться с вами кодом, который использует EditTexts. Karakuri
2

что на этот вопрос уже дан ответ, но поскольку его реализация не передана, я нашел похожую библиотеку с открытым исходным кодом. Это выглядит хорошо и для всех тех, кто бродит, может дать ему попробовать

https: //github.com/Philio/PinEntryVie

0

в помощи с InputConnection. Короче говоря, вы продлитеBaseInputConnection и переопределитьgetEditable() чтобы вернуть редактируемый. В этом случае я возвращаю личноеTextView используется внутриPinCodeView. PinCodeView также переопределяет несколько методов, таких какonKey[foo]() и переадресация звонка на внутреннийTextView. Остальное просто с помощьюTextWatcher чтобы обновить одного из детейImageViews всякий раз, когда текст меняется.

Это действительно хорошо работает. Осталось еще несколько незначительных проблем, чтобы исправить это, но я рассмотрю их как отдельные вопросы и закрою здесь.

Если вы чувствуете себя щедрым, было бы здорово, если бы этот код был доступен на github. Спасибо за публикацию! saranicole
Любое обновление о выпуске этого на github или если кто-то еще достиг такого прогресса? Код, показанный здесь, выглядит действительно многообещающе и является хорошей отправной точкой для других, хотя я действительно оценил бы весь пакет. Может быть, Android в конечном итоге реализует это как другой тип поля:) Joris Kroos
Я бы очень хотел, но он используется в приложении моей компании, поэтому я не знаю, смогу ли я выпустить исходный код для него. Позвольте мне проверить это с моим менеджером. Karakuri

Похожие вопросы