android 自定义车牌键盘(kotlin)

  • 前言
  • 示例图
  • 实现需求
  • 定义键盘文件
  • 核心代码
  • 视频效果
  • 汉字转化
  • 项目链接

前言

平时停车缴费都要填车牌号码,就想着自己能不能也做个车牌键盘demo。
自定义车牌键盘能满足(普通车牌,新能源,警车,军车,领事馆车,教练车以及特种车辆等车牌)

示例图


实现需求

1、车牌前两位默认是:粤A

2、第一个控件,默认是省份键盘

3、剩下控件,默认是abc键盘

4、当前输入框输完后能自动跳转到下个控件

5、当前输入框有选中背景,其他的没有

定义键盘文件

在res文件夹下创建xml文件夹,创建省份键盘(province.xml)和abc键盘(abc.xml)

province.xml

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"android:horizontalGap="1%p"android:keyWidth="10%p"android:keyHeight="8%p"android:verticalGap="0.0px"><Row android:verticalGap="1%p"><Keyandroid:codes="20140"android:keyLabel="" /><Keyandroid:codes="27941"android:keyLabel="" /><Keyandroid:codes="20864"android:keyLabel="" /><Keyandroid:codes="40065"android:keyLabel="" /><Keyandroid:codes="26187"android:keyLabel="" /><Keyandroid:codes="33945"android:keyLabel="" /><Keyandroid:codes="36797"android:keyLabel="" /><Keyandroid:codes="21513"android:keyLabel="" /><Keyandroid:codes="40657"android:keyLabel="" /><Keyandroid:codes="27818"android:keyLabel="" /></Row><Row android:verticalGap="1%p"><Keyandroid:codes="33487"android:keyLabel="" /><Keyandroid:codes="27993"android:keyLabel="" /><Keyandroid:codes="30358"android:keyLabel="" /><Keyandroid:codes="38397"android:keyLabel="" /><Keyandroid:codes="36195"android:keyLabel="" /><Keyandroid:codes="35947"android:keyLabel="" /><Keyandroid:codes="37122"android:keyLabel="" /><Keyandroid:codes="28248"android:keyLabel="" /><Keyandroid:codes="31908"android:keyLabel="" /><Keyandroid:codes="26690"android:keyLabel="" /></Row><Row android:verticalGap="1%p"><Keyandroid:codes="28189"android:keyLabel="" /><Keyandroid:codes="24029"android:keyLabel="" /><Keyandroid:codes="36149"android:keyLabel="" /><Keyandroid:codes="20113"android:keyLabel="" /><Keyandroid:codes="34255"android:keyLabel="" /><Keyandroid:codes="38485"android:keyLabel="" /><Keyandroid:codes="29976"android:keyLabel="" /><Keyandroid:codes="38738"android:keyLabel="" /><Keyandroid:codes="29756"android:keyLabel="" /><Keyandroid:codes="26032"android:keyLabel="" /></Row><Row><Keyandroid:codes="-1"android:isModifier="true"android:isSticky="true"android:keyWidth="10%p"android:keyLabel="ABC" /><Keyandroid:codes="23425"android:keyLabel="" /><Keyandroid:codes="20351"android:keyLabel="使" /><Keyandroid:codes="39046"android:keyLabel="" /><Keyandroid:codes="35686"android:keyLabel="" /><Keyandroid:codes="23398"android:keyLabel="" /><Keyandroid:codes="28207"android:keyLabel="" /><Keyandroid:codes="28595"android:keyLabel="" />
<!--         注释台湾-->
<!--        <Key-->
<!--            android:codes="21488"-->
<!--            android:keyLabel="台" />--><Keyandroid:codes="-3"android:isRepeatable="false"android:keyWidth="10%p"android:keyLabel="删除" /></Row>
</Keyboard>

abc.xml

