1. 效果图
2. 代码
class ClearEditText @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : AppCompatEditText(context, attributeSet) {
init {
// 添加文本改变监听器
addTextChangedListener {
val end = if (text.toString().isEmpty()) null else ResourcesCompat.getDrawable(
resources, R.drawable.baseui_ic_edit_delete, null
)
end?.setBounds(0, 0, 42, 42)
setCompoundDrawables(null, null, end, null)
setPadding(20, 0, 20, 0)
}
// 设置点击关闭按钮
setOnTouchListener { v, event ->
performClick()
var completed = false
if (v is EditText && event.x >= width - v.totalPaddingRight && event.action == MotionEvent.ACTION_UP) {
setText("")
completed = true
}
completed
}
}
}
3. 增加SetText后光标移动到最后的逻辑
class ClearEditText @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : AppCompatEditText(context, attributeSet) {
init {
// 添加文本改变监听器
addTextChangedListener {
// 当内容为空后,就不要再显示图标了
if (text.toString().isEmpty()) {
hideClearIcon()
} else {
// 就算有内容,也要获取到焦点后才能显示
if (isFocused) {
showClearIcon()
}
}
}
// 设置点击关闭按钮
setOnTouchListener { v, event ->
performClick()
var completed = false
if (v is EditText && event.x >= width - v.totalPaddingRight
&& event.action == MotionEvent.ACTION_UP
) {
setText("")
completed = true
}
completed
}
// 设置监听焦点状态改变事件
setOnFocusChangeListener { view, b ->
if (text != null && !text.toString().isEmpty()) {
if (b) {
showClearIcon()
val len = text.toString().length
if (len > 0) {
setSelection(len)
}
} else {
hideClearIcon()
}
}
}
}
/**
* 显示清除图标
*/
private fun showClearIcon() {
val end = ResourcesCompat.getDrawable(resources, R.drawable.baseui_ic_edit_delete, null)
end?.setBounds(0, 0, 42, 42)
setCompoundDrawables(null, null, end, null)
// 使用原来的内边距
setPadding(paddingLeft, 0, 20, 0)
}
/**
* 隐藏清除图标
*/
private fun hideClearIcon() {
setCompoundDrawables(null, null, null, null)
}
}
4. 图标大小适配
/**
* 显示清除图标
*/
private fun showClearIcon(context: Context) {
val end = ResourcesCompat.getDrawable(resources, R.drawable.baseui_ic_edit_delete, null)
end?.setBounds(0, 0, DensityUtil.px2dip(context, 20.0f), DensityUtil.px2dip(context, 20.0f))
setCompoundDrawables(null, null, end, null)
// 使用原来的内边距
setPadding(paddingLeft, 0, DensityUtil.px2dip(context, 10.0f), 0);
}
// Java
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
5. 参考文章
- https://zhuanlan.zhihu.com/p/541155880
- https://zinyan.com/?p=205