android 自定義水波紋點選效果Button
阿新 • • 發佈:2019-01-09
welcome
效果
;
技術基礎思路
- 自定義 Button
- 自定義 Drawable
專案原始碼
自定義button
其實這只是一些說法
自定義button,我們只需要將子類繼承 button
public class AnimationButton extends Button {
public AnimationButton(Context context) {
super(context);
initFunction(context, null, 0);
}
public AnimationButton (Context context, AttributeSet attrs) {
super(context, attrs);
initFunction(context, attrs, 0);
}
public AnimationButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initFunction(context, attrs, defStyleAttr);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
//初始化操作方法
private void initFunction(Context context, AttributeSet attrs, int defStyleAttr) {
//獲取自定義屬性
if (attrs != null) {
TypedArray typedArray =context.obtainStyledAttributes(attrs,R.styleable.AnimationButton);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
//驗證 drawable
@Override
protected boolean verifyDrawable(Drawable who) {
return who == mDrawable || super.verifyDrawable(who);
}
//觸控事件
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
}
上述只是開發一個自定義View常用的思路
自定義 drawable
public class AnimationButtonDrawable extends Drawable {
//預設 透明度
private int mAlpha = 255;
//預設畫筆
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//預設顏色
private int mColor = 0;
//繪製的區域
private int mWidth, mHeight;
//波紋圓形的 圓心與半徑
private float mCirculX, mCirculY, mCirculRadus;
private Handler mHandler = new Handler(Looper.getMainLooper());
private int mBackGroundNormalColor = Color.parseColor("#ffffff");
//背景顏色
private int mBackGroundColor = mBackGroundNormalColor;
//背景矩形
private RectF mBackGroundRect;
private float rx, ry;
//點選圓形顏色
private int mAnimationCircleColor = Color.BLUE;
//點選 按鈕 down 顏色
private int mBackGroundDownColor = Color.GRAY;
public AnimationButtonDrawable() {
//設定抗鋸齒
this.mPaint.setAntiAlias(true);
//設定防抖動
this.mPaint.setDither(true);
}
//繪製功能
@Override
public void draw(Canvas canvas) {
}
@Override
public int getAlpha() {
return mAlpha;
}
//設定透明度
@Override
public void setAlpha(int alpha) {
//設定 drawable的透明度
mAlpha = alpha;
onColorOrAlphaChange();
}
//設定顏色濾鏡
@Override
public void setColorFilter(ColorFilter colorFilter) {
if (mPaint.getColorFilter() != colorFilter) {
mPaint.setColorFilter(colorFilter);
}
}
//確認drawable是否有透明度
@Override
public int getOpacity() {
int alpha = mPaint.getAlpha();
if (alpha == 255) {
//不透明
return PixelFormat.OPAQUE;
} else if (alpha == 0) {
//全透明
return PixelFormat.TRANSPARENT;
} else {
//半透明
return PixelFormat.TRANSLUCENT;
}
}
public void onColorOrAlphaChange() {
mPaint.setColor(mColor);
//獲取畫筆透明度
if (mAlpha != 255) {
int paintAlpha = mPaint.getAlpha();
int realAppha = (int) (paintAlpha * (mAlpha / 255f));
mPaint.setAlpha(realAppha);
}
}
}
- 在這裡,我們定義實現了一個基本的drawble AnimationButtonDrawable
- 一個button ,要初始化使用的變數有
有正常顯示的背景顏色,
有按下的背景顏色,
當點選擡起時,繪製波紋的顏色,
繪製波紋的位置與半徑 最重要的步驟是在draw方法中
通過方法
canvas.drawRoundRect(mBackGroundRect, rx, ry, mPaint);
來繪製圓角矩形背景通過方法
canvas.drawCircle(mCirculX, mCirculY, mCirculRadus, mPaint);
來繪製點選後擡起的圓角矩形通過設定模式來解決邊框圓角被覆蓋問題
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));完整的draw方法
//繪製功能
@Override
public void draw(Canvas canvas) {
//繪製區域
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
//新建圖層
int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);
mPaint.setColor(mBackGroundColor);
//繪製背景 圓角矩形
if (mBackGroundRect != null) {
canvas.drawRoundRect(mBackGroundRect, rx, ry, mPaint);
}
//設定圖層重疊模式
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
mPaint.setColor(mAnimationCircleColor);
//繪製圓形波紋
canvas.drawCircle(mCirculX, mCirculY, mCirculRadus, mPaint);
//最後將畫筆去除Xfermode
mPaint.setXfermode(null);
canvas.restoreToCount(layerId);
}
button 與 drawable結合
在button中,當button建立的時候,我們建立drawable,
mDrawable = new AnimationButtonDrawable();
然後在button的ondraw方法中,使用drawable的draw方法,這樣就通過 canvas 畫布將兩者關聯起來了
@Override
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
super.onDraw(canvas);
}
設定點選時的button背景顏色
在button中的onTouchEvent方法,監聽事件的發生,並將事件傳入到drawable中
@Override
public boolean onTouchEvent(MotionEvent event) {
//設定事件
mDrawable.setTouchEvent(event);
return super.onTouchEvent(event);
}
在drawable中的setTouchEvent方法中進行事件處理
public void setTouchEvent(MotionEvent event) {
//重新整理
invalidateSelf();
//判斷點選操作
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
onTouchDown(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
onTouchMove(event.getX(), event.getY());
break;
case MotionEvent.ACTION_UP:
onTouchUp(event.getX(), event.getY());
break;
case MotionEvent.ACTION_CANCEL:
onTouchCancel(event.getX(), event.getY());
break;
}
}
在ontouchDown方法, 我們更新繪製圓角矩形的顏色為按下時的顏色,並在onTouchUp方法中恢復我們正常情況下顯示的背景顏色,就可以達到button點選選擇器的風格
在ontouchDown方法中,我們可以開啟一個非同步任務,在一定的時間內不斷的繪製不同半徑的圓 疊加在之前繪製好的矩形背景上面,就可以在視覺方面達到一種波紋效果,
在這裡 繪製不大小的圓形,是通過 不斷改變繪製半徑來達到這個效果的
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
invalidateSelf();
if (mCirculRadus <= mWidth) {
isRun = true;
mCirculRadus += 18;
mHandler.postDelayed(mRunnable, 2);
} else {
isRun = false;
mCirculX = 0;
mCirculY = 0;
mCirculRadus = 0;
}
}
};