前言
因?yàn)楹弦?guī)的原因, 所有的輸入框都得在后面加上一個(gè)清除按鈕, 直接布局里面添加ImageView雖然也可以, 但是顯然需要每個(gè)用到的地方都要copy代碼, 很是不妥, 所以但是寫了這個(gè)實(shí)現(xiàn)類, 只需要替換到原來(lái)的EditTextView就可以了. 清除邏輯已經(jīng)實(shí)現(xiàn)好了.
效果

Project Name (1).gif
實(shí)現(xiàn)代碼
kotlin代碼部分
class ClearableEditText @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : AppCompatEditText(context, attributeSet) {
private var clearBitmap: BitmapDrawable
private val paint = Paint()
private val clearRectF = RectF()
private val clickDetectRectF = RectF()
init {
val a = context.obtainStyledAttributes(attributeSet, R.styleable.ClearableEditText)
val drawableId = a.getResourceId(R.styleable.ClearableEditText_cet_clear_drawable, -1)
val bitmap = if (drawableId == -1) {
BitmapFactory.decodeResource(resources, R.drawable.mcbd__ic_close_2)
} else {
BitmapFactory.decodeResource(resources, drawableId)
}
clearBitmap = BitmapDrawable(resources, bitmap)
a.recycle()
doAfterTextChanged { postInvalidate() }
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (event?.action == MotionEvent.ACTION_UP) {
if (!text.isNullOrEmpty() && clickDetectRectF.contains(event.x, event.y)) {
text = null
return true
}
}
return super.onTouchEvent(event)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
clearRectF.set(
measuredWidth - paddingEnd - clearBitmap.intrinsicWidth.toFloat(),
(measuredHeight - clearBitmap.intrinsicHeight) / 2f,
measuredWidth - paddingEnd.toFloat(),
(measuredHeight + clearBitmap.intrinsicHeight) / 2f
)
clickDetectRectF.set(
clearRectF.left - CLICK_EXPAND,
clearRectF.top - CLICK_EXPAND,
clearRectF.right + CLICK_EXPAND,
clearRectF.bottom + CLICK_EXPAND
)
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (!text.isNullOrEmpty()) {
canvas?.drawBitmap(clearBitmap.bitmap, clearRectF.left, clearRectF.top, paint)
}
}
companion object {
//點(diǎn)擊范圍判定的延伸距離
private const val CLICK_EXPAND = 20
}
}
其中, CLICK_EXPAND這個(gè)東西是產(chǎn)品說(shuō)點(diǎn)擊的那個(gè)圖標(biāo)太小了, 不好點(diǎn), 所以專門把點(diǎn)擊區(qū)域放大了一點(diǎn)點(diǎn), 如果不需要這個(gè)操作,刪了就是
自定義屬性部分
<declare-styleable name="ClearableEditText">
<attr name="cet_clear_drawable" format="reference"/>
</declare-styleable>
只有這一個(gè)屬性, 用于決定后面的清除圖標(biāo)的樣式, 如果需要代碼中動(dòng)態(tài)設(shè)置, 需要改改代碼去實(shí)現(xiàn).