自定義View繪製--波紋擴散動畫
阿新 • • 發佈:2019-02-18
public class HankView extends View {
/**
* 擴散圓圈顏色
*/
private int mColor = getResources().getColor(R.color.colorAccent);
/**
* 圓圈中心顏色
*/
private int mCoreColor = getResources().getColor(R.color.colorPrimary);
/**
* 圓圈中心圖片
*/
private Bitmap mBitmap;
/**
* 中心圓半徑
*/
private float mCoreRadius = 50;
/**
* 擴散圓寬度
*/
private int mDiffuseWidth = 3;
/**
* 最大寬度
*/
private Integer mMaxWidth = 255;
/**
* 是否正在擴散中
*/
private boolean mIsDiffuse = false;
// 透明度集合
private List<Integer> mAlphas = new ArrayList<>();
// 擴散圓半徑集合
private List<Integer> mWidths = new ArrayList<>();
private Paint mPaint;
private OnClickListener mOnClickListener;
private String TAG = "DiffuseView";
private int mMarginBottom; // 麥克風圖片距離底邊距
public DiffuseView(Context context) {
this(context, null);
}
public DiffuseView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}
public DiffuseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.DiffuseView);
mColor = a.getColor(R.styleable.DiffuseView_diffuse_color, mColor);
mCoreColor = a.getColor(R.styleable.DiffuseView_diffuse_coreColor, mCoreColor);
mCoreRadius = a.getFloat(R.styleable.DiffuseView_diffuse_coreRadius, mCoreRadius);
mDiffuseWidth = a.getInt(R.styleable.DiffuseView_diffuse_width, mDiffuseWidth);
mMaxWidth = a.getInt(R.styleable.DiffuseView_diffuse_maxWidth, mMaxWidth);
int imageId = a.getResourceId(R.styleable.DiffuseView_diffuse_coreImage, -1);
if (imageId != -1) {
mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
}
mMarginBottom = a.getDimensionPixelOffset(R.styleable.DiffuseView_margin_bottom, 12);
a.recycle();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mAlphas.add(255);
mWidths.add(0);
}
/**
* 開始擴散
*/
public void start() {
mIsDiffuse = true;
invalidate();
}
/**
* 停止擴散
*/
public void stop() {
mIsDiffuse = false;
mWidths.clear();
mAlphas.clear();
mAlphas.add(255);
mWidths.add(0);
invalidate();
}
/**
* 是否擴散中
*/
public boolean isDiffuse() {
return mIsDiffuse;
}
/**
* 設定擴散圓顏色
*/
public void setColor(int colorId) {
mColor = colorId;
}
/**
* 設定中心圓顏色
*/
public void setCoreColor(int colorId) {
mCoreColor = colorId;
}
/**
* 設定中心圓圖片
*/
public void setCoreImage(int imageId) {
mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
}
/**
* 設定中心圓半徑
*/
public void setCoreRadius(int radius) {
mCoreRadius = radius;
}
/**
* 設定擴散圓寬度(值越小寬度越大)
*/
public void setDiffuseWidth(int width) {
mDiffuseWidth = width;
}
/**
* 設定最大寬度
*/
public void setMaxWidth(int maxWidth) {
mMaxWidth = maxWidth;
}
@Override
public void setOnClickListener(@Nullable OnClickListener onClickListener) {
mOnClickListener = onClickListener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float downX = event.getX();
float downY = event.getY();
if (downX >= (getWidth() / 2 - mBitmap.getWidth() / 2) && // 左
downX <= (getWidth() / 2 + mBitmap.getWidth() / 2) && // 右
downY >= (getHeight() - mBitmap.getHeight() - mMarginBottom) && // 上
downY <= (getHeight() - mMarginBottom)) { // 下
// 只有在圖片範圍內才具備點選響應
mOnClickListener.onClick(this);
}
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public void invalidate() {
if (hasWindowFocus()) {
super.invalidate();
}
}
@Override
public void onDraw(Canvas canvas) {
// 繪製擴散圓
mPaint.setColor(mColor);
for (int i = 0; i < mAlphas.size(); i++) {
// 設定透明度
Integer alpha = mAlphas.get(i);
mPaint.setAlpha(alpha);
// 繪製擴散圓
Integer width = mWidths.get(i);
canvas.drawCircle(getWidth() / 2, getHeight() - mMarginBottom - mBitmap.getHeight() / 2, mCoreRadius + width, mPaint);
if (alpha > 0 && width < mMaxWidth) {
mAlphas.set(i, alpha - 1);
mWidths.set(i, width + 1);
}
}
// 判斷當擴散圓擴散到指定寬度時新增新擴散圓
if (mWidths.get(mWidths.size() - 1) == mMaxWidth / mDiffuseWidth) {
mAlphas.add(255);
mWidths.add(0);
}
// 超過10個擴散圓,刪除最外層
if (mWidths.size() >= 10) {
mWidths.remove(0);
mAlphas.remove(0);
}
// 繪製中心圓及圖片
mPaint.setAlpha(255);
mPaint.setColor(mCoreColor);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius, mPaint);
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, getWidth() / 2 - mBitmap.getWidth() / 2
, getHeight() - mBitmap.getHeight() - mMarginBottom, mPaint);
}
if (mIsDiffuse) {
invalidate();
}
}
}
/**
* 擴散圓圈顏色
*/
private int mColor = getResources().getColor(R.color.colorAccent);
/**
* 圓圈中心顏色
*/
private int mCoreColor = getResources().getColor(R.color.colorPrimary);
/**
* 圓圈中心圖片
*/
private Bitmap mBitmap;
/**
* 中心圓半徑
*/
private float mCoreRadius = 50;
/**
* 擴散圓寬度
*/
private int mDiffuseWidth = 3;
/**
* 最大寬度
*/
private Integer mMaxWidth = 255;
/**
* 是否正在擴散中
*/
private boolean mIsDiffuse = false;
// 透明度集合
private List<Integer> mAlphas = new ArrayList<>();
// 擴散圓半徑集合
private List<Integer> mWidths = new ArrayList<>();
private Paint mPaint;
private OnClickListener mOnClickListener;
private String TAG = "DiffuseView";
private int mMarginBottom; // 麥克風圖片距離底邊距
public DiffuseView(Context context) {
this(context, null);
}
public DiffuseView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}
public DiffuseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.DiffuseView);
mColor = a.getColor(R.styleable.DiffuseView_diffuse_color, mColor);
mCoreColor = a.getColor(R.styleable.DiffuseView_diffuse_coreColor, mCoreColor);
mCoreRadius = a.getFloat(R.styleable.DiffuseView_diffuse_coreRadius, mCoreRadius);
mDiffuseWidth = a.getInt(R.styleable.DiffuseView_diffuse_width, mDiffuseWidth);
mMaxWidth = a.getInt(R.styleable.DiffuseView_diffuse_maxWidth, mMaxWidth);
int imageId = a.getResourceId(R.styleable.DiffuseView_diffuse_coreImage, -1);
if (imageId != -1) {
mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
}
mMarginBottom = a.getDimensionPixelOffset(R.styleable.DiffuseView_margin_bottom, 12);
a.recycle();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mAlphas.add(255);
mWidths.add(0);
}
/**
* 開始擴散
*/
public void start() {
mIsDiffuse = true;
invalidate();
}
/**
* 停止擴散
*/
public void stop() {
mIsDiffuse = false;
mWidths.clear();
mAlphas.clear();
mAlphas.add(255);
mWidths.add(0);
invalidate();
}
/**
* 是否擴散中
*/
public boolean isDiffuse() {
return mIsDiffuse;
}
/**
* 設定擴散圓顏色
*/
public void setColor(int colorId) {
mColor = colorId;
}
/**
* 設定中心圓顏色
*/
public void setCoreColor(int colorId) {
mCoreColor = colorId;
}
/**
* 設定中心圓圖片
*/
public void setCoreImage(int imageId) {
mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
}
/**
* 設定中心圓半徑
*/
public void setCoreRadius(int radius) {
mCoreRadius = radius;
}
/**
* 設定擴散圓寬度(值越小寬度越大)
*/
public void setDiffuseWidth(int width) {
mDiffuseWidth = width;
}
/**
* 設定最大寬度
*/
public void setMaxWidth(int maxWidth) {
mMaxWidth = maxWidth;
}
@Override
public void setOnClickListener(@Nullable OnClickListener onClickListener) {
mOnClickListener = onClickListener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float downX = event.getX();
float downY = event.getY();
if (downX >= (getWidth() / 2 - mBitmap.getWidth() / 2) && // 左
downX <= (getWidth() / 2 + mBitmap.getWidth() / 2) && // 右
downY >= (getHeight() - mBitmap.getHeight() - mMarginBottom) && // 上
downY <= (getHeight() - mMarginBottom)) { // 下
// 只有在圖片範圍內才具備點選響應
mOnClickListener.onClick(this);
}
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public void invalidate() {
if (hasWindowFocus()) {
super.invalidate();
}
}
@Override
public void onDraw(Canvas canvas) {
// 繪製擴散圓
mPaint.setColor(mColor);
for (int i = 0; i < mAlphas.size(); i++) {
// 設定透明度
Integer alpha = mAlphas.get(i);
mPaint.setAlpha(alpha);
// 繪製擴散圓
Integer width = mWidths.get(i);
canvas.drawCircle(getWidth() / 2, getHeight() - mMarginBottom - mBitmap.getHeight() / 2, mCoreRadius + width, mPaint);
if (alpha > 0 && width < mMaxWidth) {
mAlphas.set(i, alpha - 1);
mWidths.set(i, width + 1);
}
}
// 判斷當擴散圓擴散到指定寬度時新增新擴散圓
if (mWidths.get(mWidths.size() - 1) == mMaxWidth / mDiffuseWidth) {
mAlphas.add(255);
mWidths.add(0);
}
// 超過10個擴散圓,刪除最外層
if (mWidths.size() >= 10) {
mWidths.remove(0);
mAlphas.remove(0);
}
// 繪製中心圓及圖片
mPaint.setAlpha(255);
mPaint.setColor(mCoreColor);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius, mPaint);
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, getWidth() / 2 - mBitmap.getWidth() / 2
, getHeight() - mBitmap.getHeight() - mMarginBottom, mPaint);
}
if (mIsDiffuse) {
invalidate();
}
}
}