android自定義圓形抖動(縮放)檢視
阿新 • • 發佈:2018-12-05
轉載請註明出處:https://blog.csdn.net/u011038298/article/details/84786307
import android.graphics.Color; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { // 宣告一個圓形抖動(縮放)檢視 private CircleShakeView circleShakeView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 控制元件的大小(寬/高) float size = getResources().getDimension(R.dimen.width34px); // 抖動縮放距離 float shakeDistance = getResources().getDimension(R.dimen.width8px); // 外圓半徑與內圓半徑直接的距離 float circleDistance = getResources().getDimension(R.dimen.width6px); // 獲取自定義圓形抖動(縮放)檢視 circleShakeView = findViewById(R.id.circle_shake_view); // 設定延遲顯示時間(單位:毫秒) 例如延遲20s後再顯示紅點縮放抖動效果 circleShakeView.setDelayTime(1000 * 20); // 設定圓的抖動(縮放)距離 circleShakeView.setShakeDistance(shakeDistance); // 設定內圓顏色 circleShakeView.setInsideColor(Color.RED); // 設定外圓顏色 circleShakeView.setOuterColor(Color.WHITE); // 設定內圓半徑 circleShakeView.setInsideRadius(size / 2 - circleDistance); // 設定外圓半徑 circleShakeView.setOuterRadius(size / 2); } @Override protected void onResume() { super.onResume(); // 開始 circleShakeView.start(); } @Override protected void onStop() { super.onStop(); // 停止 circleShakeView.stop(); } }
import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; /** * 自定義圓形抖動(縮放)檢視 */ public class CircleShakeView extends View { public CircleShakeView(Context context) { super(context); init(); } public CircleShakeView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CircleShakeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } // 外圓半徑 private float outerRadius; // 內圓半徑(小於外圓半徑) private float insideRadius; // 抖動縮放的距離 private float shakeDistance; // 當前抖動縮放的距離 private float curDistance; // 外圓顏色 private int outerColor; // 內圓顏色 private int insideColor; // 畫筆 private Paint mPaint; // 延遲抖動時間 private long delayTime; // 是否允許繪製 private boolean isDraw; // 是否開始執行 private volatile boolean isRun; // 宣告一個執行緒 private Thread mThread; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isInEditMode()) { return; } if (!isDraw) { return; } if (outerRadius > insideRadius) { // 繪製外圓(圓心不變,半徑發生變化) RectF outerRectF = new RectF(); outerRectF.left = curDistance; outerRectF.right = outerRadius * 2 - curDistance; outerRectF.top = curDistance; outerRectF.bottom = outerRadius * 2 - curDistance; mPaint.setColor(outerColor); canvas.drawRoundRect(outerRectF, outerRadius, outerRadius, mPaint); // 繪製內圓(內圓心跟外圓心保持同一個圓心座標,半徑發生變化) float size = outerRadius - insideRadius; RectF insideRectF = new RectF(); insideRectF.left = outerRectF.left + size; insideRectF.right = outerRectF.right - size; insideRectF.top = outerRectF.top + size; insideRectF.bottom = outerRectF.bottom - size; mPaint.setColor(insideColor); canvas.drawRoundRect(insideRectF, outerRadius, outerRadius, mPaint); } else { // 繪製內圓(圓心不變,半徑發生變化) RectF rectF = new RectF(); rectF.left = curDistance; rectF.right = insideRadius * 2 - curDistance; rectF.top = curDistance; rectF.bottom = insideRadius * 2 - curDistance; mPaint.setColor(insideColor); canvas.drawRoundRect(rectF, insideRadius, insideRadius, mPaint); } } /** * 初始化資料 */ private void init() { isDraw = false; isRun = false; curDistance = 0; delayTime = 0; insideRadius = 0; outerRadius = 0; if (mPaint == null) { mPaint = new Paint(); // 防抖動 mPaint.setDither(true); // 抗鋸齒 mPaint.setAntiAlias(true); // 設定繪畫的連線 mPaint.setStrokeJoin(Paint.Join.ROUND); } } /** * 開始 */ public synchronized void start() { if (isRun == false) { isRun = true; mThread = new Thread(new Runnable() { @Override public void run() { if (delayTime > 0) { // 如果有延遲顯示時間 try { Thread.sleep(delayTime); } catch (Exception e) { e.printStackTrace(); } delayTime = 0; } isDraw = true; // 如果不想優先顯示最大抖動縮放距離,可省略此句 curDistance = shakeDistance; while (isRun) { postInvalidate(); if (curDistance > 0) { curDistance = 0; } else { curDistance = shakeDistance; } try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } }); mThread.start(); } } /** * 停止 */ public synchronized void stop() { try { isRun = false; isDraw = false; // 如果當前Thread不為空,並且存活,並且還沒有被中斷 if (mThread != null && mThread.isAlive() && !mThread.isInterrupted()) { mThread.interrupt(); } } catch (Exception ex) { } finally { mThread = null; } } /** * 設定外圓半徑 * * @param outerRadius */ public void setOuterRadius(float outerRadius) { this.outerRadius = outerRadius; } /** * 設定內圓半徑 * * @param insideRadius */ public void setInsideRadius(float insideRadius) { this.insideRadius = insideRadius; } /** * 設定圓的抖動(縮放)距離 * * @param shakeDistance */ public void setShakeDistance(float shakeDistance) { this.shakeDistance = shakeDistance; } /** * 設定外圓顏色 * * @param outerColor */ public void setOuterColor(int outerColor) { this.outerColor = outerColor; } /** * 設定內圓顏色 * * @param insideColor */ public void setInsideColor(int insideColor) { this.insideColor = insideColor; } /** * 設定延遲顯示時間 * * @param delayTime */ public void setDelayTime(long delayTime) { this.delayTime = delayTime; } }
效果圖 :