前言
平时停车缴费都要填车牌号码,就想着自己能不能也做个车牌键盘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">
<Key
android:codes="20140"
android:keyLabel="京" />
<Key
android:codes="27941"
android:keyLabel="津" />
<Key
android:codes="20864"
android:keyLabel="冀" />
<Key
android:codes="40065"
android:keyLabel="鲁" />
<Key
android:codes="26187"
android:keyLabel="晋" />
<Key
android:codes="33945"
android:keyLabel="蒙" />
<Key
android:codes="36797"
android:keyLabel="辽" />
<Key
android:codes="21513"
android:keyLabel="吉" />
<Key
android:codes="40657"
android:keyLabel="黑" />
<Key
android:codes="27818"
android:keyLabel="沪" />
</Row>
<Row android:verticalGap="1%p">
<Key
android:codes="33487"
android:keyLabel="苏" />
<Key
android:codes="27993"
android:keyLabel="浙" />
<Key
android:codes="30358"
android:keyLabel="皖" />
<Key
android:codes="38397"
android:keyLabel="闽" />
<Key
android:codes="36195"
android:keyLabel="赣" />
<Key
android:codes="35947"
android:keyLabel="豫" />
<Key
android:codes="37122"
android:keyLabel="鄂" />
<Key
android:codes="28248"
android:keyLabel="湘" />
<Key
android:codes="31908"
android:keyLabel="粤" />
<Key
android:codes="26690"
android:keyLabel="桂" />
</Row>
<Row android:verticalGap="1%p">
<Key
android:codes="28189"
android:keyLabel="渝" />
<Key
android:codes="24029"
android:keyLabel="川" />
<Key
android:codes="36149"
android:keyLabel="贵" />
<Key
android:codes="20113"
android:keyLabel="云" />
<Key
android:codes="34255"
android:keyLabel="藏" />
<Key
android:codes="38485"
android:keyLabel="陕" />
<Key
android:codes="29976"
android:keyLabel="甘" />
<Key
android:codes="38738"
android:keyLabel="青" />
<Key
android:codes="29756"
android:keyLabel="琼" />
<Key
android:codes="26032"
android:keyLabel="新" />
</Row>
<Row>
<Key
android:codes="-1"
android:isModifier="true"
android:isSticky="true"
android:keyWidth="10%p"
android:keyLabel="ABC" />
<Key
android:codes="23425"
android:keyLabel="宁" />
<Key
android:codes="20351"
android:keyLabel="使" />
<Key
android:codes="39046"
android:keyLabel="领" />
<Key
android:codes="35686"
android:keyLabel="警" />
<Key
android:codes="23398"
android:keyLabel="学" />
<Key
android:codes="28207"
android:keyLabel="港" />
<Key
android:codes="28595"
android:keyLabel="澳" />
<!-- 注释台湾-->
<!-- <Key-->
<!-- android:codes="21488"-->
<!-- android:keyLabel="台" />-->
<Key
android: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.AppCompatActivity
class KeyboardUtil(private var activity: AppCompatActivity) {
private var mKeyboardView: KeyboardView
private val provinceKeyboard: Keyboard
private var abcKeyboard: Keyboard
private var editText: EditText? = null
init {
// 省份键盘
provinceKeyboard = Keyboard(activity, R.xml.province)
// abc键盘
abcKeyboard = Keyboard(activity, R.xml.abc)
mKeyboardView = activity.findViewById(R.id.keyboard_view)
mKeyboardView.apply {
keyboard = provinceKeyboard
isEnabled = true
// 设置按键没有点击放大镜显示的效果
isPreviewEnabled = false
setOnKeyboardActionListener(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?.text
val start: Int = editText?.selectionStart ?: 0
when (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.visibility
if (visibility == View.GONE || visibility == View.INVISIBLE) {
mKeyboardView.visibility = View.VISIBLE
}
}
/**
* 隐藏软键盘
*/
fun hideKeyboard() {
val visibility = mKeyboardView.visibility
if (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: KeyboardUtil
override 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">
<TextView
android: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" />
<LinearLayout
android: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">
<EditText
android: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" />
<EditText
android: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" />
<EditText
android: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" />
<EditText
android: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" />
<EditText
android: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" />
<EditText
android: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" />
<EditText
android: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" />
<EditText
android: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.KeyboardView
android: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进制文章来源:https://www.toymoban.com/news/detail-562489.html
项目链接
项目gitee链接: https://gitee.com/linvisf/KtDemo文章来源地址https://www.toymoban.com/news/detail-562489.html
到了这里,关于android 自定义车牌键盘(kotlin)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!