Android带清除按钮的文本框
大部分的android应用中的文本框都带有清除按钮,在输入长文本后可以一次清除所有输入,实现的思路有很多,比如直接用EditText+ImageView,但是每个文本框都要这么搞麻烦不说,且不利于维护。
本文的实现思路是通过继承EditText,并通过复写draw方法,将清除按钮画出来,然后通过监听onTouchEvent方法,判定用户是否点击了draw出来的区域进而判定是否需要清除文本。
以下是两种方式区别不大,方法一使用了资源图片作为清除按钮,方法二使用了android的绘图api绘制清除按钮。
方法一:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.EditText;public class MyEditText extends EditText implements TextWatcher {private float density;private boolean drawableShown = false;private Drawable drawable;private int drawableWidth;private int drawableHeight;private int paddingLeft;private int paddingTop;private int paddingRight;private int paddingBottom;public MyEditText(Context context, AttributeSet attrs) {super(context, attrs);// 密度density = context.getResources().getDisplayMetrics().density;// 删除图标drawable = getResources().getDrawable(R.drawable.sdk_cancel);drawableWidth = drawable.getIntrinsicWidth();drawableHeight = drawable.getIntrinsicHeight();paddingLeft = getPaddingLeft();paddingTop = getPaddingTop();paddingRight = getPaddingRight();paddingBottom = getPaddingBottom();setPadding(paddingLeft, paddingTop, paddingRight + drawableWidth, paddingBottom);addTextChangedListener(this);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (drawable.getBounds().contains((int)event.getX(), (int)event.getY())) {return true;}break;case MotionEvent.ACTION_UP:if (drawable.getBounds().contains((int)event.getX(), (int)event.getY())) {// 删除文本setText("");// 重新请求布局requestLayout();return true;}break;}return super.onTouchEvent(event);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);if (!TextUtils.isEmpty(getText())) {int width = drawableWidth; // 图标宽int height = drawableHeight; // 图标高int w = right - left; // 控件宽int h = bottom - top; // 控件高width = Math.min(width, w);height = Math.min(height, h);width = height = Math.min(width, height);// 设置图标已显示drawableShown = true;int l = w - width;l = l <= 0 ? 0 : l - (w - l - getDp(getPaddingLeft() + getPaddingRight())) / 2;int t = (h-height)/2;int r = l + width;int b = t + height;drawable.setBounds(l, t, r, b);} else {// 设置图标已隐藏drawableShown = false;drawable.setBounds(0, 0, 0, 0);}}@Overridepublic void draw(Canvas canvas) {super.draw(canvas);// 将图标绘制到界面drawable.draw(canvas);}@Overridepublic void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {super.onTextChanged(text, start, lengthBefore, lengthAfter);}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void afterTextChanged(Editable s) {// 当有文本没有显示删除图标时和没有文本显示删除图标时,重新请求布局if ((!drawableShown && !TextUtils.isEmpty(s)) || (drawableShown && TextUtils.isEmpty(s))) {requestLayout();}}private int getPx(int dp) {return (int)(dp * density + 0.5f);}private int getDp(int px) {return (int)(px / density + 0.5f);}}
方法二:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.EditText;public class MyEditText1 extends EditText {private Paint circlePaint;private Paint plusPaint;private Paint clearPaint;private Rect clearRect;private Rect clearRectPx;private int circleRadiusDp;private int circleRadius;private int circlePaddingDp;private int circlePadding;private int clearRectBox;public MyEditText1(Context context, AttributeSet attrs) {super(context, attrs);circlePaint = new Paint();circlePaint.setColor(Color.GRAY);plusPaint = new Paint();plusPaint.setColor(Color.WHITE);plusPaint.setStrokeWidth(getPx(5));clearPaint = new Paint();clearPaint.setColor(Color.argb(0, 0, 0, 0));clearRect = new Rect();clearRectPx = new Rect();circleRadiusDp = 10;circleRadius = getPx(circleRadiusDp);circlePaddingDp = 3;circlePadding = getPx(circlePaddingDp);clearRectBox = circleRadiusDp * 2 + circlePaddingDp * 2;//if (0 == getPaddingRight() || getPaddingRight() < getPx(clearRectBox)) {setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight() + getPx(clearRectBox), getPaddingBottom());}}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (MotionEvent.ACTION_DOWN == event.getAction()) {if (clearRect.contains((int)event.getX(), (int)event.getY())) {return true;}} else if (MotionEvent.ACTION_UP == event.getAction()) {if (!TextUtils.isEmpty(getText()) && clearRect.contains((int)event.getX(), (int)event.getY())) {setText("");return true;}}return super.onTouchEvent(event);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);int l = right - left - clearRectBox*2 - getDp(getPaddingLeft() - getDp(getPaddingRight()));int t = (bottom - top - clearRectBox - getDp(getPaddingTop()) - getDp(getPaddingBottom())) / 2 + getDp(getPaddingTop());int r = l + clearRectBox;int b = t + clearRectBox;clearRect.set(l-clearRectBox, t-clearRectBox, r+clearRectBox, b+clearRectBox);clearRectPx.set(l, t, r, b);}@Overridepublic void draw(Canvas canvas) {super.draw(canvas);if (!TextUtils.isEmpty(getText())) {canvas.drawRect(clearRect, clearPaint);canvas.translate(clearRectPx.centerX(), clearRectPx.centerY());canvas.save();canvas.drawCircle(0, 0, circleRadius, circlePaint);canvas.restore();canvas.save();canvas.rotate(45);canvas.translate(-(circleRadius - circlePadding), 0);canvas.drawLine(0, 0, circleRadius*2 - circlePadding*2, 0, plusPaint);canvas.restore();canvas.save();canvas.rotate(135);canvas.translate(-(circleRadius - circlePadding), 0);canvas.drawLine(0, 0, circleRadius*2 - circlePadding*2, 0, plusPaint);canvas.restore();}}private int getPx(int dp) {return (int)(dp * getContext().getResources().getDisplayMetrics().density + 0.5f);}private int getDp(int px) {return (int)(px / getContext().getResources().getDisplayMetrics().density + 0.5f);}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