<?xml version="1.0" encoding="utf-8"?>
<Keyboard android:keyWidth="9%p" android:keyHeight="8%"android:horizontalGap="1%p" android:verticalGap="0.0px"xmlns:android="http://schemas.android.com/apk/res/android"><Row android:verticalGap="1%p"><Key android:codes="49" android:keyLabel="1"android:horizontalGap="1%p" android:keyWidth="8%p"  /><Key android:codes="50" android:keyLabel="2"/><Key android:codes="51" android:keyLabel="3"/><Key android:codes="52" android:keyLabel="4"/><Key android:codes="53" android:keyLabel="5"/><Key android:codes="54" android:keyLabel="6"/><Key android:codes="55" android:keyLabel="7"/><Key android:codes="56" android:keyLabel="8"/><Key android:codes="57" android:keyLabel="9"/><Key android:codes="48" android:keyLabel="0"/></Row><Row android:verticalGap="1%p"><Key android:codes="81" android:keyLabel="Q"android:horizontalGap="1%p" android:keyWidth="8%p"android:keyEdgeFlags="left" /><Key android:codes="87" android:keyLabel="W"/><Key android:codes="69" android:keyLabel="E"/><Key android:codes="82" android:keyLabel="R"/><Key android:codes="84" android:keyLabel="T"/><Key android:codes="89" android:keyLabel="Y"/><Key android:codes="85" android:keyLabel="U"/><Key android:codes="73" android:keyLabel="I"/><Key android:codes="79" android:keyLabel="O"/><Key android:codes="80" android:keyLabel="P"android:keyEdgeFlags="right" /></Row><Row android:verticalGap="1%p"><Key android:codes="65" android:keyLabel="A"android:horizontalGap="6%p" android:keyWidth="8%p"android:keyEdgeFlags="left"/><Key android:codes="83" android:keyLabel="S"/><Key android:codes="68" android:keyLabel="D"/><Key android:codes="70"  android:keyLabel="F"/><Key android:codes="71" android:keyLabel="G"/><Key android:codes="72"  android:keyLabel="H"/><Key android:codes="74" android:keyLabel="J"/><Key android:codes="75" android:keyLabel="K"/><Key android:codes="76"  android:keyLabel="L"android:keyEdgeFlags="right" /></Row><Row ><Key android:codes="-2"android:keyEdgeFlags="left" android:keyLabel="省份"android:horizontalGap="1%p" android:keyWidth="13%p"android:isModifier="true" android:isSticky="true"  /><Key android:codes="90" android:keyLabel="Z"/><Key android:codes="88" android:keyLabel="X"/><Key android:codes="67" android:keyLabel="C"/><Key android:codes="86" android:keyLabel="V"/><Key android:codes="66" android:keyLabel="B"/><Key android:codes="78" android:keyLabel="N"/><Key android:codes="77" android:keyLabel="M"/><Key  android:codes="-3"android:keyEdgeFlags="right" android:keyLabel="删除"android:horizontalGap="1.5%p" android:keyWidth="13%p"android:isRepeatable="false" /></Row>
</Keyboard>

核心代码

键盘工具类KeyboardUtil

