Android 自定义键盘

过时了

言简意赅直奔主题!

项目有需求用户输入身份证的时候数字英文来回切不方便搞个自定义键盘吧

确实不方便输入完数字还要切回去输入英文,有的身份证最后一位是X

说干就干直接自定义View集成KeyboardView 好家伙 过时了!好吧反正也是就输入数字和X 用KeyboardView写本来就不少 那就自己画吧...

这是画完的效果

贴下代码吧 虽然你们可能也不会用毕竟太丑了

主要就是最外层设置focusableInTouchMode属性让页面进入的时候先不要获取焦点```

ini 复制代码
<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里面配置了公用的属性

<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>

复制代码
接着就是在我们的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) } }

less 复制代码
完结散花

  

![](https://upload-images.jianshu.io/upload_images/13649967-f7c03d52fad91be9.gif)

  

下面按照惯例放出Activity完整代码

class KeyBoardActivity : BaseActivityV2() { override fun event() { mBinding.mKeyBoardCL.visibility = View.GONE // 设置我们的自定义键盘所搭配的EditText不会弹出系统键盘 mBinding.mCustomET.showSoftInputOnFocus = false

ini 复制代码
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) } } }

相关推荐
sun0077007 小时前
android ndk编译valgrind
android
AI视觉网奇9 小时前
android studio 断点无效
android·ide·android studio
jiaxi的天空9 小时前
android studio gradle 访问不了
android·ide·android studio
No Silver Bullet10 小时前
android组包时会把从maven私服获取的包下载到本地吗
android
catchadmin10 小时前
PHP serialize 序列化完全指南
android·开发语言·php
tangweiguo0305198711 小时前
Kable使用指南:Android BLE开发的现代化解决方案
android·kotlin
00后程序员张13 小时前
iOS App 混淆与资源保护:iOS配置文件加密、ipa文件安全、代码与多媒体资源防护全流程指南
android·安全·ios·小程序·uni-app·cocoa·iphone
柳岸风15 小时前
Android Studio Meerkat | 2024.3.1 Gradle Tasks不展示
android·ide·android studio
编程乐学15 小时前
安卓原创--基于 Android 开发的菜单管理系统
android
whatever who cares17 小时前
android中ViewModel 和 onSaveInstanceState 的最佳使用方法
android