<?xml version="1.0" encoding="utf-8"?><!-- isRepeatable:长按时是否重复这个操作 --> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:horizontalGap="1px" android:keyHeight="7%p" android:keyWidth="33.33%p" android:verticalGap="1px"> <Row android:keyHeight="6%p"> <Key android:codes="-4" android:keyIcon="@drawable/hidden" android:keyWidth="100%" /> </Row> <Row> <Key android:codes="49" android:keyLabel="1" /> <Key android:codes="50" android:keyLabel="2" /> <Key android:codes="51" android:keyLabel="3" /> </Row> <Row> <Key android:codes="52" android:keyLabel="4" /> <Key android:codes="53" android:keyLabel="5" /> <Key android:codes="54" android:keyLabel="6" /> </Row> <Row> <Key android:codes="55" android:keyLabel="7" /> <Key android:codes="56" android:keyLabel="8" /> <Key android:codes="57" android:keyLabel="9" /> </Row> <Row> <Key android:codes="46" android:keyLabel="." /> <Key android:codes="48" android:keyLabel="0" /> <Key android:codes="-5" android:isRepeatable="true" android:keyIcon="@drawable/delete" /> </Row> </Keyboard>
//就不解释了,通过名字应该看得出来 public static final int KEYCODE_SHIFT = -1; public static final int KEYCODE_MODE_CHANGE = -2; public static final int KEYCODE_CANCEL = -3; public static final int KEYCODE_DONE = -4; public static final int KEYCODE_DELETE = -5; public static final int KEYCODE_ALT = -6;
class CustomKeyboardView : KeyboardView {
private var mKeyBoard: Keyboard? = null
constructor(context: Context, attrs: AttributeSet) : this(context, attrs,0) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
//
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
mKeyBoard = this.keyboard
var keys: MutableList<Keyboard.Key>? = null
if (mKeyBoard != null) {
keys = mKeyBoard!!.keys
}
if (keys != null) {
for (key in keys) {
//可以自定义自己的绘制(例如某个按钮绘制背景图片和文字,亦或者更改某个按钮颜色等)
if (key.codes[0] == -111) {//过滤指定某个键自定义绘制
}
}
}
}
}
if (key.codes[0] == -111) {//过滤指定某个键自定义绘制
//绘制后,原来xml中的keyLabel以及keyIcon会被覆盖,如需显示文字
//需要自己重新绘制,要后绘制文字,否则文字不显示
drawBackground(R.drawable.bg_keyboardview1, canvas, key)
drawTextOrIcon(canvas, key)
}
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/btnpressed" android:state_pressed="true"/> <item android:drawable="@color/btnnormal"/> </selector>
//绘制背景
fun drawBackground(drawableId: Int, canvas: Canvas, key: Keyboard.Key) {
var drawable = resources.getDrawable(drawableId)
var drawableState: IntArray = key.currentDrawableState
if (key.codes[0] != 0) {
drawable.state=drawableState
}
drawable.bounds = Rect(key.x, key.y, key.x + key.width, key.height + key.y)
drawable.draw(canvas)
}
//绘制文字或图标
fun drawTextOrIcon(canvas: Canvas, key: Keyboard.Key) {
var bounds = Rect()
var paint = Paint()
paint.color = Color.WHITE
paint.isAntiAlias = true
paint.textAlign = Paint.Align.CENTER
paint.typeface = Typeface.DEFAULT
if (key.label != null) {
var label = key.label.toString()
//为了将字体大小与默认绘制的Label字体大小相同,需要反射获取默认大小。然后在此处设置文字大小
//还有一种取巧的方法在布局文件keyboardview中设置keyTextSize,labelTextSize
var field = KeyboardView::class.java.getDeclaredField("mLabelTextSize")
field.isAccessible = true
var labelTextSize = field.get(this) as Int
paint.textSize = labelTextSize.toFloat()
paint.getTextBounds(label, 0, label.length, bounds)
canvas.drawText(label, (key.x + key.width / 2).toFloat(), (key.y + key.height / 2 + bounds.height() / 2).toFloat(), paint)
} else if (key.icon != null) {
key.icon.bounds = Rect(key.x + (key.width - key.icon.intrinsicWidth) / 2, key.y + (key.height - key.icon.intrinsicHeight) / 2, key.x + (key.width - key.icon.intrinsicWidth) / 2 + key.icon.intrinsicWidth, key.y + (key.height - key.icon.intrinsicHeight) / 2 + key.icon.intrinsicHeight)
key.icon.draw(canvas)
}
}
<?xml version="1.0" encoding="utf-8"?><!-- background:整个键盘的背景色 keyBackground :设置键的背景 keyPreviewHeight:预览高度 keyPreviewLayout :设置预览布局 keyPreviewOffset :设置反馈的垂直偏移量 keyTextColor :设置key标签文字颜色 keyTextSize:设置key标签字体大小 labelTextSize:设置带文本和图标的键上个的文本的小大 --> <com.code4android.keyboard.CustomKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keyboard_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/keyborad_line_color" android:focusable="true" android:focusableInTouchMode="true" android:keyBackground="@drawable/bg_keyboardview" android:keyPreviewHeight="35dp" android:keyPreviewLayout="@layout/keyboard_key_preview" android:keyPreviewOffset="0dp" android:keyTextColor="#8a8a8a" android:keyTextSize="18sp" android:labelTextSize="18sp" android:paddingTop="0dp" android:shadowColor="#fff" android:shadowRadius="0.0" />
constructor(activity: Activity) : this(activity, true, false)
/**
* @param activity
* @param isRandom 是否时随机键盘
* @param mIsDecimal 是否支持小数输入
*/
constructor(activity: Activity, isRandom: Boolean, isDecimal: Boolean) {
mActivity = activity
mIsRandom = isRandom
mIsDecimal = isDecimal
mKeyboard = Keyboard(mActivity, R.xml.keyboard)
addViewToRoot()
}
//加载自定义的键盘layout
private fun addViewToRoot() {
mKeyBoardViewContainer = mActivity.layoutInflater.inflate(R.layout.keyboardview, null)
//var frameLayout: FrameLayout = mActivity.window.decorView as FrameLayout//不要直接往DecorView(状态栏,内容,导航栏)中addView,如使用这个则最后显示布局不全(一部分内容在导航栏区域)
var frameLayout: FrameLayout = mActivity.window.decorView.find(android.R.id.content)
var lp = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
lp.gravity = Gravity.BOTTOM
frameLayout.addView(mKeyBoardViewContainer, lp)
mKeyBoardView = mKeyBoardViewContainer.find(R.id.keyboard_view)
}
fun attachTo(editText: EditText) {
//如果editText与上次设置的是同一个对象,并且键盘已经正在在显示,不再执行后续操作
if (mEditText != null && mEditText == editText && mKeyBoardView.visibility == View.VISIBLE) return
mEditText = editText
Log.e(TAG, "attachTo")
//根据焦点及点击监听,来显示或者隐藏键盘
onFoucsChange()
//隐藏系统键盘
hideSystemSoftKeyboard()
//显示自定义键盘
showSoftKeyboard()
}
private fun onFoucsChange() {
mEditText!!.setOnFocusChangeListener { v, hasFocus ->
Log.e(TAG, "onFoucsChange:$hasFocus" + v)
//如果获取焦点,并且当前键盘没有显示,则显示,并执行动画
if (hasFocus && mKeyBoardView.visibility != View.VISIBLE) {
mKeyBoardView.visibility = View.VISIBLE
startAnimation(true)
} else if (!hasFocus && mKeyBoardView.visibility == View.VISIBLE) {
//如果当前时失去较大,并且当前在键盘正在显示,则隐藏
mKeyBoardView.visibility = View.GONE
startAnimation(false)
}
}
mEditText!!.setOnClickListener {
Log.e(TAG, "setOnClickListener")
//根据上面焦点的判断,如果已经获取到焦点,并且键盘隐藏。再次点击时,
// 焦点改变函数不会回调,所以在此判断如果隐藏就显示
if (mKeyBoardView.visibility == View.GONE) {
mKeyBoardView.visibility = View.VISIBLE
startAnimation(true)
}
}
}
private fun hideSystemSoftKeyboard() {
//11版本开始需要反射setShowSoftInputOnFocus方法设置false,来隐藏系统软键盘
if (Build.VERSION.SDK_INT > 10) {
var clazz = EditText::class.java
var setShowSoftInputOnFocus: Method? = null
setShowSoftInputOnFocus = clazz.getMethod("setShowSoftInputOnFocus", Boolean::class.java)
setShowSoftInputOnFocus.isAccessible = true
setShowSoftInputOnFocus.invoke(mEditText, false)
} else {
mEditText!!.inputType = InputType.TYPE_NULL
}
var inputMethodManager = mActivity.applicationContext.inputMethodManager
inputMethodManager.hideSoftInputFromWindow(mEditText!!.windowToken, 0)
}
private fun showSoftKeyboard() {
if (mIsRandom) {
//生成随机键盘
generateRandomKey()
} else {
//有序键盘
mKeyBoardView.keyboard = mKeyboard
}
mKeyBoardView.isEnabled = true
//设置预览,如果设置false,则就不现实预览效果
mKeyBoardView.isPreviewEnabled = true
//设置可见
mKeyBoardView.visibility = View.VISIBLE
//指定键盘弹出动画
startAnimation(true)
//设置监听
mKeyBoardView.setOnKeyboardActionListener(mOnKeyboardActionListener())
}
private fun generateRandomKey() {
var keys = mKeyboard.keys
var numberKeys = mutableListOf<Keyboard.Key>()
//保存数字
var nums = mutableListOf<Int>()
//0的ASCII码是48,之后顺序加1
for (key in keys) {
//过滤数字键盘
if (key.label != null && "0123456789".contains(key.label)) {
nums.add(Integer.parseInt(key.label.toString()))
numberKeys.add(key)
}
}
var random = Random()
var changeKey = 0//更改numberKeys对应的数值
while (nums.size > 0) {
var size = nums.size
var randomNum = nums[random.nextInt(size)]
var key = numberKeys[changeKey++]
key.codes[0] = 48 + randomNum
key.label = randomNum.toString()
nums.remove(randomNum)
}
mKeyBoardView.keyboard = mKeyboard
}
inner class mOnKeyboardActionListener : KeyboardView.OnKeyboardActionListener {
override fun swipeRight() {
Log.e(TAG, "swipeRight")
}
override fun onPress(primaryCode: Int) {
Log.e(TAG, "onPress")
//添加震动效果
mActivity.applicationContext.vibrator.vibrate(50)
////指定隐藏(确定)删除不显示预览
mKeyBoardView.isPreviewEnabled = !(primaryCode == Keyboard.KEYCODE_DONE || primaryCode == Keyboard.KEYCODE_DELETE)
}
override fun onRelease(primaryCode: Int) {
Log.e(TAG, "onRelease")
}
override fun swipeLeft() {
Log.e(TAG, "swipeLeft")
}
override fun swipeUp() {
Log.e(TAG, "swipeUp")
}
override fun swipeDown() {
Log.e(TAG, "swipeDown")
}
override fun onKey(primaryCode: Int, keyCodes: IntArray?) {
Log.e(TAG, "onKey primaryCode:$primaryCode keyCodes:$keyCodes")
if (mEditText == null) throw RuntimeException("The mEditText is null,Please call attachTo method")
mEditText?.let {
var editable: Editable = it.text
var textString = editable.toString()
//获取光标位置
var start = it.selectionStart
when (primaryCode) {
//如果是删除键,editable有值并且光标大于0(即光标之前有内容),则删除
Keyboard.KEYCODE_DELETE -> {
if (!editable.isNullOrEmpty()) {
if (start > 0) {
editable.delete(start - 1, start)
} else {
}
} else {
}
}
Keyboard.KEYCODE_DONE -> {
hideSoftKeyboard()
mOnOkClick?.let {
//点击确定时,写一个回调,如果你对有确定的需求
it.onOkClick()
}
}
else -> {
// 由于promaryCode是用的ASCII码,则直接转换字符即可,46是小数点
if (primaryCode != 46 ) {
//如果点击的是数字,不是小数点,则直接写入EditText,由于我codes使用的是ASCII码,
// 则可以直接转换为数字。当然可以你也可以获取label,或者根据你自己随便约定。
editable.insert(start, Character.toString(primaryCode.toChar()))
} else {
//如果点击的是逗号
if (mIsDecimal && primaryCode == 46) {
if ("" == textString) {
//如果点的是小数点,并且当前无内容,自动加0
editable.insert(start, "0.")
} else if (!textString.contains(".")) {
//当前内容不含有小数点,并且光标在第一个位置,依然加0操作
if (start == 0) {
editable.insert(start, "0.")
} else {
editable.insert(start, ".")
}
} else {
//如果是不允许小数输入,或者允许小数,但是已经有小数点,则不操作
}
} else {
}
}
}
}
}
}
override fun onText(text: CharSequence?) {
Log.e(TAG, "onText:" + text.toString())
}
}
fun hideSoftKeyboard(): Boolean {
if (mEditText == null) return false
var visibility = mKeyBoardView.visibility
if (visibility == View.VISIBLE) {
startAnimation(false)
mKeyBoardView.visibility = View.GONE
return true
}
return false
}
fun startAnimation(isIn: Boolean) {
Log.e(TAG, "startAnimation")
var anim: Animation
if (isIn) {
anim = AnimationUtils.loadAnimation(mActivity, R.anim.anim_bottom_in)
} else {
anim = AnimationUtils.loadAnimation(mActivity, R.anim.anim_bottom_out)
}
mKeyBoardViewContainer.startAnimation(anim)
}
keyboardUtli = KeyBoardUtil(this@KeyBoardDemoActivity)
et_keyboard.setOnTouchListener { v, event ->
keyboardUtli?.attachTo(et_keyboard)
//设置是否可以输入小数
keyboardUtli?.mIsDecimal = true
false
}
et_keyboard2.setOnTouchListener { v, event ->
keyboardUtli?.attachTo(et_keyboard2)
keyboardUtli?.mIsDecimal = false
false
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有