安卓自定义View之旋转麦克风

安卓自定义View之旋转麦克风

前言

工作需要一个外圈会转动,还能任意分成多少份的外圈的麦克风,研究一番之后设计了一个会旋转的麦克风。

一、先看效果图

视频效果请看https://live.youkuaiyun.com/v/464864?spm=1001.2014.3001.5501
在这里插入图片描述

二、自定义属性

接下来就是熟悉的自定义属性了

在项目的\res\values\attrs.xml 中 新增一个 declare-styleable 名字就叫RotateView。

为了好看出是在旋转,静止和旋转状态都定义了俩种颜色。

份数的简单计算方式:360度除以每份的度数再取整即可,份数 = (int) (360/ 每份扫过的角度)

<declare-styleable name="RotateView">
        <!--静止状态下的第1种颜色-->
        <attr name="rotate_view_color_normal_one" format="reference|color" />
        <!--静止状态下的第2种颜色-->
        <attr name="rotate_view_color_normal_two" format="reference|color" />
        <!--旋转状态下的第1种颜色-->
        <attr name="rotate_view_color_running_one" format="reference|color" />
        <!--旋转状态下的第2种颜色-->
        <attr name="rotate_view_color_running_two" format="reference|color" />
        <!--静止状态下画笔描边宽度-->
        <attr name="rotate_view_stroke_width_normal" format="reference|float|dimension" />
        <!--旋转状态下画笔描边宽度-->
        <attr name="rotate_view_stroke_width_running" format="reference|float|dimension" />
        <!--每份扫过的角度-->
        <attr name="rotate_view_angle_of_each_sweep" format="reference|float|dimension" />
        <attr name="rotate_view_rotate_direction">
            <!--顺时针旋转-->
            <enum name="clockwise" value="1" />
            <!--逆时针旋转-->
            <enum name="counterclockwise" value="2" />
        </attr>
    </declare-styleable>

三、关键设计

1. 继承View 复写必要的构造方法

/**
 * 可以旋转的 圆环 麦克风
 */
public class RotateView extends View {

    public RotateView(Context context) {
        this(context, null);
    }

    public RotateView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RotateView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context, attrs);
        init();
    }

2. 读取自定义属性并初始化

 private void initAttr(Context context, AttributeSet attrs) {
        int normalOneColorDefValue = context.getResources().getColor(R.color.colorRingNormalOne);
        int normalTwoColorDefValue = context.getResources().getColor(R.color.colorRingNormalTwo);

        int runningOneColorDefValue = context.getResources().getColor(R.color.colorRingRunningOne);
        int runningTwoColorDefValue = context.getResources().getColor(R.color.colorRingRunningTwo);

        normalColorOne = normalOneColorDefValue;
        normalColorTwo = normalTwoColorDefValue;

        runningColorOne = runningOneColorDefValue;
        runningColorTwo = runningTwoColorDefValue;

        float normalStrokeWidthDef = 3;
        normalStrokeWidth = dipToPx(normalStrokeWidthDef);

        float runningStrokeWidthDef = 3;
        runningStrokeWidth = dipToPx(runningStrokeWidthDef);

        rotateDirection = ANTI_CLOCK_WISE;

        int sweepAngleDef = 18;
        sweepAngle = sweepAngleDef;

        countStep = (int) (360 / sweepAngle); //计算分为几份

        try (TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotateView)) {
            normalColorOne = typedArray.getColor(R.styleable.RotateView_rotate_view_color_normal_one, normalOneColorDefValue);
            normalColorTwo = typedArray.getColor(R.styleable.RotateView_rotate_view_color_normal_two, normalTwoColorDefValue);

            runningColorOne = typedArray.getColor(R.styleable.RotateView_rotate_view_color_running_one, runningOneColorDefValue);
            runningColorTwo = typedArray.getColor(R.styleable.RotateView_rotate_view_color_running_two, runningTwoColorDefValue);

            float normalStrokeWidthV = typedArray.getFloat(R.styleable.RotateView_rotate_view_stroke_width_normal, normalStrokeWidthDef);
            normalStrokeWidth = dipToPx(normalStrokeWidthV);
            float runningStrokeWidthV = typedArray.getFloat(R.styleable.RotateView_rotate_view_stroke_width_running, runningStrokeWidthDef);
            runningStrokeWidth = dipToPx(runningStrokeWidthV);

            sweepAngle = typedArray.getFloat(R.styleable.RotateView_rotate_view_angle_of_each_sweep, sweepAngleDef);
            countStep = (int) (360 / sweepAngle); //计算分成几份

            // 读取自定义属性中的 旋转方向 ,默认逆时针
            rotateDirection = typedArray.getInt(R.styleable.RotateView_rotate_view_rotate_direction, ANTI_CLOCK_WISE);
            //typedArray.recycle();
        }
    }

    private void init() {
        paintRing = new Paint();
        paintRing.setAntiAlias(true);
        paintRing.setDither(true);
        paintRing.setStrokeWidth(normalStrokeWidth);
        paintRing.setStyle(Paint.Style.STROKE);

        paintMic = new Paint();
        paintMic.setAntiAlias(true);
        paintMic.setDither(true);
        paintMic.setStrokeWidth(normalStrokeWidth / 2);
        paintMic.setStyle(Paint.Style.FILL);

        ringRectF = new RectF();  // 这个矩形区域用来确定圆环的位置
        roundRectF = new RectF();
        micRectF = new RectF();
    }
    

