项目中需要用到一个功能,需要在编辑框有内容时显示删除按钮,在没有内容的时候也能点击搜索
常用的做法有两种:
1、通过组合布局方式:LinearLayout + EditText+ImageView
2、继承EditText,初始化的时候填充右侧drawable
本次采用第二种,少套用一层布局
操作如下:
1、在value/attrs.xml 文件下 添加自定义属性
<declare-styleable name="SearchEditText">
<attr name="rightWidth" format="dimension" />
<attr name="rightHeight" format="dimension" />
</declare-styleable>
2、继承EditText
@SuppressLint("AppCompatCustomView")
class SearchEditText @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = android.R.attr.editTextStyle
) : EditText(context, attrs, defStyleAttr), TextWatcher {
private var rightDrawableWidth: Int = 10
private var rightDrawableHeight: Int = 10
private var mClearDrawable: Drawable? = null
private var mSearchDrawable: Drawable? = null
init {
//扩展属性
val typedArray =
context.obtainStyledAttributes(
attrs,
R.styleable.SearchEditText,
android.R.attr.editTextStyle,
0
)
rightDrawableHeight = typedArray.getDimensionPixelSize(
R.styleable.SearchEditText_rightHeight,
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
20f,
resources.displayMetrics
).toInt()
)
rightDrawableWidth = typedArray.getDimensionPixelSize(
R.styleable.SearchEditText_rightWidth,
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
20f,
resources.displayMetrics
).toInt()
)
typedArray.recycle()
//获取图片
if (mClearDrawable == null) {
mClearDrawable = resources.getDrawable(
R.drawable.clear_help, null
)
}
if (mSearchDrawable == null) {
mSearchDrawable = resources.getDrawable(
R.drawable.icon_serach, null
)
}
setDrawableSize(mClearDrawable)
setDrawableSize(mSearchDrawable)
showClean(false)
// 设置输入框里面内容发生改变的监听
addTextChangedListener(this)
// setSelectAllOnFocus(true)
}
//设置图片的高度和宽度
private fun setDrawableSize(
drawable: Drawable?
) {
if (drawable == null) {
return
}
//左上右下
var width = 0
var height = 0
width = rightDrawableWidth
height = rightDrawableHeight
//如果没有设置图片的高度和宽度具使用默认的图片高度和宽度
if (width < 0) {
width = UIUtils.dip2Px(20f)
}
if (height < 0) {
height = UIUtils.dip2Px(20f)
}
drawable.setBounds(0, 0, width, height)
}
fun setRightView(cleanResId: Int = 0, searchResId: Int = 0) {
if (cleanResId != 0) {
mClearDrawable = resources.getDrawable(
cleanResId, null
)
setDrawableSize(mClearDrawable)
}
if (searchResId != 0) {
mSearchDrawable = resources.getDrawable(
searchResId, null
)
setDrawableSize(mSearchDrawable)
}
showClean(text.toString().isNotEmpty())
}
private fun showClean(show: Boolean) {
val drawable = if (show) mClearDrawable else mSearchDrawable
//放置图片
setCompoundDrawables(
null,
null,
drawable,
null
)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
if (compoundDrawables[2] != null) {
val x = event.x.toInt()
// val y = event.y.toInt()
// val rect = compoundDrawables[2].bounds
// val height = rect.height()
// val distance = (getHeight() - height) / 2
//判断点击的区域 右侧区域的最小范围 = 误差在5px 这个操作是为了避免区域太小而手指太差导致不能精准点击区域
val isInnerWidth = x >= width - totalPaddingRight - 5 && x <= width - paddingRight - 5
// val isInnerHeight = y > distance && y < distance + height
if (isInnerWidth /*&& isInnerHeight*/) {
val str = text.toString().trim()
if (str.isNotEmpty()) {
this.setText("")
mOnSearchListener?.onClean()
} else {
//搜索
mOnSearchListener?.onSearch(str)
}
return true
}
}
}
return super.onTouchEvent(event)
}
override fun onTextChanged(
text: CharSequence,
start: Int,
lengthBefore: Int,
lengthAfter: Int
) {
val str = text.toString().trim()
showClean(str.isNotEmpty())
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable?) {
}
var mOnSearchListener: OnSearchListener? = null
fun setOnSearchListener(onSearchListener: OnSearchListener) {
mOnSearchListener = onSearchListener
}
interface OnSearchListener {
fun onClean()
fun onSearch(text: String)
}
}
3、具体使用
<com.****.SearchEditText
android:id="@+id/etSearchKeyword"
style="@style/item_edit"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:hint="品名/货号/条码"
android:imeOptions="actionSearch"
android:minWidth="120dp"
android:paddingHorizontal="5dp"
custom:rightHeight="20dp"
custom:rightWidth="20dp" />
共用编辑属性操作,可根据需要是否添加
<style name="item_edit">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:textColor">@color/color_text_333333</item>
<item name="android:textSize">18sp</item>
<item name="android:gravity">center_vertical</item>
<item name="android:maxLines">1</item>
<item name="android:layout_weight">3</item>
<item name="android:singleLine">true</item>
<item name="android:textColorHighlight">@color/colorGreenV2</item>
<item name="android:background">@drawable/gray_stroke_radius5_bg</item>
<item name="android:selectAllOnFocus">true</item>
<!-- 光标颜色-->
<item name="android:textCursorDrawable">@drawable/shape_edit_cursor_bg</item>
</sty
光标颜色:shape_edit_cursor_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="2dp"/>
<solid android:color="@color/colorGreenV2"/>
</shape>
4、代码中接收事件处理逻辑
etSearchKeyword.setOnSearchListener(object :SearchEditText.OnSearchListener{
override fun onClean() {
searchKeyword("")
}
override fun onSearch(text: String) {
searchKeyword(text)
}
})
本文介绍了如何在Android开发中创建一个自定义的SearchEditText组件,该组件在编辑框有内容时显示删除按钮,无内容时可进行搜索操作。通过继承EditText,设置自定义属性,以及监听文本变化来动态显示或隐藏清除图标。

4924

被折叠的 条评论
为什么被折叠?



