自动搜索EditText,带删除图标

本文介绍了一个自动搜索EditText的需求,当用户输入字符时自动搜索,并在输入框有字符时显示删除图标。通过监听EditText内容变化,实现自动搜索功能,并在EditText焦点且有字符时显示清除图标。代码中展示了布局文件、MainActivity、和自定义AutoSearchClearEditText的实现,包括触摸事件的处理来触发清除功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

最近项目里需要一个搜索框,其需求是这样的:当用户输入字符,将自动进行搜索,且搜索框中有字符时,显示一个删除icon,点击可以清空输入框。

分析

在这两个功能我们都需要监听EditText中输入字符的变化
1. 自动搜索:
这里我们可以采用接口回调的机制来完成。
2. 清空按钮:
首先判断EditText中的字符长度,如果字符的长度大于0且有焦点的时候让图标显示。

代码

  • 布局文件 activity_main.xml
<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"
    tools:context="com.dd.test.MainActivity" >

    <com.dd.test.AutoSearchClearEditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_centerInParent="true"
        android:layout_margin="5dp"
        android:drawableRight="@drawable/delete"
        android:padding="2dp" />

</RelativeLayout>

布局文件很简单,添加一个自定义的EditText,让其居中显示。其中android:drawleRight=”@drawable/delete”这里是为EditText的右侧显示一张清空图标。

  • MainActivity.class
public class MainActivity extends Activity implements OnAutoSearchListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AutoSearchClearEditText et = (AutoSearchClearEditText) findViewById(R.id.et);
        et.setOnAutoSearchListener(this);
    }

    @Override
    public void search(String s) {
        Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
    }

}

在这里MainActivity实现了一个叫OnAutoSearchListener的接口,这是自定义的一个回调接口,去实现自动搜索功能。search(String s) 是具体的实现方法,这里用了Toast来做测试。

  • AutoSearchClearEditText.class
public class AutoSearchClearEditText extends EditText implements
        OnFocusChangeListener, TextWatcher {

    /** 清空图标 **/
    private Drawable mClearDrawable;

    /** 是否获得焦点 **/
    private boolean hasFocus;

    private OnAutoSearchListener onAutoSearchListener;

    public interface OnAutoSearchListener {
        public void search(String s);
    }

    public void setOnAutoSearchListener(
            OnAutoSearchListener onAutoSearchListener) {
        this.onAutoSearchListener = onAutoSearchListener;
    }

    public AutoSearchClearEditText(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public AutoSearchClearEditText(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.editTextStyle);
    }

    public AutoSearchClearEditText(Context context) {
        this(context, null);
    }

    private void init() {
        // 获取EditText最右侧的删除图标
        mClearDrawable = this.getCompoundDrawables()[2];
        if (mClearDrawable == null) {
            mClearDrawable = getResources().getDrawable(R.drawable.delete);
        }
        mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(),
                mClearDrawable.getIntrinsicHeight());
        // 默认右侧删除图标不可见
        setClearIconVisible(false);

        setOnFocusChangeListener(this);
        addTextChangedListener(this);
    }

    /**
     * 
     * 设置右侧的删除图标是否可见
     * 
     * @param visible
     */
    public void setClearIconVisible(boolean visible) {
        Drawable drawable = visible ? mClearDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0],
                getCompoundDrawables()[1], drawable, getCompoundDrawables()[3]);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
    }

    @Override
    public void afterTextChanged(Editable s) {
        onAutoSearchListener.search(s.toString());
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        this.hasFocus = hasFocus;
        if (hasFocus) {
            // 有焦点时焦点,当EditText里的内容长度>0时,显示图标,否则隐藏图标
            setClearIconVisible(getText().length() > 0);
        } else {
            // 失去焦点,不显示清空图标
            setClearIconVisible(false);
        }
    }

    @Override
    public void onTextChanged(CharSequence text, int start, int lengthBefore,
            int lengthAfter) {
        Log.i("tag", "textChanged");
        if (hasFocus) {
            setClearIconVisible(getText().length() > 0);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {
                // 判断是否触摸的为右侧图标
                boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
                        && (event.getX() < (getWidth() + getTotalPaddingRight()));
                if (touchable) {
                    // 如果触摸了右侧图标,清空文字
                    setText("");
                }
            }
        }
        return super.onTouchEvent(event);
    }

}

这里写图片描述
从上图可以看出在init()方法中,mClearDrawable=getCompoundDrawables()[2]这一行是获取右侧图标,在这里我们看见getCompoundDrawables()是属于TextView的,而我们是继承EditText,为什么也可以这样用呢?

java.lang.Object
 android.view.View
  android.widget.TextView 
   android.widget.EditText

可以看出EditText是TextView的直接子类,所以可以直接用这个方法。

如何监听清空按钮是否被点击?这里覆盖了onTouchEvent(MotionEvent event)方法,通过判断touch的位置,去处理清空EditText

boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
                        && (event.getX() < (getWidth() + getTotalPaddingRight()));

getWidth()返回EditText的宽度,getTotalPaddingRight()返回的是EditText所有的右内边距,在这里我们只做了X轴上的判断。

效果

效果图

源码地址

下载地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值