3. 确定圆环的位置

为了让视图保持在正中央,需要找出圆心的位置,确定矩形的区域;
在这里插入图片描述

4. 绘制圆环

计算好开始角度和每份需要扫过的角度,通过 drawArc 函数来画圆环即可

public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,
            @NonNull Paint paint) {
        super.drawArc(oval, startAngle, sweepAngle, useCenter, paint);
    }

在这里插入图片描述

5.绘制麦克风

之前有一篇文章已经介绍过如何绘制麦克风了,这里不再赘述。传送门自定义麦克风

如何让圆环旋转起来呢?
可以每次画圆环之前让画布旋转一个角度rotateDegrees,然后每次改变这个 rotateDegrees 重新绘制圆环即可达到旋转的效果。

在这里插入图片描述
在这里插入图片描述

6.实现旋转效果

使用 Handler 发延迟消息不断重绘,就能旋转起来了。

 private final Handler handlerForRotate = new Handler(Looper.getMainLooper());
    private final Runnable runnableForRotate = new Runnable() {
        @Override
        public void run() {
            updateRotateDegrees();
            invalidate();
            handlerForRotate.postDelayed(runnableForRotate, 10);
        }
    };
/**
     * 更新角度
     */
    private float updateRotateDegrees() {
        if (isRunning()) {
            // rotateDegrees = (float) (rotateDegrees + 1.828)
            rotateDegrees = (float) (rotateDegrees + 0.225);
            if (rotateDegrees > 360) {
                rotateDegrees = rotateDegrees % 360;
            }
        } else {
            rotateDegrees = 0;
        }
        // Log.i("RotateView", "角度 " + rotateDegrees);
        return rotateDegrees;
    }

    /**
     * 开始 旋转
     * <p>
     * requestLayout 方法会导致View的onMeasure、onLayout、onDraw方法被调用;
     * <p>
     * 在非UI线程中调用 postInvalidate(); 来请求重绘
     * <p>
     * 在UI线程中调用 Invalidate(); 来请求重绘
     */
    public void startRotate() {
        if (isRunning()) {
            return;
        }
        setRunning(true);
        handlerForRotate.removeCallbacks(runnableForRotate);
        handlerForRotate.post(runnableForRotate);
    }

    /**
     * 停止 旋转
     */
    public void stopRotate() {
        handlerForRotate.removeCallbacks(runnableForRotate);
        handlerForRotate.removeCallbacksAndMessages(null);
        setRunning(false);
        rotateDegrees = 0;
        invalidate();
    }
    

7.完整代码

package com.linkpoon.hamlauncher.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;

import com.linkpoon.hamlauncher.R;


/**
 * 可以旋转的 圆环 麦克风
 */
public class RotateView extends View {


