我做了我的自定义PIN码视图
class StarsPasswordView : LinearLayout {
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
init(context, attrs)
}
val passwordHolder = SpannableStringBuilder()
var count
fun init(context: Context, attrs: AttributeSet?) {
orientation = HORIZONTAL
isFocusable = true
isFocusableInTouchMode = true
gravity = Gravity.CENTER
val attr = context.obtainStyledAttributes(attrs, R.styleable.StarsPasswordView, 0, 0)
count = attr.getInteger(R.styleable.StarsPasswordView_count, 4)
attr.recycle()
drawView(count)
setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_ENTER)
return@OnKeyListener true
if (keyCode == KeyEvent.KEYCODE_BACK)
return@OnKeyListener false
if (keyCode == KeyEvent.KEYCODE_DEL) {
clear()
get(0).requestFocus()
} else
if (passwordHolder.length != count) {
passwordHolder.append(event.number)
val position = passwordHolder.length
select(position - 1)
if (position < count)
get(position).requestFocus()
else {
passwordFilled?.invoke(passwordHolder.toString())
}
}
return@OnKeyListener true
}
false
})
}
fun samsungWorkaround() {
val position = passwordHolder.length
select(position - 1)
if (position == count)
passwordFilled?.invoke(passwordHolder.toString())
}
}
// toggle whether the keyboard is showing when the view is clicked
override fun onTouchEvent(event: MotionEvent): Boolean {
if (enableKeyboard && event.action == MotionEvent.ACTION_UP) {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY)
}
return true
}
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
return InputConnection(this, true)
}
}
class InputConnection internal constructor(val targetView: StarsPasswordView, fullEditor: Boolean) : BaseInputConnection(targetView, fullEditor) {
override fun getEditable(): Editable {
return targetView.passwordHolder
}
override fun commitText(text: CharSequence?, newCursorPosition: Int): Boolean {
val res = super.commitText(text, newCursorPosition)
targetView.samsungWorkaround()
return res
}
}
当您想要设置
时会出现问题 outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
在这种情况下
InputConnection
无法处理数字commitText()不会触发
所以我的解决方法只是处理setOnKeyListener中的麻木,如上所示。
有谁知道这是什么问题?
答案 0 :(得分:2)
根据键盘的不同,并非所有密钥都通过InputConnection
发送。有些是像硬键事件一样发送的,必须单独处理。这包括标准键盘上的数字键盘编号。就我目前所知,使用OnKeyListener
就像你要做的那样(但请参阅@ pskink的评论here)。
您可以使用KeyEvent.getUnicodeChar()
将文本字符与控制字符分开,如下所示。
if (keyEvent.getUnicodeChar() != 0) {
// unicode text
char unicodeChar = (char) keyEvent.getUnicodeChar();
} else {
// control char
}
处理您需要的控制代码,但将捕获所有有效的Unicode字符(包括数字和新行(输入)字符)。
我在准备回答这个问题时写的问题和答案中更详细地介绍了这方面的一些方面。
我还更新了my previous answer关于接收键盘输入的自定义视图。