Я пытаюсь создать собственный виджет пин-кода для Android в качестве альтернативы простому использованию 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;
}
}
Об этих переопределениях: onCheckIsTextEditor()должен возвращать true и onCreateInputConnection(EditorInfo outAttrs)должен возвращать новый InputConnection
для взаимодействия с InputMethod (клавиатурой), но это все, что я знаю.
Кто-нибудь знает, на правильном ли я пути? Кто-нибудь работал с InputConnection
раньше или делал свои собственные редактируемые представления, способные давать рекомендации?
(Редактировать 1)
Посмотрев на это еще немного, кажется, что я должен подклассировать BaseInputConnection и указать TextView
или EditText
в качестве цели:
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (!onCheckIsTextEditor()) {
return null;
}
return new BaseInputConnection(mText, true);
}
Предполагая, что это сохраняет текст в том виде, в котором он напечатан, все еще нужен какой-то способ обновить представления, чтобы отразить изменение содержимого...
(Редактировать 2)
Поэтому я добавил этот пользовательский вид на экран для тестирования. Он показывает количество полей, и весь вид можно сфокусировать, но клавиатура никогда не появляется.Я знаю, что он получает/теряет фокус, потому что поля правильно подсвечены, и я установил OnFocusChangedListener
для записи в logcat.
Из-за чего появляется реальная клавиатура, когда редактируемый вид получает фокус?