    public RotateView(Context context) {
        this(context, null);
    }

    public RotateView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RotateView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context, attrs);
        init();
    }


    private Paint paintRing;// 圆环画笔
    private Paint paintMic;// 麦克风画笔

    private int normalColorOne; //静止状态下 圆环 颜色1
    private int normalColorTwo;//静止状态下 圆环 颜色2
    private float normalStrokeWidth; //静止状态下 麦克风画笔 描边宽度

    private int runningColorOne;//旋转状态下 圆环 颜色1
    private int runningColorTwo;//旋转状态下 圆环 颜色2
    private float runningStrokeWidth;//旋转状态下 圆环 画笔 描边宽度

    public static final int CLOCK_WISE = 1;// 顺时针 旋转
    public static final int ANTI_CLOCK_WISE = 2;// 逆时针 旋转

    private float circlePointX; //圆心横坐标
    private float circlePointY; //圆心纵坐标

    private RectF ringRectF;// 用于绘制 最外圈的圆环
    private RectF roundRectF;// 用于绘制 麦克风上面的圆角矩形部分
    private RectF micRectF;// 用于绘制 麦克风中间的弧线部分

    private int paddingTopRect = 5;//麦克风的位置在中心往下偏移5dp
    private float startAngle = 0; // 开始角度
    private float sweepAngle; // 扫过的角度(每一小段占的角度)
    private int countStep; //计算分为几段

    private float rotateDegrees = 0; //画布旋转的初始角度
    private int rotateDirection;// 旋转方向
    private boolean isRunning;// 是否在旋转

    public boolean isRunning() {
        return this.isRunning;
    }

    public void setRunning(boolean running) {
        this.isRunning = running;
    }

    /**
     * 设置旋转方向
     */
    public void setRotateDirection(int direction) {
        this.rotateDirection = direction;
        // requestLayout();
    }

    /**
     * 获取旋转方向
     */
    public int getRotateDirection() {
        return this.rotateDirection;
    }


    public int getNormalColorOne() {
        return normalColorOne;
    }

    public void setNormalColorOne(int normalColorOne) {
        this.normalColorOne = normalColorOne;
    }

    public int getNormalColorTwo() {
        return normalColorTwo;
    }

    public void setNormalColorTwo(int normalColorTwo) {
        this.normalColorTwo = normalColorTwo;
    }

    public float getNormalStrokeWidth() {
        return normalStrokeWidth;
    }

    public void setNormalStrokeWidth(float normalStrokeWidth) {
        this.normalStrokeWidth = normalStrokeWidth;
    }

    public int getRunningColorOne() {
        return runningColorOne;
    }

    public void setRunningColorOne(int runningColorOne) {
        this.runningColorOne = runningColorOne;
    }

    public int getRunningColorTwo() {
        return runningColorTwo;
    }

    public void setRunningColorTwo(int runningColorTwo) {
        this.runningColorTwo = runningColorTwo;
    }

    public float getRunningStrokeWidth() {
        return runningStrokeWidth;
    }

    public void setRunningStrokeWidth(float runningStrokeWidth) {
        this.runningStrokeWidth = runningStrokeWidth;
    }


    /**
     * 将 dp 转换成 px
     */
    private int dipToPx(float dip) {
        float density = getResources().getDisplayMetrics().density;
        return (int) ((dip * density) + 0.5f);
    }

    private final Handler handlerForRotate = new Handler(Looper.getMainLooper());
    private final Runnable runnableForRotate = new Runnable() {
        @Override
        public void run() {
            //requestLayout();
            updateRotateDegrees();
            invalidate();
            handlerForRotate.postDelayed(runnableForRotate, 10);
        }
    };


    private void initAttr(Context context, AttributeSet attrs) {
        int normalOneColorDefValue = context.getResources().getColor(R.color.colorRingNormalOne);
        int normalTwoColorDefValue = context.getResources().getColor(R.color.colorRingNormalTwo);

        int runningOneColorDefValue = context.getResources().getColor(R.color.colorRingRunningOne);
        int runningTwoColorDefValue = context.getResources().getColor(R.color.colorRingRunningTwo);

        normalColorOne = normalOneColorDefValue;
        normalColorTwo = normalTwoColorDefValue;

        runningColorOne = runningOneColorDefValue;
        runningColorTwo = runningTwoColorDefValue;

        float normalStrokeWidthDef = 3;
        normalStrokeWidth = dipToPx(normalStrokeWidthDef);

        float runningStrokeWidthDef = 3;
        runningStrokeWidth = dipToPx(runningStrokeWidthDef);

        rotateDirection = ANTI_CLOCK_WISE;

        int sweepAngleDef = 18;
        sweepAngle = sweepAngleDef;

        countStep = (int) (360 / sweepAngle); //计算分为几份

        try (TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotateView)) {
            normalColorOne = typedArray.getColor(R.styleable.RotateView_rotate_view_color_normal_one, normalOneColorDefValue);
            normalColorTwo = typedArray.getColor(R.styleable.RotateView_rotate_view_color_normal_two, normalTwoColorDefValue);

            runningColorOne = typedArray.getColor(R.styleable.RotateView_rotate_view_color_running_one, runningOneColorDefValue);
            runningColorTwo = typedArray.getColor(R.styleable.RotateView_rotate_view_color_running_two, runningTwoColorDefValue);

            float normalStrokeWidthV = typedArray.getFloat(R.styleable.RotateView_rotate_view_stroke_width_normal, normalStrokeWidthDef);
            normalStrokeWidth = dipToPx(normalStrokeWidthV);
            float runningStrokeWidthV = typedArray.getFloat(R.styleable.RotateView_rotate_view_stroke_width_running, runningStrokeWidthDef);
            runningStrokeWidth = dipToPx(runningStrokeWidthV);

            sweepAngle = typedArray.getFloat(R.styleable.RotateView_rotate_view_angle_of_each_sweep, sweepAngleDef);
            countStep = (int) (360 / sweepAngle); //计算分成几份

            // 读取自定义属性中的 旋转方向 ,默认逆时针
            rotateDirection = typedArray.getInt(R.styleable.RotateView_rotate_view_rotate_direction, ANTI_CLOCK_WISE);
            //typedArray.recycle();
        }
    }

    private void init() {
        paintRing = new Paint();
        paintRing.setAntiAlias(true);
        paintRing.setDither(true);
        paintRing.setStrokeWidth(normalStrokeWidth);
        paintRing.setStyle(Paint.Style.STROKE);

        paintMic = new Paint();
        paintMic.setAntiAlias(true);
        paintMic.setDither(true);
        paintMic.setStrokeWidth(normalStrokeWidth / 2);
        paintMic.setStyle(Paint.Style.FILL);

        ringRectF = new RectF();  // 这个矩形区域用来确定圆环的位置
        roundRectF = new RectF();
        micRectF = new RectF();
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        // 比较宽 高 取小的值得一半  作为圆环的半径
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        float minValue = (float) Math.min(width, height);
        float radius = minValue / 2;   //半径

        circlePointX = (float) (width / 2); //圆心横坐标
        circlePointY = (float) (height / 2); //圆心纵坐标

        float spaceOfRing = radius * 0.12f;

        float ringRectFLeft = circlePointX - radius + spaceOfRing;
        float ringRectFTop = circlePointY - radius + spaceOfRing;
        float ringRectFRight = circlePointX + radius - spaceOfRing;
        float ringRectFBottom = circlePointY + radius - spaceOfRing;
        // 设置这个矩形区域的位置
        ringRectF.set(ringRectFLeft, ringRectFTop, ringRectFRight, ringRectFBottom);

        //canvas.drawRect(ringRectF, paintRing);

        canvas.save();
        if (getRotateDirection() == CLOCK_WISE) {
            // 顺时针
            canvas.rotate(rotateDegrees, ringRectF.centerX(), ringRectF.centerY());
        } else {
            // 逆时针
            canvas.rotate(-rotateDegrees, ringRectF.centerX(), ringRectF.centerY());
        }
        // Log.i("RotateView", "" + ringRectF.centerX() + "" + ringRectF.centerY());
        for (int i = 0; i < countStep; i++) {
            if (isRunning()) {
                // 动态(旋转时)
                if (i % 2 == 0) {
                    // 偶数位置 用第 1 种颜色
                    paintRing.setColor(runningColorOne);
                    // paint.setAlpha(128);// 半透明
                    paintRing.setStrokeWidth(runningStrokeWidth);
                } else {
                    // 奇数位置 用第 2 种颜色
                    paintRing.setColor(runningColorTwo);
                    // paint.setAlpha(128);// 半透明
                    paintRing.setStrokeWidth(runningStrokeWidth);
                }
            } else {
                // 静态
                if (i % 2 == 0) {
                    paintRing.setColor(normalColorOne);
                    // paint.setAlpha(255);// 不透明
                    paintRing.setStrokeWidth(normalStrokeWidth);
                } else {
                    paintRing.setColor(normalColorTwo);
                    // paint.setAlpha(255);// 不透明
                    paintRing.setStrokeWidth(normalStrokeWidth);
                }
            }
            // Log.i("PanView", "  " + startAngle + " rotate " + ringRectF.toString());
            // 画弧线 画圆环
            canvas.drawArc(ringRectF, startAngle, sweepAngle, false, paintRing);
            startAngle = startAngle + sweepAngle;
        }
        startAngle = 0; //画好圆环后 将开始角度重置
        canvas.restore();


        if (isRunning()) {
            paintMic.setColor(runningColorTwo);
        } else {
            paintMic.setColor(normalColorOne);
        }

        float roundLeft = circlePointX - circlePointX / 19;
        float roundTop = circlePointY - circlePointY / 5 + dipToPx(paddingTopRect);
        float roundRight = circlePointX + circlePointX / 19;
        float roundBottom = circlePointY + dipToPx(paddingTopRect - 2);
        // 设置矩形区域,用于确定麦克风上部的位置
        roundRectF.set(roundLeft, roundTop, roundRight, roundBottom);

        // paintMic.setStrokeWidth(normalStrokeWidth);
        paintMic.setStyle(Paint.Style.FILL);
        // 画一个圆角矩形 圆角度数16
        canvas.drawRoundRect(roundRectF, 16, 16, paintMic);

        // paintMic.setStrokeWidth(normalStrokeWidth);
        float vLineStartY = circlePointY + dipToPx(paddingTopRect + 3);
        float vLineStopY = circlePointY + circlePointY / 11 + dipToPx(paddingTopRect + 3);
        // 画一段竖线
        canvas.drawLine(circlePointX, vLineStartY, circlePointX, vLineStopY, paintMic);


        float rectLeftOfArc = circlePointX - circlePointX / 10;
        float rectTopOfArc = circlePointY - circlePointY / 8 + dipToPx(paddingTopRect + 3);
        float rectRightOfArc = circlePointX + circlePointX / 10;
        float rectBottomOfArc = circlePointY + dipToPx(paddingTopRect + 3);
        micRectF.set(rectLeftOfArc, rectTopOfArc, rectRightOfArc, rectBottomOfArc);
        /***
         * path.arcTo 用来绘制一段圆弧,实际上是截取圆或者椭圆的一部分
         * 该方法接收三个参数,
         * 第一个表示弧形所在的矩形,
         * 如果矩形为正方形,则画出的弧形为圆的一部分,
         * 如果矩形宽高不等,画出的弧形为椭圆的一部分,
         * 第二个参数表示绘制的起点位置,
         * 0 度为钟表三点位置, 顺时针方向为正
         * 第三个参数表示绘制的度数。
         * */
        // paintMic.setStrokeWidth(normalStrokeWidth);
        paintMic.setStyle(Paint.Style.STROKE);
        //画一段圆弧
        canvas.drawArc(micRectF, -10, 180 + 10 + 10, false, paintMic);

        float hStartX = circlePointX - circlePointX / 15;
        float hStartY = circlePointY + circlePointY / 11 + dipToPx(paddingTopRect + 5);
        float hStopX = circlePointX + circlePointX / 15;
        float hStopY = circlePointY + circlePointY / 11 + dipToPx(paddingTopRect + 5);
        // 画一段横线
        canvas.drawLine(hStartX, hStartY, hStopX, hStopY, paintMic);

    }

    /**
     * 更新角度
     */
    private float updateRotateDegrees() {
        if (isRunning()) {
            // rotateDegrees = (float) (rotateDegrees + 1.828)
            rotateDegrees = (float) (rotateDegrees + 0.225);
            if (rotateDegrees > 360) {
                rotateDegrees = rotateDegrees % 360;
            }
        } else {
            rotateDegrees = 0;
        }
        // Log.i("RotateView", "角度 " + rotateDegrees);
        return rotateDegrees;
    }

    /**
     * 开始 旋转
     * <p>
     * requestLayout 方法会导致View的onMeasure、onLayout、onDraw方法被调用;
     * <p>
     * 在非UI线程中调用 postInvalidate(); 来请求重绘
     * <p>
     * 在UI线程中调用 Invalidate(); 来请求重绘
     */
    public void startRotate() {
        if (isRunning()) {
            return;
        }
        setRunning(true);
        handlerForRotate.removeCallbacks(runnableForRotate);
        handlerForRotate.post(runnableForRotate);
    }

    /**
     * 停止 旋转
     */
    public void stopRotate() {
        handlerForRotate.removeCallbacks(runnableForRotate);
        handlerForRotate.removeCallbacksAndMessages(null);
        setRunning(false);
        rotateDegrees = 0;
        //requestLayout();
        invalidate();
    }

}

