Android自定义带搜索图标及删除按钮的搜索框SearchEditText

最近项目需求要用到带删除按钮的搜索框,开始设计时搜索图标及提示文字是在左侧的,但是经讨论要求与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>

猜你喜欢

转载自blog.csdn.net/u014611408/article/details/86599178