开始
先上图:
相信很多人都有这样的需求,就是在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" />
这是那个小删除图标