言简意赅直奔主题!
项目有需求用户输入身份证的时候数字英文来回切不方便搞个自定义键盘吧
确实不方便输入完数字还要切回去输入英文,有的身份证最后一位是X
说干就干直接自定义View集成KeyboardView 好家伙 过时了!好吧反正也是就输入数字和X 用KeyboardView写本来就不少 那就自己画吧...
这是画完的效果
贴下代码吧 虽然你们可能也不会用毕竟太丑了
主要就是最外层设置focusableInTouchMode属性让页面进入的时候先不要获取焦点
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
tools:context=".ui.KeyBoardActivity">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/mSystemET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="系统键盘输入"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/mCustomET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="自定义键盘输入"
android:maxLength="18"
app:layout_constraintTop_toBottomOf="@id/mSystemET" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/mKeyBoardCL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/one"
style="@style/keyboardItem"
android:text="1" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/two"
style="@style/keyboardItem"
android:text="2" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/three"
style="@style/keyboardItem"
android:text="3" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/four"
style="@style/keyboardItem"
android:text="4" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/five"
style="@style/keyboardItem"
android:text="5" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/six"
style="@style/keyboardItem"
android:text="6" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/seven"
style="@style/keyboardItem"
android:text="7" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/eight"
style="@style/keyboardItem"
android:text="8" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/nine"
style="@style/keyboardItem"
android:text="9" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/x"
style="@style/keyboardItem"
android:text="X" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/zero"
style="@style/keyboardItem"
android:text="0" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/delete"
style="@style/keyboardItem"
android:background="@android:color/holo_red_light"
android:text="DEL" />
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/mKeyBoardFlow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="100dp"
app:constraint_referenced_ids="one,two,three,four,five,six,seven,eight,nine,x,zero,delete"
app:flow_maxElementsWrap="3"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/mCloseKB"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_green_light"
android:gravity="center"
android:text="关闭"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/mKeyBoardFlow"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
style里面配置了公用的属性
<style name="keyboardItem">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">60dp</item>
<item name="android:gravity">center</item>
<item name="android:background">@android:color/holo_blue_light</item>
<item name="android:textColor">@android:color/white</item>
</style>
接着就是在我们的Activity中设置一些键盘的展示和隐藏的逻辑
// 设置我们的自定义键盘所搭配的EditText不会弹出系统键盘
mBinding.mCustomET.showSoftInputOnFocus = false
mBinding.mCustomET.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
//自定义键盘输入框获取焦点的时候隐藏系统软键盘并展示我们自己的键盘
hideSoftKeyboard(this)
mBinding.mKeyBoardCL.visibility = View.VISIBLE
} else {
//失去焦点的时候把我们的键盘也隐藏掉
mBinding.mKeyBoardCL.visibility = View.GONE
}
}
mBinding.mCustomET.setOnClickListener {
//当输入框被点击的时候展示我们的软键盘
mBinding.mKeyBoardCL.visibility = View.VISIBLE
}
隐藏系统键盘的方法
private fun hideSoftKeyboard(activity: Activity) {
val view: View? = activity.currentFocus
if (view != null) {
val inputMethodManager = activity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(
view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
}
接下来处理我们的点击事件
//根据点击的按钮如果是数字和X就是增加X则为删除
mBinding.mKeyBoardCL.children.forEach {
if (it is TextView) {
it.setOnClickListener { _ ->
when (it.text.toString()) {
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "X" -> {
keyboardAdd(it.text.toString())
}
"DEL" -> {
keyboardRemove()
}
"关闭" -> {
mBinding.mKeyBoardCL.visibility = View.GONE
}
}
}
}
}
插入的方法
/** * 增加字符 */
private fun keyboardAdd(str: String) {
// 当前文字
val currentText = StringBuilder(mBinding.mCustomET.text.toString())
// 身份证输入满18位禁止输入
if (currentText.length >= 18) return
// 当前游标位置
val currentIndex = mBinding.mCustomET.selectionStart
var inputFlag = true
// X只允许出现在18位
if (str == "X" && currentIndex != 17) {
inputFlag = false
}
if (inputFlag) {
currentText.insert(currentIndex, str)
mBinding.mCustomET.text = Editable.Factory.getInstance().newEditable(currentText.toString())
mBinding.mCustomET.setSelection(currentIndex + 1)
}
}
删除字符的方法
/*** 移除字符*/
private fun keyboardRemove() {
// 当前文字
val currentText = StringBuilder(mBinding.mCustomET.text.toString())
// 当前游标位置
val currentIndex = mBinding.mCustomET.selectionStart
// 文字判空 并且游标不在最前端
if (currentText.isNotEmpty() && currentIndex != 0) {
// 删除游标前一个字符
currentText.deleteCharAt(currentIndex - 1)
// 为EditText赋值
mBinding.mCustomET.text = Editable.Factory.getInstance().newEditable(currentText.toString())
// 游标往前移动一格
mBinding.mCustomET.setSelection(currentIndex - 1)
}
}
完结散花
下面按照惯例放出Activity完整代码
class KeyBoardActivity : BaseActivityV2<ActivityKeyBoardBinding>() {
override fun event() {
mBinding.mKeyBoardCL.visibility = View.GONE
// 设置我们的自定义键盘所搭配的EditText不会弹出系统键盘
mBinding.mCustomET.showSoftInputOnFocus = false
mBinding.mCustomET.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
// 自定义键盘输入框获取焦点的时候隐藏系统软键盘并展示我们自己的键盘
hideSoftKeyboard(this)
mBinding.mKeyBoardCL.visibility = View.VISIBLE
} else {
// 失去焦点的时候把我们的键盘也隐藏掉
mBinding.mKeyBoardCL.visibility = View.GONE
}
}
mBinding.mCustomET.setOnClickListener {
// 当输入框被点击的时候展示我们的软键盘
mBinding.mKeyBoardCL.visibility = View.VISIBLE
}
}
override fun click() {
mBinding.mKeyBoardCL.children.forEach {
if (it is TextView) {
it.setOnClickListener { _ ->
when (it.text.toString()) {
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "X" -> {
keyboardAdd(it.text.toString())
}
"DEL" -> {
keyboardRemove()
}
"关闭" -> {
mBinding.mKeyBoardCL.visibility = View.GONE
}
}
}
}
}
}
/*** 移除字符*/
private fun keyboardRemove() {
// 当前文字
val currentText = StringBuilder(mBinding.mCustomET.text.toString())
// 当前游标位置
val currentIndex = mBinding.mCustomET.selectionStart
// 文字判空 并且游标不在最前端
if (currentText.isNotEmpty() && currentIndex != 0) {
// 删除游标前一个字符
currentText.deleteCharAt(currentIndex - 1)
// 为EditText赋值
mBinding.mCustomET.text = Editable.Factory.getInstance().newEditable(currentText.toString())
// 游标往前移动一格
mBinding.mCustomET.setSelection(currentIndex - 1)
}
}
/** * 增加字符 */
private fun keyboardAdd(str: String) {
// 当前文字
val currentText = StringBuilder(mBinding.mCustomET.text.toString())
// 身份证输入满18位禁止输入
if (currentText.length >= 18) return
// 当前游标位置
val currentIndex = mBinding.mCustomET.selectionStart
var inputFlag = true
// X只允许出现在18位
if (str == "X" && currentIndex != 17) {
inputFlag = false
}
if (inputFlag) {
currentText.insert(currentIndex, str)
mBinding.mCustomET.text = Editable.Factory.getInstance().newEditable(currentText.toString())
mBinding.mCustomET.setSelection(currentIndex + 1)
}
}
private fun hideSoftKeyboard(activity: Activity) {
val view: View? = activity.currentFocus
if (view != null) {
val inputMethodManager = activity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(
view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
}
}
网友评论