android 在编辑文本时经常会用到一些功能按钮,例如输入密码时后面显示一个眼睛图标或者显示一键清理图标, 如果采用多ViewGroup嵌套,很容易就能解决问题,但是这样真的好吗,其实不然, 咱们也可以直接继承EditText对它背景进行绘制,思路很简单, 将Drawable 绘制到Canves再转成BitmapDrawable 设置成背景, 不然每次在onDraw方法中绘制挺耗性能的,贴上主要代码
package com.dy.mydemo;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
/**
* @author DaiYao
*/
public class EditTextExtend extends android.support.v7.widget.AppCompatEditText implements TextWatcher {
private int drawableSize;
private Drawable drawableRight;
private Rect drawableClickRect;
private Rect drawableBounds;
private boolean isDisplayIcon;
private Bitmap bgBitmap;
public EditTextExtend(Context context) {
this(context, null);
}
public EditTextExtend(Context context, AttributeSet attrs) {
this(context, attrs, android.support.v7.appcompat.R.attr.editTextStyle);
}
public EditTextExtend(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(attrs);
}
private void initView(AttributeSet attrs) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.EditTextExtend);
int drawableRightRes = typedArray.getResourceId(R.styleable.EditTextExtend_drawableRight,
R.mipmap.icon_close);
drawableSize = typedArray.getDimensionPixelSize(R.styleable.EditTextExtend_drawableSize,
dp2px(getContext(), 17));
typedArray.recycle();
drawableRight = ContextCompat.getDrawable(getContext(), drawableRightRes);
addTextChangedListener(this);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bgBitmap == null) {
bgBitmap = Bitmap.createBitmap(getWidth(),
getHeight(),
Bitmap.Config.ARGB_8888);
Canvas bgCanvas = new Canvas(bgBitmap);
if (drawableBounds == null) {
drawableBounds = new Rect(0, 0, drawableSize, drawableSize);
drawableRight.setBounds(drawableBounds);
}
bgCanvas.save();
//垂直居中 右对齐 找到偏移Y
int offsetPadding = (getHeight() - drawableBounds.height()) / 2;
int offsetX = getWidth() - drawableBounds.width() - drawableBounds.width() / 2;
bgCanvas.translate(offsetX, offsetPadding);
drawableRight.draw(bgCanvas);
if (drawableClickRect == null) {
drawableClickRect = new Rect(offsetX - offsetPadding,
0,
offsetX + drawableBounds.width() + offsetPadding,
getHeight());
}
setBackgroundDrawable(new BitmapDrawable(getResources(), bgBitmap));
int drawableWidth = drawableBounds.width() + offsetPadding;
int minRightPadding = drawableWidth < getPaddingRight() ?
getPaddingRight() :
drawableWidth;
setPadding(getPaddingLeft(), getPaddingTop(), minRightPadding, getPaddingBottom());
bgCanvas.restore();
afterTextChanged(getEditableText());
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isDisplayIcon) {
boolean contains = drawableClickRect.contains(
(int) event.getX(),
(int) event.getY());
if (contains) {
setText(null);
return true;
}
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s == null || TextUtils.isEmpty(s.toString())) {
isDisplayIcon = false;
} else {
isDisplayIcon = true;
}
setBackgroundDrawable(
isDisplayIcon ?
new BitmapDrawable(getResources(), bgBitmap) :
null);
}
/**
* DP转PX
*/
public static int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal,
context.getResources()
.getDisplayMetrics());
}
}
这样就能显示一键清理文本的效果了,代码提供思路, 如果要封装的更加完美就需要你自己来动手了
网友评论