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

相关推荐
千里马学框架7 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台7 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone7 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc8 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo9 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770010 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼11 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone12 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen12 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone12 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui