前言
最近項(xiàng)目中有支付功能,用戶輸入密碼時(shí)要類似微信支付密碼輸入框的樣式特占,本想直接copy網(wǎng)上的云茸,但設(shè)計(jì)姐姐總是對(duì)樣式挑三揀四,抽空自己自定義了一個(gè)懊纳,無(wú)奈之下抽空自定義了個(gè)宜岛,并把它貼到GitHub上供網(wǎng)友們參考功舀。
示例
廢話不多說(shuō)辟汰,先看效果圖。
實(shí)現(xiàn)
BorderTextView
首先戴而,實(shí)現(xiàn)這種效果我用多個(gè)TextView控件組合翩蘸,為什么是TextView呢,因?yàn)槲也粌H需要文字大小顏色等可以定制扶踊,還要文字的背景色郎任,背景框等可以變化。但系統(tǒng)的TextView設(shè)置背景過(guò)于單一分井,假如我要帶圓角的背景,甚至是圓角可以變化的背景尺锚,這就麻煩了。因此我繼承TextView自定義了BorderTextView铸磅。
BorderTextView控件主要是文字的背景色可變化阅仔,有邊框和填充兩種背景弧械。
- 邊框的粗細(xì)、顏色刃唐、圓角均可定制。
- 填充背景時(shí)衔瓮,填充顏色抖甘,背景圓角可定制。
- 除此之外薇宠,BorderTextView有明文顯示和密文顯示兩種模式〕胃郏考慮過(guò)設(shè)置transformationMethod屬性來(lái)將TextView顯示成"●"柄沮,但有時(shí)候設(shè)置的"●"太小了,而且顏色又單一狱意,因此我重寫了TextView的setBackgroundColor方法棕硫,在文字的中心化了個(gè)實(shí)心圈覆蓋文字,同時(shí)"●"的顏色大小均可變化纬纪。
- 核心代碼如下
override fun onDraw(canvas: Canvas) {
mStrokePaint.isAntiAlias = true
mStrokePaint.strokeWidth = strokeWidth.toFloat()
mStrokePaint.color = strokeColor
mStrokePaint.style = if (isFill) Paint.Style.FILL else Paint.Style.STROKE
mStrokePaint.strokeCap = Paint.Cap.ROUND
//解決canvas.drawRoundRect時(shí),四個(gè)圓角線較粗問(wèn)題
if (rectF == null) {
val d = strokeWidth / 2
rectF = RectF(d.toFloat(), d.toFloat(), (measuredWidth - d).toFloat(), (measuredHeight - d).toFloat())
}
if (mBgPaint != null) {
canvas.drawRoundRect(rectF!!, cornerRadius.toFloat(), cornerRadius.toFloat(), mBgPaint!!)
}
canvas.drawRoundRect(rectF!!, cornerRadius.toFloat(), cornerRadius.toFloat(), mStrokePaint)
if (mIsPassWordMode && text.isNotEmpty()) {
mDotPaint.style = Paint.Style.FILL
mDotPaint.color = textColors.defaultColor
val xy = measuredWidth / 2.toFloat()
canvas.drawCircle(xy, xy, textSize / 2, mDotPaint)
}
super.onDraw(canvas)
}
- EditText
EditText用于監(jiān)聽用戶輸入的數(shù)字摘仅,將其的背景設(shè)置成透明问畅,再設(shè)置 isCursorVisible = false、inputType = InputType.TYPE_CLASS_NUMBER 屬性矾端。同時(shí)卵皂,用戶輸入的時(shí)候需要攔截輸入內(nèi)容,再將內(nèi)容顯示到BorderTextView上殴玛。監(jiān)聽用戶鍵盤的KeyEvent.KEYCODE_DEL事件用戶處理輸入內(nèi)容的刪除 - 搞定BorderTextView和EditText后就簡(jiǎn)單了,用List集合存儲(chǔ)TextViews滚粟,創(chuàng)建LineaLayout將N個(gè)TextView添加過(guò)去刃泌,調(diào)整其位置就ok了。
/**
* 初始化EditText
*/
private fun initEditText() {
mEditText = EditText(context)
mEditText.let {
it.setBackgroundColor(Color.TRANSPARENT)
it.isFocusable = true
it.isCursorVisible = false
it.inputType = InputType.TYPE_CLASS_NUMBER
}
}
/**
* 監(jiān)聽刪除鍵
**/
mEditText.setOnKeyListener { v, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_DEL && event.action == KeyEvent.ACTION_DOWN) {
if (mInputSb.isNotEmpty()) {
mInputSb.delete(mInputSb.length - 1, mInputSb.length)
mTextViews[mInputSb.length].text = ""
return@setOnKeyListener true
}
}
return@setOnKeyListener false
}
自定義屬性
name | 說(shuō)明 | format | 默認(rèn)值 |
---|---|---|---|
niv_text_size_sp | 輸入框字體大小 | integer | 16 |
niv_text_color | 輸入框字體顏色 | color | #333333 |
niv_text_divider | 輸入框間隔 | dimension | 5 |
niv_text_width | 輸入框?qū)挾?width=height) | dimension | 40 |
niv_border_width | 輸入框邊框?qū)挾?/td> | dimension | 2 |
niv_border_color | 輸入邊框顏色 | color | #333333 |
niv_border_radius | 輸入框圓角角度 | dimension | 4 |
niv_is_fill | 是否填充輸入框 | boolean | false |
niv_count | 輸入框個(gè)數(shù)(最大為10) | integer | 6 |
niv_is_pw_mode | 輸入數(shù)字是否用點(diǎn)代替 | boolean | false |
可用方法
method_name | description | return type |
---|---|---|
setInputCompleteListener(inputCompleteListener: InputCompleteListener) | 輸入完成時(shí)監(jiān)聽 | Unit |
使用示例
-
上示例圖中xml代碼如下
<LinearLayout 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" android:gravity="center" android:orientation="vertical" android:paddingBottom="20dp" android:paddingTop="20dp" tools:context="com.neworin.sample.MainActivity"> <com.neworin.numberinputview.widget.NumberInputView android:id="@+id/sample_niv1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:niv_count="4" app:niv_is_fill="false" app:niv_text_size_sp="18"/> <com.neworin.numberinputview.widget.NumberInputView android:id="@+id/sample_niv2" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:niv_border_color="@color/colorPrimaryDark" app:niv_border_radius="0dp" app:niv_count="5" app:niv_text_color="@color/color_red"/> <com.neworin.numberinputview.widget.NumberInputView android:id="@+id/sample_niv3" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:niv_border_color="@color/input_layout_bg" app:niv_border_radius="0dp" app:niv_count="6" app:niv_is_fill="true" app:niv_text_size_sp="20"/> <com.neworin.numberinputview.widget.NumberInputView android:id="@+id/sample_niv4" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:niv_count="6" app:niv_is_pw_mode="true" app:niv_text_color="@color/colorPrimary" app:niv_text_size_sp="18"/> </LinearLayout>
效果圖
最后附上多種效果圖以及GitHub地址:https://github.com/NewOrin/number-input