What can you learn
- The use of kotlin, the writing of extended features, etc.
- Some basics of custom ViewGroup
- Writing and reading of xml properties
Because each key takes into account the need to support other personal settings such as background settings and Touch gestures, I decided to implement it with the idea of each key corresponding to a View. Otherwise, I can use itaccomplish
This improves scalability and customizability
1. Define the keys according to the renderings
//First define the required keys//The order is disrupted, and the display is out of order, which can be safer.//Special keys-> "": means blank placeholder key; "-1": means back key, that is, delete.var keys = arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "-1")
Update the corresponding keys and create the corresponding view
{ val keyView: View = when (it) { "-1" -> { //delete imageView(.keyboard_del, .keyboard_del_press).apply { background = null setBackgroundColor(("#E2E7ED")) } } "" -> { //Placeholder View View(context).apply { setBackgroundColor(("#E2E7ED")) } } else -> { createKeyView(it) } } = it //Save the corresponding value of the key through tag addView(keyView) } private fun createKeyView(key: String): View { return if (useImageKey) { val keyRes = when (key) { "1" -> .keyboard_1 "2" -> .keyboard_2 "3" -> .keyboard_3 "4" -> .keyboard_4 "5" -> .keyboard_5 "6" -> .keyboard_6 "7" -> .keyboard_7 "8" -> .keyboard_8 "9" -> .keyboard_9 else -> .keyboard_0 } imageView(keyRes) } else { textView(key) } } private fun imageView(res: Int, pressRes: Int = -1): ImageView { return ImageView(context).apply { if (pressRes == -1) { setImageResource(res) } else { setImageResource(res) //setImageDrawable((getDrawable(res), getDrawable(pressRes))) } scaleType = keyViewBGDrawable?.let { background = () } setOnClickListener(this@KeyboardLayout) } } private fun textView(text: String): TextView { return TextView(context).apply { gravity = = text setTextSize(TypedValue.COMPLEX_UNIT_PX, keyTextSize) keyViewBGDrawable?.let { background = () } setTextColor() setOnClickListener(this@KeyboardLayout) } }
2. After the key element is created, start the standard operation of customizing ViewGroup
onMeasure: Measure the width and height of each key
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { //(widthMeasureSpec, heightMeasureSpec) var widthSize = (widthMeasureSpec) val widthMode = (widthMeasureSpec) var heightSize = (heightMeasureSpec) val heightMode = (heightMeasureSpec) if (widthMode != ) { widthSize = } if (heightMode != ) { heightSize = (4 * keyViewHeight + 3 * vSpace).toInt() } childWidth = ((widthSize - 2 * hSpace - paddingLeft - paddingRight) / 3).toInt() childHeight = ((heightSize - 3 * vSpace - paddingTop - paddingBottom) / 4).toInt() childs { _, view -> (exactlyMeasure(childWidth), exactlyMeasure(childHeight)) } setMeasuredDimension(widthSize, heightSize) }
onLayout: Determines the coordinate position of the key in the ViewGroup
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { //Lattach one line, 4 lines in total for (line in 0..3) { var top: Int = (paddingTop + line * (childHeight + vSpace)).toInt() //3 columns for (i in 0..2) { var left: Int = (paddingLeft + i * (childWidth + hSpace)).toInt() getChildAt(line * 3 + i).layout(left, top, left + childWidth, top + childHeight) } } }
3: Event listening and callback
override fun onClick(v: View?) { if (onKeyboardInputListener == null) { return } v?.let { view -> val tag = if (tag is String) { val isDel = "-1" == tag onKeyboardInputListener?.onKeyboardInput(tag, isDel) } } }
4: Properties declaration in xml
You need to create an XML file with any file name in the values folder
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="KeyboardLayout"> <attr name="r_key_height" format="dimension"/> <attr name="r_key_width" format="dimension"/> <attr name="r_key_text_size" format="dimension"/> <attr name="r_key_background" format="reference"/> <attr name="r_background" format="reference"/> <attr name="r_use_image_key" format="boolean"/> </declare-styleable> </resources>
declare-styleable are both standard writing methods. Name corresponds to the type of custom view, and they are all standard writing methods. Different formats correspond to different get methods. It is easy to use when you are familiar with it.
5: Property reading in xml
init { val typedArray = (attributeSet, ) //Note 1: keyViewHeight = (.KeyboardLayout_r_key_height, keyViewHeight) //(.KeyboardLayout_r_key_width, keyViewHeight) keyTextSize = (.KeyboardLayout_r_key_text_size, keyTextSize) useImageKey = (.KeyboardLayout_r_use_image_key, useImageKey) keyViewBGDrawable = (.KeyboardLayout_r_key_background) if (keyViewBGDrawable == null) { keyViewBGDrawable = getDrawable(.base_white_bg_selector) } mBackgroundDrawable = (.KeyboardLayout_r_background) if (mBackgroundDrawable == null) { mBackgroundDrawable = ColorDrawable(getColor(.base_chat_bg_color)) } setWillNotDraw(false) () //Note 2 }
Note 1,2:All are necessary writing methods, and the middle part is the corresponding attribute reading operation.
Source code address /angcyo/KeyboardLayout (Local download)
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.