// 按鈕寬度dp
private int mWidth;
// 按鈕的bitmap
private Bitmap mBitmapInvisible;
private Bitmap mBitmapVisible;
// 按鈕是否可見
private boolean isVisible;
// 清除按鈕出現動畫
private ValueAnimator mAnimatorVisible;
// 消失動畫
private ValueAnimator mAnimatorGone;
// 間隔
private int Interval;
// 內容是否是明文
private boolean isPlaintext = false;
// 是否只在獲得焦點後顯示
private boolean focusedShow = false;
先了解這些變量含義。
/**
* 繪製內容是否是明文的ICON
*/
private void drawVisible(float scale, Canvas canvas) {
int right = (int) (getWidth() + getScrollX() - getmPaddingRight() - Interval - mWidth * (1f - scale) / 2f);
int left = (int) (getWidth() + getScrollX() - getmPaddingRight() - Interval - mWidth * (scale + (1f - scale) / 2f));
int top = (int) ((getHeight() - mWidth * scale) / 2);
int bottom = (int) (top + mWidth * scale);
rect.set(left, top, right, bottom);
if (isPlaintext) {
canvas.drawBitmap(mBitmapVisible, null, rect, null);
} else {
canvas.drawBitmap(mBitmapInvisible, null, rect, null);
}
}
/**
* 只在獲得焦點後顯示
*/
private void focusedShow() {
focusedShow(isFocusable());
}
/**
* 只在獲得焦點後顯示
*/
private void focusedShow(boolean focused) {
if (!TextUtil.isEmpty(getText()) && isEditThis() && focused) {
if (!isVisible) {
isVisible = true;
mAnimatorGone.end();
mAnimatorVisible.end();
mAnimatorVisible.start();
invalidate();
}
} else {
if (isVisible) {
isVisible = false;
mAnimatorGone.end();
mAnimatorVisible.end();
mAnimatorGone.start();
invalidate();
}
}
}
// 按鈕資源
private final int CLEAR = R.mipmap.icon_clear;
// 動畫時長
protected final int ANIMATOR_TIME = 200;
// 按鈕左右間隔,單位PX
private int Interval;
// 清除按鈕寬度,單位PX
private int mWidthClear;
// 左內邊距
private int mPaddingLeft;
// 右內邊距
private int mPaddingRight;
// 右側多出的空間(間隔 + 按鈕寬度)
private int mExtraWidth;
// 清除按鈕的bitmap
private Bitmap mBitmapClear;
// 清除按鈕出現動畫
private ValueAnimator mAnimatorVisible;
// 消失動畫
private ValueAnimator mAnimatorGone;
// 是否顯示的記錄
private boolean isVisible = false;
// 右邊添加其他按鈕時使用
private int mRight = 0;
/**
* EditText內容變化的監聽
*/
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
if (getInputType() == (InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_CLASS_NUMBER) && !TextUtils.isEmpty(text) && text.charAt(0) == '.') {
if (text.length() == 1) {
setText("0.");
} else {
setText(getText().replace(0, 0, "0."));
}
setSelection(getText().length());
}
super.onTextChanged(text, start, lengthBefore, lengthAfter);
if (text.length() > 0 && isFocused() && isEditThis()) {
if (!isVisible) {
isVisible = true;
startVisibleAnimator();
}
} else {
if (isVisible) {
isVisible = false;
startGoneAnimator();
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int additional = 0;
if (getGravity() == Gravity.CENTER || getGravity() == Gravity.CENTER_HORIZONTAL) {
additional = mExtraWidth + mRight + mPaddingRight;
}
// 設置內邊距
setPadding(mPaddingLeft + additional, getPaddingTop(), mExtraWidth + mRight + mPaddingRight, getPaddingBottom());
if (!TextUtil.isEmpty(getText()) && isEditThis()) {
if (!isVisible) {
isVisible = true;
startVisibleAnimator();
}
} else {
if (isVisible) {
isVisible = false;
startGoneAnimator();
}
}
}
/**
* 晃動動畫
*
* @param counts 0.5秒鐘晃動多少下
*/
private Animation shakeAnimation(int counts) {
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration(500);
return translateAnimation;
}
/**
* 給圖標染上當前提示文本的顏色並且轉出Bitmap
*/
public Bitmap createBitmap(int resources, Context context) {
final Drawable drawable = ContextCompat.getDrawable(context, resources);
final Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(wrappedDrawable, getCurrentHintTextColor());
return drawableToBitmap(wrappedDrawable);
}
/**
* 觸控執行的監聽
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean touchable = (getWidth() - mPaddingRight - Interval - mRight - mWidthClear < event.getX())
&& (event.getX() < getWidth() - mPaddingRight - Interval - mRight);
if (touchable && isVisible) {
setError(null);
this.setText("");
}
}
return super.onTouchEvent(event);
}
其實主要的就是一些繪製和一些動畫的顯示,基本原理還是遵從Edittext的屬性來的。