自带删除功能的EditText

开始

先上图:
自带删除功能的editText

相信很多人都有这样的需求,就是在EditText中输入内容时希望后面可以出现一个小删除按钮,点击删除按钮可以直接将刚刚输入的内容清除,这样就不用按键盘上的删除按钮一个一个删了。

代码实现分析

实现这个功能的方式有很多,我用的办法是自定义控件的方式,这种方式使用起来特别方便,只需要在布局文件中一引用就可以啦!

这个控件现实起来两个地方有点小难度,
1.把小删除图标画出来
2.为小删除图标设置点击事件

ok,废话不多说啦,直接贴代码:

package com.uips.ustopcar.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.EditText;

import com.uips.ustopcar.R;

/**
 - @funtion 有文字时自带清除文字功能
 - Created by gaoqingliang on 2017/6/6.
 */
public class ExtendEditText extends EditText implements TextWatcher {
    public ExtendEditText(Context context) {
        super(context);
        this.addTextChangedListener(this);
    }

    public ExtendEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.addTextChangedListener(this);
    }

    public ExtendEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.addTextChangedListener(this);
    }
    private int left;
    private int top;
    private int right;
    private int bottom;
    //是否显示 "删除文字按钮"
    private boolean isShowDeleteBtn = false;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(isShowDeleteBtn){
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.close_2);
        int bitmapWidth =  bitmap.getWidth();
        int bitmapHeight =  bitmap.getHeight();
        int editTextWidth = this.getWidth();
        int editTextHeight = this.getHeight();
        //圆×的位置
        left = editTextWidth - bitmapWidth - 5;
        top = editTextHeight/2 - bitmapHeight/2;
        right = editTextWidth;
        bottom = editTextHeight - ((editTextHeight-bitmapHeight)/2);
        canvas.drawBitmap(bitmap,left,top,null);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(isShowDeleteBtn) {
            float eventX = event.getX();
            float eventY = event.getY();
            //判断当前点击的位置  是否在清除图标的位置  如果是就清除文字
            if (eventX > left - 10 && eventX < right + 10 && eventY > top - 5 && eventY < bottom + 5) {
                this.setText("");
                hideDeleteBtn();
            }
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        if(TextUtils.isEmpty(text)){
            hideDeleteBtn();
        }else{
            showDeleteBtn();
        }
    }

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

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
    /**
     * 显示删除按钮
     */
    private void showDeleteBtn(){
        isShowDeleteBtn = true;
        invalidate();
    }
    /**
     * 隐藏删除按钮
     */
    private void hideDeleteBtn(){
        isShowDeleteBtn = false;
        invalidate();
    }
}

ok,说一下实现逻辑其实特别简单,哈哈

1.创建类ExtendEditText 并继承 EditText
2.覆盖onDraw方法
3.把那个小删除图标 转成bitmap(因为一会要把它画到edittext上)

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.mipmap.close_2);

4.准备小删除图标的位置,也就是你想把它画到哪?

left = editTextWidth - bitmapWidth - 5;
top = editTextHeight/2 - bitmapHeight/2;

代码中通过left和top就能确定 小删除图标的位置,left是小删除图标距离当前控件左边的位置,top是小删除图标距离当前控件上边的位置。
上面代码的 bitmapWidth - 5 是把小图标在往左移动5个像素,不然小删除图标就靠在最右面了,不好看。
top大家就自己算一下吧,控件高度/2 - 小删除图标/2 = 小删除图标在控件中间上边缘的位置

5.该准备的都准备差不多拉,下面调用这个方法一画小删除图标就出来喽

canvas.drawBitmap(bitmap,left,top,null);

6.小删除图标画出来了,下面我们再为它设置个点击事件,点击事件的思想就是用onTouchEvent事件得知当前用户点击的位置,如果点击的位置正好是我们小删除图标的位置,那就证明小删除图标被点击了。
也就是这段代码:

 @Override
    public boolean onTouchEvent(MotionEvent event) {     
            float eventX = event.getX();
            float eventY = event.getY();
            //判断当前点击的位置  是否在清除图标的位置  如果是就清除文字
            if (eventX > left - 10 && eventX < right + 10 
            && eventY > top - 5 && eventY < bottom + 5) {
                this.setText("");
                hideDeleteBtn();
            }      
        return super.onTouchEvent(event);
    }

通过:

float eventX = event.getX();
float eventY = event.getY();

得到当前用户点击的位置,上面我们在画小删除图标时已经知道小删除图标的位置和大小,就是它们4个

left = editTextWidth - bitmapWidth - 5;
top = editTextHeight/2 - bitmapHeight/2;
right = editTextWidth;
bottom = editTextHeight - ((editTextHeight-bitmapHeight)/2);

然后接下来就简单啦,我们拿着用户点击的位置判断,如果用户点击的位置在小删除图标的范围内,就证明小删除图标被点击了,就是下面这段代码:

if (eventX > left - 10 && eventX < right + 10
&& eventY > top - 5 && eventY < bottom + 5) {
}

那个-10 ,+10 ,-5,+5 的作用是我把小图标的点击范围扩大了,不然只用小图标的范围有点小,不好点击。

7.好啦,主要功能我们都实现完啦,接下来我们再让它完美一点,就是当用户输入文字时才显示小删除图标,没有文字时不显示删除小图标,这个就比较简单啦,我们先写个标记 默认为false不显示

//是否显示 “删除小图标按钮”
private boolean isShowDeleteBtn = false;

然后在创建两个方法

 /**
     * 显示删除按钮
     */
    private void showDeleteBtn(){
        isShowDeleteBtn = true;
        invalidate();
    }
    /**
     * 隐藏删除按钮
     */
    private void hideDeleteBtn(){
        isShowDeleteBtn = false;
        invalidate();
    }

invalidate()方法就是刷新当前view重新绘制的意思。
还有个需要注意的地方就是 我们都在哪用到了 isShowDeleteBtn这个标记,一个是onDraw方法里面,一个是点击事件里面。
isShowDeleteBtn为false时没有点击事件,和不画小删除图标,true则相反。
8.最后就是调用这两个方法了,刚刚我们说了 当有内容输入时就显示小删除图标,这个时候我们就需要给当前控件添加一个addTextChangedListener事件了,这个事件里有这样一个方法

public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        if(TextUtils.isEmpty(text)){
            hideDeleteBtn();
        }else{
            showDeleteBtn();
        }
    }

这个方法可以监听当前是否有内容正在输入,有的话就显示小图标,没有就不显示小图标,就是这句代码

if(TextUtils.isEmpty(text)){
            hideDeleteBtn();
        }else{
            showDeleteBtn();
        }

ok,到这里就完事喽!

怎么使用?

很简单,跟使用 edittext一样,注意引用时的包名全路径

<com.uips.uspcar.view.ExtendEditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@null"
      android:hint="请输入密码"
      android:inputType="textPassword"
      android:textColorHint="#c3c6c8"
      android:maxLength="20"
      android:textSize="19sp" />

这里写图片描述
这是那个小删除图标

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Granger_g

大爷,赏小女子口饭吃如何?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值