package com.example.ktproject
import android.inputmethodservice.Keyboard
import android.inputmethodservice.KeyboardView
import android.text.InputType
import android.view.View
import android.view.WindowManager
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivityclass KeyboardUtil(private var activity: AppCompatActivity) {private var mKeyboardView: KeyboardViewprivate val provinceKeyboard: Keyboardprivate var abcKeyboard: Keyboardprivate var editText: EditText? = nullinit {// 省份键盘provinceKeyboard = Keyboard(activity, R.xml.province)// abc键盘abcKeyboard = Keyboard(activity, R.xml.abc)mKeyboardView = activity.findViewById(R.id.keyboard_view)mKeyboardView.apply {keyboard = provinceKeyboardisEnabled = true// 设置按键没有点击放大镜显示的效果isPreviewEnabled = falsesetOnKeyboardActionListener(object : KeyboardView.OnKeyboardActionListener {override fun onPress(primaryCode: Int) {}override fun onRelease(primaryCode: Int) {}override fun onText(text: CharSequence?) {}override fun swipeLeft() {}override fun swipeRight() {}override fun swipeDown() {}override fun swipeUp() {}override fun onKey(primaryCode: Int, keyCodes: IntArray?) {val editable = editText?.textval start: Int = editText?.selectionStart ?: 0when (primaryCode) {-1 -> changeKeyboard(true)-2 -> changeKeyboard(false)-3 -> {if (start != null) {editable?.delete(0, start)}}else -> {// 清空之前数据editText?.text?.clear()editable?.insert(0, primaryCode.toChar().toString())}}}})}}fun setEditText(editText: EditText) {this.editText = editText}/*** 指定切换软键盘* isNumber false 省份软键盘, true 数字字母软键盘*/fun changeKeyboard(isNumber: Boolean) {if (isNumber) {mKeyboardView.keyboard = abcKeyboard} else {mKeyboardView.keyboard = provinceKeyboard}}/*** 软键盘展示状态*/fun isShow() = mKeyboardView.visibility == View.VISIBLE/*** 显示软键盘*/fun showKeyboard() {val visibility = mKeyboardView.visibilityif (visibility == View.GONE || visibility == View.INVISIBLE) {mKeyboardView.visibility = View.VISIBLE}}/*** 隐藏软键盘*/fun hideKeyboard() {val visibility = mKeyboardView.visibilityif (visibility == View.VISIBLE) {mKeyboardView.visibility = View.INVISIBLE}}/*** 禁掉系统软键盘*/fun hideSoftInputMethod(editText: EditText) {activity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)editText.inputType = InputType.TYPE_NULL}
}

实现代码

package com.example.ktproject
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {private lateinit var keyboardUtil: KeyboardUtiloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 默认选中第三个控件keyboardUtil = KeyboardUtil(this)keyboardUtil.hideSoftInputMethod(et2)keyboardUtil.showKeyboard()keyboardUtil.setEditText(et2)keyboardUtil.changeKeyboard(true)et2.setBackgroundResource(R.drawable.shape_et_select)val etList = listOf(etProvince, et1, et2, et3, et4, et5, et6, et7)etProvince.setOnTouchListener(MyOnTouchListener(0, false, etList, keyboardUtil))et1.setOnTouchListener(MyOnTouchListener(1, true, etList, keyboardUtil))et2.setOnTouchListener(MyOnTouchListener(2, true, etList, keyboardUtil))et3.setOnTouchListener(MyOnTouchListener(3, true, etList, keyboardUtil))et4.setOnTouchListener(MyOnTouchListener(4, true, etList, keyboardUtil))et5.setOnTouchListener(MyOnTouchListener(5, true, etList, keyboardUtil))et6.setOnTouchListener(MyOnTouchListener(6, true, etList, keyboardUtil))et7.setOnTouchListener(MyOnTouchListener(7, true, etList, keyboardUtil))etProvince.addTextChangedListener(MyTextWatcher(etProvince, et1, true, keyboardUtil))et1.addTextChangedListener(MyTextWatcher(et1, et2, true, keyboardUtil))et2.addTextChangedListener(MyTextWatcher(et2, et3, true, keyboardUtil))et3.addTextChangedListener(MyTextWatcher(et3, et4, true, keyboardUtil))et4.addTextChangedListener(MyTextWatcher(et4, et5, true, keyboardUtil))et5.addTextChangedListener(MyTextWatcher(et5, et6, true, keyboardUtil))}class MyTextWatcher(private val curEditText: EditText,private val nextEditText: EditText,private val isNumber: Boolean,private val keyboardUtil: KeyboardUtil) : TextWatcher {override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}override fun afterTextChanged(s: Editable?) {s?.let {if (it.isNotEmpty()) {// 下个控件获取焦点nextEditText.requestFocus()nextEditText.setSelection(nextEditText.text.length)// 更新背景curEditText.setBackgroundResource(R.drawable.shape_et)nextEditText.setBackgroundResource(R.drawable.shape_et_select)// 切换键盘keyboardUtil.changeKeyboard(isNumber)keyboardUtil.setEditText(nextEditText)}}}}class MyOnTouchListener(private val index: Int,private val isNumber: Boolean,private val etList: List<EditText>,private val keyboardUtil: KeyboardUtil) : View.OnTouchListener {override fun onTouch(v: View?, event: MotionEvent?): Boolean {changeEditTextBg(index, etList)// 切换键盘keyboardUtil.hideSoftInputMethod(v as EditText)keyboardUtil.changeKeyboard(isNumber)keyboardUtil.setEditText(v)v.setSelection(v.text.length)return false}// 更新控件背景private fun changeEditTextBg(index: Int, etList: List<EditText>) {etList[0].setBackgroundResource((if (index == 0) R.drawable.shape_et_select else R.drawable.shape_et))etList[1].setBackgroundResource((if (index == 1) R.drawable.shape_et_select else R.drawable.shape_et))etList[2].setBackgroundResource((if (index == 2) R.drawable.shape_et_select else R.drawable.shape_et))etList[3].setBackgroundResource((if (index == 3) R.drawable.shape_et_select else R.drawable.shape_et))etList[4].setBackgroundResource((if (index == 4) R.drawable.shape_et_select else R.drawable.shape_et))etList[5].setBackgroundResource((if (index == 5) R.drawable.shape_et_select else R.drawable.shape_et))etList[6].setBackgroundResource((if (index == 6) R.drawable.shape_et_select else R.drawable.shape_et))etList[7].setBackgroundResource((if (index == 7) R.drawable.shape_et_select else R.drawable.shape_et_green))}}override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {if (keyCode == KeyEvent.KEYCODE_BACK) {if (keyboardUtil.isShow()) {keyboardUtil.hideKeyboard()} else {finish()}}return false}
}

布局文件

<?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"tools:context=".MainActivity"><TextViewandroid:id="@+id/tvTitle"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginTop="20dp"android:text="请输入您的车牌号码:"android:textColor="#000"android:textSize="20sp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><LinearLayoutandroid:id="@+id/carLayout"android:layout_width="match_parent"android:layout_height="60dp"android:orientation="horizontal"app:layout_constraintTop_toBottomOf="@id/tvTitle"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"android:layout_marginTop="12dp"><EditTextandroid:id="@+id/etProvince"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:text=""android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et1"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:text="A"android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et2"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et3"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et4"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et5"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et6"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et"android:gravity="center"android:maxLength="1"android:textSize="20sp" /><EditTextandroid:id="@+id/et7"android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="2dp"android:layout_weight="1"android:background="@drawable/shape_et_green"android:gravity="center"android:hint=""android:maxLength="1"android:textSize="20sp" /></LinearLayout><android.inputmethodservice.KeyboardViewandroid:id="@+id/keyboard_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#DCDCDC"android:focusable="true"android:focusableInTouchMode="true"android:keyBackground="@drawable/selector_key"android:keyTextColor="#000"android:keyTextSize="18sp"android:paddingTop="8dp"android:paddingBottom="8dp"android:shadowColor="#FFFFFF"android:shadowRadius="0.0"android:visibility="visible"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

视频效果

自定义车牌

汉字转化

先将目标汉字转换Unicode, 再通过16进制转换成10进制。比如“京” 转换Unicode码为“\u4eac”,再将16进制的“4eac”转换成10进制码为“20140”。

<Key android:codes="20140" android:keyLabel="" />

转换参考下面链接:

汉字转换Unicode网址:http://www.msxindl.com/tools/unicode16.asp
汉字转换Unicode

16进制转10进制网址:https://tool.oschina.net/hexconvert/
16进制转10进制

项目链接

项目gitee链接: https://gitee.com/linvisf/KtDemo

android 自定义车牌键盘(kotlin)相关推荐

  1. android自定义系统键盘,Android自定义软键盘

    [实例简介] Android自定义软键盘 [实例截图] [核心代码] keydemo └── keydemo ├── AndroidManifest.xml ├── bin │   ├── class ...

  2. Android自定义安全键盘

    Android自定义安全键盘 Demo地址 主要功能:包含功能:数字+字母组合键盘.纯数字键盘.字符键盘,防止录屏截屏 . 项目主要是通过Recyclerview来进行实现的,项目整体结构使用了建造者 ...

  3. android自定义数字键盘和字母键盘,Android自定义键盘的实现(数字键盘和字母键盘)...

    Android自定义键盘的实现(数字键盘和字母键盘) 发布时间:2020-09-04 03:18:48 来源:脚本之家 阅读:100 作者:浪淘沙xud 在项目中,产品对于输入方式会有特殊的要求,需要 ...

  4. android自动软键盘,Android自定义软键盘

    MyKeyboard Android自定义键盘的使用 实现步骤 第一步: 1.新建一个xml文件夹放在res目录下面,然后新建xml文件:money_keyboard.xml 2.然后在XML文件中添 ...

  5. Android 自定义软键盘实现 数字九宫格

    前言 最近项目在对接美团外卖功能 实现外面小哥凭取货码取货 对接完功能后 用户反馈 弹出的软键盘 很难输入 数字太小了 大概是下面这种显示方式 需求 组长说 要不搞一个自定义软键盘吧 数字搞大点 方便 ...

  6. 【uniapp前端组件】自定义车牌键盘

    自定义车牌输入键盘–车牌键盘 简介 本组件根据自定义万能键盘(数字键盘.身份证键盘.带小数点数字键盘.车牌键盘)升级而来,老组件代码有点看不懂了,哈哈哈哈.另外数字键盘.身份证键盘.小数点数字键盘un ...

  7. Android自定义软键盘输入法,隐藏系统输入法显示光标的实现

    android实现自定义软键盘,先上图看效果,效果基本上是仿ios输入法实现的 这里是实现隐藏系统输入法,同时让EditText能获取光标的代码部分(通过反射调用): <span style=& ...

  8. Android 自定义软键盘实现

    module链接:https://download.csdn.net/download/meixi_android/10652565 compile project(':edlibrary') , ' ...

  9. Android 自定义手势键盘

    自定义手势键盘 手势键盘有三种状态,初始状态.点击状态和错误状态,分别以下列三个图片显示. 2. 数据类CircleArea CircleArea类用来记录手势键盘的信息. static class ...

最新文章

  1. 3 个重要因素,带你看透 AI 技术架构方案的可行性
  2. 基于visual Studio2013解决面试题之1002公共子串
  3. 细节决胜 盘点IBM x86平台虚拟化优势
  4. FPGA的发展历史及相关名词解释
  5. 【原创】Windows下使用 Eclipse 管理 RabbitMQ 源码之问题解决
  6. oracle的EMCTL
  7. 朋友圈、浏览器分享实现
  8. python使用-python 类如何使用
  9. Webpack4 学习笔记一初探Webpack
  10. 读《白话统计》笔记——第七章
  11. 西门子阀门定位器安装教程来啦,不会安装的宝贝们仔细看看咯!
  12. VM虚拟机win2003桥接模式本地连接受限制问题
  13. Microsoft Visio 2013在安装过程中出错的一种解决方案
  14. GGC/ITF/国自然
  15. Invalid configuration of tez jars, tez.lib.uris is not defined in the configuration
  16. 安卓手机备忘录怎么添加录音
  17. 全屋互联网家电领导者云米科技在美IPO募资1.03亿美元
  18. R语言Copula的贝叶斯非参数估计
  19. cocos2d 高仿doodle jump 无源码
  20. 主观下线和客观下线的情况

热门文章

  1. CNN经典模型整理Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning,squeezenet
  2. 我将进化成一条狗(2)——大数据
  3. 有人负责,才有质量:写给在集市中迷失的一代(读后有感)
  4. 利用ant编译EJB(1)-生成公共包
  5. matlab删除连通域面积_matlab连通域处理函数
  6. HTML/CSS IE6、7兼容性问题、bug总汇
  7. 警告:不能读取 AppletViewer 的属性文件解决
  8. C#遇到 错误:不可访问,因为它具有一定的保护级别
  9. [分享]高仿网易新闻WebApp模板+Dcloud打包源码下载
  10. phpyun人才系统v6.2视频面试聊天功能怎么申请App Key来保障正常使用