四、测试一下

写个测试布局
R.layout.activity_test

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.linkpoon.hamlauncher.view.RotateView
        android:id="@+id/test_rotate_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:rotate_view_angle_of_each_sweep="18"
        app:rotate_view_stroke_width_normal="8"
        app:rotate_view_stroke_width_running="8" />


    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#565656" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/test_button_stat_ni"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:minHeight="45dp"
        android:text="逆时针旋转" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#565656" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/test_button_stat_shun"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:minHeight="45dp"
        android:text="顺时针旋转" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#565656" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/test_button_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:minHeight="45dp"
        android:text="停止旋转" />

</LinearLayout>

再写个TestActivity 。

import android.graphics.Color;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatTextView;

import com.linkpoon.hamlauncher.R;
import com.linkpoon.hamlauncher.view.RotateView;

public class TestActivity extends AppCompatActivity implements View.OnClickListener {

    private RotateView rotateView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        rotateView = findViewById(R.id.test_rotate_view);
        AppCompatTextView buttonStartNi = findViewById(R.id.test_button_stat_ni);
        AppCompatTextView buttonStartShun = findViewById(R.id.test_button_stat_shun);
        AppCompatTextView buttonStop = findViewById(R.id.test_button_stop);
        buttonStartNi.setOnClickListener(this);
        buttonStartShun.setOnClickListener(this);
        buttonStop.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.test_button_stat_ni) {
            startNiButtonClicked();
        } else if (id == R.id.test_button_stat_shun) {
            startShunButtonClicked();
        } else if (id == R.id.test_button_stop) {
            stopButtonClicked();
        }
    }

    private void startNiButtonClicked() {
        if (rotateView == null) {
            return;
        }
        rotateView.setRunningColorOne(Color.argb(255, 111, 55, 0));
        rotateView.setRunningColorTwo(Color.argb(255, 23, 128, 35));
        rotateView.setRotateDirection(RotateView.ANTI_CLOCK_WISE);
        rotateView.startRotate();
    }

    private void startShunButtonClicked() {
        if (rotateView == null) {
            return;
        }
        rotateView.setRunningColorOne(Color.parseColor("#fe8812"));
        rotateView.setRunningColorTwo(Color.argb(255, 200, 33, 33));
        rotateView.setRotateDirection(RotateView.CLOCK_WISE);
        rotateView.startRotate();
    }

    private void stopButtonClicked() {
        if (rotateView == null) {
            return;
        }
        rotateView.stopRotate();
    }

}

Nice ,效果不错,收工,以后需求有变化再改了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值