最近项目需求要用到带删除按钮的搜索框,开始设计时搜索图标及提示文字是在左侧的,但是经讨论要求与IOS的UISearchBar风格一致即默认情况下,搜索图标和文字是居中的,在获取焦点时,图标及提示文字左移,输入搜索文字时,删除按钮右端显示,如下图所示:
默认情况:
获取焦点时:
输入文字后:
首先直接自定义SearchEditText:
@SuppressLint("AppCompatCustomView")
public class SearchEditText extends EditText implements View.OnFocusChangeListener, TextWatcher {
private static final String TAG = "SearchEditText";
/**
* 删除按钮与右边编辑框之间的paddingRight距离
*/
private int paddingRightValueBetweenRightBorderAndDel = 0;
/**
* 图标是否默认在左边
*/
private boolean isIconLeft = false;
/**
* 控件的图片资源
*/
private Drawable[] mDrawables;
/**
* drawableLeft:搜索图标; drawableDel:删除按钮图标
*/
private Drawable drawableLeft, drawableDel;
/**
* 记录点击坐标
*/
private int eventX, eventY;
/**
* 控件区域
*/
private Rect mRect;
public SearchEditText(Context context) {
super(context);
init();
}
public SearchEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SearchEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public SearchEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init(){
setOnFocusChangeListener(this);
addTextChangedListener(this);
}
@Override
protected void onDraw(Canvas canvas){
if(isIconLeft){
if(length() < 1){
drawableDel = null;
}
this.setCompoundDrawablesWithIntrinsicBounds(drawableLeft, null, drawableDel, null); //在edittext的左上右下设置Drawable
super.onDraw(canvas);
}else {
if(mDrawables == null){
mDrawables = getCompoundDrawables(); //返回包含左上右下四个位置的Drawable数组
}
if(drawableLeft == null){
drawableLeft = mDrawables[0];
}
float textWidth = getPaint().measureText(getHint().toString());
int drawablePadding = getCompoundDrawablePadding(); //返回Drawable和text之间的padding值
int drawableWidth = drawableLeft.getIntrinsicWidth(); //获得Drawable的固有宽度
float bodyWidth = textWidth + drawablePadding + drawableWidth;
canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);
super.onDraw(canvas);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(drawableDel != null && event.getAction() == MotionEvent.ACTION_UP){
eventX = (int)event.getRawX();
eventY = (int)event.getRawY();
if(mRect == null){
mRect = new Rect();
}
getGlobalVisibleRect(mRect); // edittext在屏幕中的坐标
mRect.left = mRect.right - drawableDel.getIntrinsicWidth() - getPaddingRightValueBetweenRightBorderAndDel();
if(mRect.contains(eventX, eventY)){
setText("");
}
}
// if(drawableDel != null && event.getAction() == MotionEvent.ACTION_DOWN){
// eventX = (int)event.getRawX();
// eventY = (int)event.getRawY();
// if(mRect == null){
// mRect = new Rect();
// }
// getGlobalVisibleRect(mRect);
// mRect.left = mRect.right - drawableDel.getIntrinsicWidth();
// if(mRect.contains(eventX, eventY)){
// drawableDel = this.getResources().getDrawable(R.mipmap.clear_edit);
// }else {
// drawableDel = this.getResources().getDrawable(R.mipmap.clear_edit);
// }
// }
return super.onTouchEvent(event);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(this.length() < 1){
drawableDel = null;
}else {
drawableDel = this.getResources().getDrawable(R.mipmap.clear_edit);
}
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(TextUtils.isEmpty(getText().toString())){
isIconLeft = hasFocus;
}
}
public void setPaddingRightValueBetweenRightBorderAndDel(int dimenID){
this.paddingRightValueBetweenRightBorderAndDel = dimenID;
}
private int getPaddingRightValueBetweenRightBorderAndDel(){
return this.getResources().getDimensionPixelOffset(paddingRightValueBetweenRightBorderAndDel);
}
}
搜索框样式:
<!--搜索框样式-->
<style name="editTextStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:background">@drawable/search_edit_text_bg</item>
<item name="android:drawablePadding">@dimen/dp_2</item>
<item name="android:drawableStart">@mipmap/search_icon</item>
<item name="android:gravity">center_vertical</item>
<!--<item name="android:imeOptions">actionSearch</item>-->
<item name="android:paddingLeft">@dimen/dp_15</item>
<item name="android:paddingRight">@dimen/dp_15</item>
<item name="android:singleLine">true</item>
<item name="android:textSize">@dimen/sp_11</item>
<item name="android:hint">@string/please_input_search_name</item>
<item name="android:textColorHint">#B3B3B3</item>
</style>
搜索框背景:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
<corners android:radius="@dimen/dp_15"/>
<stroke android:color="#D9D9D9" android:width="@dimen/dp_1"/>
</shape>
</item>
</layer-list>
布局代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:focusable="true"
android:focusableInTouchMode="true"
tools:context=".MainActivity" >
<SearchEditText
android:id="@+id/activity_main_input_edittext"
style="@style/editTextStyle"
android:layout_marginTop="20dp" />
</RelativeLayout>