自定義控制元件-----自定義數字鍵盤,適配了正則表示式的帶輸出字串的控制元件
阿新 • • 發佈:2019-01-11
一、主要的類:CustomAmountInputKeyboard class CustomAmountInputKeyboard constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs), AdapterView.OnItemClickListener, View.OnClickListener { private var mItemHeight: Int = 0//行高 private var mItemTextSize: Float = 0.toFloat()//item文字大小 private var mKeyBoardType: Int = 0//鍵盤型別 private var mAdapter: KeyBoardNumAdapter? = null private var mKeyBoartTouchListener: KeyBoartTouchListener? = null private var mInput: String = ""//已經輸入的數字 // private val mPatternCalculation = "^(([1-9]\\d{0,8})|([0]{0,1}))(\\.(\\d){0,2})?$"//計算器模式 private val mPatternCalculation = "^(([1-9]{1}\\d{0,6})|([0]{1}))(\\.(\\d){0,2})?\$"//計算器模式 private val mPatternPassword = "^(\\d{0,6})"//密碼鍵盤模式 companion object { private val TYPE_CALCULATION = 1//主介面鍵盤 private val TYPE_PASSWORD = 2//輸入密碼 private val TYPE_OTHER = 3//亂序 } init { val view = LayoutInflater.from(context).inflate(R.layout.base_view_custom_amount_input_keyboard, null) setLinearLayoutStyle(context, attrs, view) addView(view) } private fun setLinearLayoutStyle(context: Context, attrs: AttributeSet?, view: View) { val array = context.obtainStyledAttributes(attrs, R.styleable.CustomAmountInputKeyboard) mItemHeight = array.getDimensionPixelSize(R.styleable.CustomAmountInputKeyboard_itemHeight, 100) mItemTextSize = array.getDimension(R.styleable.CustomAmountInputKeyboard_itemTextSize, 30f) mKeyBoardType = array.getInt(R.styleable.CustomAmountInputKeyboard_keyBoardType, TYPE_CALCULATION) val gvKeyBoardNum = view.findViewById<View>(R.id.gv_keyboard_num) as GridView gvKeyBoardNum.onItemClickListener = this mAdapter = KeyBoardNumAdapter(context, getNumbers(mKeyBoardType)) gvKeyBoardNum.adapter = mAdapter val tvKeyBoardZero: TextView = view.findViewById<View>(R.id.tv_keyboard_zero) as TextView tvKeyBoardZero.setOnClickListener(this) tvKeyBoardZero.textSize = mItemTextSize setViewHeight(tvKeyBoardZero) val windowManager1 = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager tvKeyBoardZero.setPadding(0, 0, windowManager1.defaultDisplay.width / 4, 0) val tvKeyboardPoint: TextView = view.findViewById(R.id.tv_keyboard_point) as TextView tvKeyboardPoint.setOnClickListener(this) tvKeyboardPoint.textSize = mItemTextSize setViewHeight(tvKeyboardPoint) val tvKeyboardClear: TextView = view.findViewById(R.id.tv_keyboard_clear) as TextView tvKeyboardClear.setOnClickListener(this) tvKeyboardClear.textSize = mItemTextSize setViewHeight(tvKeyboardClear) if (mKeyBoardType == TYPE_PASSWORD) tvKeyboardClear.visibility = View.VISIBLE else tvKeyboardPoint.visibility = View.VISIBLE val llKeyBoardDelete = view.findViewById<View>(R.id.ll_keyboard_del) as LinearLayout llKeyBoardDelete.setOnClickListener(this) val tvKeyBoardOk = view.findViewById<View>(R.id.tv_keyboard_ok) as TextView tvKeyBoardOk.setOnClickListener(this) tvKeyBoardOk.textSize = mItemTextSize - 8 } /** * 設定子控制元件的高度 */ private fun setViewHeight(view: View) { val params = view.layoutParams as LinearLayout.LayoutParams val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager val height = (windowManager.defaultDisplay.height * mItemHeight / 1280.0).toInt() params.height = height view.layoutParams = params } /** * 獲得鍵盤上要填入的資料 */ private fun getNumbers(keyBoardType: Int): List<String> { var numbers: MutableList<String>? = null when (keyBoardType) { TYPE_CALCULATION -> numbers = Arrays.asList(*arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9")) // TYPE_PASSWORD -> numbers = Arrays.asList(*arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", " ", "C")) // TYPE_OTHER -> { // numbers = Arrays.asList(*arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9", " ", "0", "C")) // Collections.shuffle(numbers)//亂序 // numbers[numbers.indexOf(" ")] = numbers[10] // numbers[10] = " " // numbers[numbers.indexOf("C")] = numbers[11] // numbers[11] = "C" // } else -> numbers = Arrays.asList(*arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9")) } return numbers } override fun onClick(v: View) { if (mKeyBoartTouchListener == null) return when (v.id) { R.id.tv_keyboard_zero -> input((v as TextView).text as String) R.id.tv_keyboard_point -> input((v as TextView).text as String) R.id.tv_keyboard_clear -> input((v as TextView).text as String) R.id.ll_keyboard_del -> input("del") R.id.tv_keyboard_ok -> mKeyBoartTouchListener!!.onOkTouch() } } override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { input(mAdapter!!.getItem(position).toString() + "") showNumber(mInput) } interface KeyBoartTouchListener { fun onOkTouch() fun onInputNumberTouch(inputNumber: String) } fun setKeyBoartTouchListener(listener: KeyBoartTouchListener) { this.mKeyBoartTouchListener = listener } private inner class KeyBoardNumAdapter(private val mContext: Context, mNumbers: List<String>) : BaseAdapter() { private val mNumbers: List<String> private val inflater: LayoutInflater init { this.mNumbers = getNumbers(mNumbers) this.inflater = LayoutInflater.from(mContext) } private fun getNumbers(mNumbers: List<String>?): List<String> { var mNumbers = mNumbers if (mNumbers == null) { mNumbers = ArrayList() } return mNumbers } override fun getCount(): Int { return mNumbers.size } override fun getItem(position: Int): Any { return mNumbers[position] } override fun getItemId(position: Int): Long { return position.toLong() } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { var convertView = convertView val hodler: ViewHodler if (convertView == null) { hodler = ViewHodler() convertView = inflater.inflate(R.layout.base_grid_item_custom_amount_input_keyboard, null) hodler.mTvStyle = convertView!!.findViewById<View>(R.id.tv_style) as TextView hodler.mTvStyle!!.textSize = mItemTextSize convertView.tag = hodler } else { hodler = convertView.tag as ViewHodler } setViewHeight(hodler.mTvStyle!!) val number = mNumbers[position] hodler.mTvStyle!!.text = number if (position == 11) { hodler.mTvStyle!!.setTextColor(resources.getColor(R.color.colorAccent))//清除按鈕 } return convertView } private inner class ViewHodler { var mTvStyle: TextView? = null } } /** * 顯示內容 */ fun showNumber(inputNumber: String) { if (mKeyBoartTouchListener == null) return mKeyBoartTouchListener!!.onInputNumberTouch(inputNumber) } /** * 數字鍵盤輸入內容 */ fun input(input: String) { var tempInput: String = mInput + input var regex: String? = null when (mKeyBoardType) { TYPE_CALCULATION -> {//計算器模式(帶小數點) if ("0" == (tempInput)) return//一次輸入0 if ("." == tempInput) tempInput = "0." regex = mPatternCalculation } TYPE_PASSWORD -> regex = mPatternPassword//密碼鍵盤模式(帶C的清除按鈕) } when (input) { "del" -> if (tempInput.length > 4) { if (tempInput.startsWith("0.") && tempInput.length == 5) {//此時tempInput == 0.del mInput = "" } else { tempInput = tempInput.substring(0, tempInput.length - 4) } } else mInput = "" "C" -> tempInput = "" } var pattern = Pattern.compile(regex) if (pattern.matcher(tempInput).matches()) { mInput = tempInput } showNumber(mInput) } }
二、呼叫
class MainActivity : BaseActivity(),CustomAmountInputKeyboard.KeyBoartTouchListener{ var mPopupWindow: TipPopupWindow? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity_main) keyboard.setKeyBoartTouchListener(this) } @SuppressLint("NewApi") override fun onOkTouch() { //點選OK按鈕 } override fun onInputNumberTouch(inputNumber: String) { if (!"".equals(inputNumber)) tv_input_amount.text = inputNumber else tv_input_amount.text = "0" } }
三、其他res下面的檔案可參考 https://mp.csdn.net/postedit/81163156 裡的佈局及資源