自定义 Android 密码输入小部件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10528592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom Android pin code entry widget
提问by Karakuri
I am trying to create a custom pin code widget for android as an alternative to just using an EditText
with a password inputType attribute. What I'd like to display is a row of boxes, and have each box be filled as the user types his pin.
我正在尝试为 android 创建一个自定义 pin 码小部件,作为仅使用EditText
带有密码 inputType 属性的替代方法。我想要显示的是一行框,并在用户输入他的 pin 时填充每个框。
Someone else did something like this but it turned out to be a fixed number of EditText
views and there was a lot of uglycode for swapping focus as characters were typed or deleted. This is NOT the approach I want to take; rather, I'm designing mine to have customizable length(easy) and behave as a single focusable view(not so easy).
其他人做了类似的事情,但结果是固定数量的EditText
视图,并且有很多丑陋的代码用于在键入或删除字符时交换焦点。这不是我想要采取的方法;相反,我正在设计我的具有可自定义长度(容易)并且表现为单个可聚焦视图(不是那么容易)。
My concept thus far is some kind of hybrid between a LinearLayout
(to hold the "boxes") and an EditText
(to store the user's input).
到目前为止,我的概念是 a LinearLayout
(保存“盒子”)和 an EditText
(存储用户输入)之间的某种混合。
This is the code so far...
这是到目前为止的代码...
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;
}
}
About those overrides: onCheckIsTextEditor()should return true and onCreateInputConnection(EditorInfo outAttrs)should return a new InputConnection
object to interact with an InputMethod (a keyboard), but that's all I know.
关于这些覆盖:onCheckIsTextEditor()应该返回 true 并且onCreateInputConnection(EditorInfo outAttrs)应该返回一个新InputConnection
对象以与 InputMethod (键盘)交互,但这就是我所知道的。
Does anyone know if I'm on the right track? Has anyone done work with InputConnection
before or made their own editable views able to give guidance?
有谁知道我是否在正确的轨道上?有没有人InputConnection
以前做过工作或制作过自己的可编辑视图来提供指导?
(Edit 1)
After looking at this some more, it seems I should subclass BaseInputConnection and supply a TextView
or EditText
as its target:
(编辑 1)在查看更多内容后,似乎我应该将 BaseInputConnection 子类化并提供 a TextView
orEditText
作为其目标:
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (!onCheckIsTextEditor()) {
return null;
}
return new BaseInputConnection(mText, true);
}
Assuming this does store the text as it is typed, I still need some way to update the views to reflect the content change...
假设这确实存储了键入的文本,我仍然需要某种方式来更新视图以反映内容更改...
(Edit 2)
So I added this custom view to a screen for testing. It shows the number of boxes, and the whole view is focusable, but the keyboard never pops up. I know it gains/loses focus because the boxes show highlighting appropriately and I set an OnFocusChangedListener
to write to logcat.
(编辑 2)所以我将此自定义视图添加到屏幕进行测试。它显示了框的数量,并且整个视图是可聚焦的,但是键盘永远不会弹出。我知道它获得/失去焦点,因为这些框适当地显示突出显示并且我设置了OnFocusChangedListener
写入 logcat。
What makes an actual keyboard appear when an editable view takes focus?
当可编辑视图获得焦点时,是什么使实际键盘出现?
采纳答案by Karakuri
I've made considerable progress on this and no longer need help with the InputConnection. In short, you extend BaseInputConnection
and override getEditable()
to return an Editable. In this case, I'm returning a private TextView
used internally by the PinCodeView
. PinCodeView
is also overriding several methods like onKey[foo]()
and forwarding the call to the internal TextView
. The rest is just using a TextWatcher
to update one of the child ImageView
s whenever the text changes.
我在这方面取得了相当大的进步,不再需要 InputConnection 的帮助。简而言之,您扩展BaseInputConnection
和覆盖getEditable()
以返回可编辑。在这种情况下,我回送一个专用TextView
由内部使用PinCodeView
。PinCodeView
还覆盖了几种方法,例如onKey[foo]()
将调用转发到内部TextView
。其余的只是在文本更改时使用 aTextWatcher
来更新 child 之一ImageView
。
It works really well. There are still a few minor issues left to polish it up, but I'll address those as separate questions and close this here.
它真的很好用。还有一些小问题需要完善,但我会将它们作为单独的问题解决并在此处结束。
回答by ChinLoong
It seems like you might be trying to create an iOS like pin entry view/widget.
看起来您可能正在尝试创建一个类似于 pin 条目视图/小部件的 iOS。
Here is a good sample code you may find useful. However, it is fix length, but still maybe useful to some people.
这是一个很好的示例代码,您可能会发现它很有用。但是,它是固定长度的,但对某些人来说可能仍然有用。
https://github.com/chinloong/Android-PinView
https://github.com/chinloong/Android-PinView
http://madeveloper.blogspot.com/2013/02/android-ios-like-pin-entrychallenge.html
http://madeveloper.blogspot.com/2013/02/android-ios-like-pin-entrychallenge.html
回答by Gaurav Sarma
I know this has already been answered but since its implementation is not shared i found a similar open source library. It looks good and for all those who wandering can give it try
我知道这已经得到了回答,但由于它的实现不是共享的,我发现了一个类似的开源库。看起来不错,所有流浪的人都可以尝试一下
回答by James Cross
Looks ok to me. Something you might want to do is when a user types a character into one EditText
box, find a reference to the next EditText box and do a requestFocus()
on it. This will move the text entry onto the next box. Very simple.
对我来说看起来没问题。您可能想要做的事情是当用户在一个EditText
框中键入一个字符时,找到对下一个 EditText 框的引用并requestFocus()
对其进行操作。这会将文本条目移动到下一个框。很简单。
回答by ishika vaghasiya
implementation 'com.alimuzaffar.lib:pinentryedittext:1.3.10'
Put this dependency in your app module Gradle file and sync.
将此依赖项放在您的应用模块 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"/>
Put this code in XML (layout file).
It works perfectly I use this code
将此代码放在 XML(布局文件)中。
它完美地工作我使用此代码