带删除按钮的 EditText

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/miao9999/article/details/73530674

一个带删除按钮的 EditText 在各种 APP 中随处可见,比如,搜索框、登录时用户名与密码的输入框等等。在没有自己实现之前,想法是这样的:在 EditText 中的添加一个 Drawable 然后给这个 Drawable 添加一个监听事件,当点击 Drawable 时设置 EditText 里的字符串为空。当要实现的时候却发现 Drawable 没有点击事件,所以这个方法是行不通的。那么只好通过触摸事件来实现,通过计算触摸的位置,这个位置正好就是该 Drawable 所在的位置。

  1. 获取 EditText 的 DrawableRight

    mClearDrawable = getCompoundDrawables()[2];
    

    getCompoundDrawables() 方法源码是这样的

 /**
        * Returns drawables for the left, top, right, and bottom borders.
        *
        * @attr ref android.R.styleable#TextView_drawableLeft
        * @attr ref android.R.styleable#TextView_drawableTop
        * @attr ref android.R.styleable#TextView_drawableRight
        * @attr ref android.R.styleable#TextView_drawableBottom
        */
        @NonNull
        public Drawable[] getCompoundDrawables() {
        final Drawables dr = mDrawables;
        if (dr != null) {
            return dr.mShowing.clone();
        } else {
            return new Drawable[] { null, null, null, null };
        }
        }

返回值是控件四周的 Drawable 数组,顺序为左、上、右、下。在这里需要的是右边的 Drawable,所以下标为 2.
2. 接下来就是获取并设置 Drawable 图标

if (mClearDrawable == null) {
            mClearDrawable = getResources().getDrawable(R.drawable.x);
        }
        // 为 Drawable 设置为自身大小的宽高
         mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());

3.最后一步就是设置点击 Drawable 图标实现删除文本框中的内容

@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() - getPaddingRight()));
               if (touchable){
                   this.setText("");
               }
           }
       }
        return super.onTouchEvent(event);
        }

clear

红色的横线代表的是 (getWidth() - getTotalPaddingRight())的值,黑色的横线代表的是 (getWidth() - getPaddingRight()) 的值,当触摸到这两个值之间的位置就正好是 Drawable 所在位置。也就实现了点击删除图标就可以清空文本框中的内容。

到此最主要功能就可以实现了,当然还可以再添加一些其他的功能,以提高用户体验。比如,当文本框中没有内容时,就不显示删除图标,或是在输入错误时文本框抖动等。

首先实现删除图标的隐藏功能。

public void setClearIconVisible(boolean visible) {
        Drawable right = visible ? mClearDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1],right,getCompoundDrawables()[3]);

        }

setCompoundDrawables() 方法里的四个参数就是按照左、上、右、下的顺序分别为组件添加四个方向上的 Drawable。这里添加的在右边的,所以在第三个位置设置刚刚设置好的 Drawable。其他设置为默认的。然后实 TextWatcher 接口,在 onTextChange 方法里进行设置。

public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        if (hasFocus){
            setClearIconVisible(text.length() > 0);
        }
        }

接下来实现抖动功能。

public void setSharkAnimation(){
           this.setAnimation(sharkAnimation(5));
            }

public static Animation sharkAnimation(int counts){
       Animation translateAnimation = new TranslateAnimation(0,10,0,0);
       translateAnimation.setInterpolator(new CycleInterpolator(counts));
       translateAnimation.setDuration(1000);
          return translateAnimation;
        }   

在输入错误或是有重要信息时调用 setSharkAnimation() 方法就可以实现了。

最终效果图:
clear

总结

实现文章中的功能并不是很难,只要动动手基本都可以实现。所以重点是要动手去做,在没有动手之前虽然也有很多的想法,想了几种可能实现的方法,那些方法到底能不能实现,或是实现起来有什么困难,亦或是可以更加简洁等等,这些都不是只靠想就可以做到的,所以以后再想到什么想法的时候一定要亲自动手实践一下,再做结论。以上!

猜你喜欢

转载自blog.csdn.net/miao9999/article/details/73530674