我正在尝试为Android创建一个自定义PIN码小部件,作为仅使用带有密码inputType属性的EditText
的替代方法。我想要显示的是一排盒子,每个盒子都会在用户输入其针脚时填充。
其他人做了类似这样的事情,但事实证明这是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。
当可编辑视图成为焦点时,实际键盘出现的原因是什么?
答案 0 :(得分:4)
似乎您可能正在尝试创建类似针入口视图/窗口小部件的iOS。
这是一个很有用的示例代码。但是,它是固定长度,但对某些人来说仍然有用。
https://github.com/chinloong/Android-PinView
http://madeveloper.blogspot.com/2013/02/android-ios-like-pin-entrychallenge.html
答案 1 :(得分:2)
我知道这已经得到了解答,但由于它的实现没有共享,我发现了一个类似的开源库。它看起来不错,对于所有流浪的人都可以试试
答案 2 :(得分:1)
对我来说没问题。您可能想要做的事情是当用户在一个EditText
框中键入一个字符时,找到对下一个EditText框的引用并对其执行requestFocus()
。这会将文本条目移动到下一个框中。非常简单。
答案 3 :(得分:0)
我在此方面取得了相当大的进展,不再需要有关InputConnection的帮助。简而言之,您扩展BaseInputConnection
并覆盖getEditable()
以返回可编辑。在这种情况下,我将返回TextView
内部使用的私有PinCodeView
。 PinCodeView
也覆盖了onKey[foo]()
等多种方法,并将调用转发给内部TextView
。其余的只是在文本发生变化时使用TextWatcher
更新其中一个子ImageView
。
效果很好。还有一些小问题需要加以改进,但我会将这些问题作为单独的问题来解决,并在此处关闭。
答案 4 :(得分: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(布局文件)中。
使用此代码,效果很好