Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> RecycleView刷新 齒輪轉動動畫效果

RecycleView刷新 齒輪轉動動畫效果

編輯:關於Android編程

穿插一篇自定義view 的動畫效果,偶然看到的一個gif刷新齒輪效果圖片,原圖如下:
這裡寫圖片描述

感覺挺有意思的,就想自己也做一個,發費了一番功夫,算是做出了基本效果,但原諒我使其美觀盡毀,做出的效果如下:
這裡寫圖片描述
gif錄制有些掉幀

好了,放源碼了:

public class GearView extends View {
    private Context context;
    private Paint paint;
    private float PI = 3.1415926f;
    private int circleGrade = 1;//圓的齒輪個數 9+circleGrade 個
    private float gearWidth = 40;
    private float gearHeight = 50;
    private float length = 60;//弧長
    private List circles;//存儲圓的參數
    private Map bitmaps;//把已經繪制好的bitmap存儲起來,循環利用
    private int speedArgu = 20;//旋轉速度參數
    private int viewWidth;//所在view 的寬度
    private int viewHeight;//所在view 的高度
    private boolean startRotato = true;//是否開始動畫
    private int r1;
    private int r2;
    private int r3;
    private int r4;
    private int r5;

    private float fTran = 0;//平移基本數
    private float translationArgu = 4.0f;//平移乘數
    private float fRotate = 0;//平移後中心旋轉基本數
    private float transientRotate = 70.0f;//平移後中心旋轉乘數
    private float scale = 0.001f;//平移後中心縮放 程度
    private float scaleBase = 1.0f;//平移後中心縮放基本數

    public boolean isStartRotato() {
        return startRotato;
    }

    public void setStartRotato(boolean startRotato) {
        this.startRotato = startRotato;
    }

    public int getSpeedArgu() {
        return speedArgu;
    }

    public void setSpeedArgu(int speedArgu) {
        if(speedArgu > 70){
            speedArgu = 70;
        }
        if(speedArgu < 5 && speedArgu > 0){
            speedArgu = 5;
        }
        if(speedArgu < -70){
            speedArgu = -70;
        }
        if(speedArgu <0 && speedArgu > -5){
            speedArgu = -5;
        }
        this.speedArgu = speedArgu;
    }

    public GearView(Context context) {
        super(context);
        this.context = context;

        init();
    }

    public GearView(Context context, AttributeSet attrs) {
        super(context, attrs);
        context = context;
        init();
    }

    public GearView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        context = context;
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(false);
        bitmaps = new HashMap();
        circles = new ArrayList();

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.viewHeight = h;
        this.viewWidth = w;
        initCircle();
    }

    private void initCircle() {
        float centerX = viewWidth/2;
        float centerY = viewHeight/2;

        //添加圓和設置位置,在此處添加和修改即可

        r1 = 3;
//        float c1Top = centerY-getRaidus(r1) * 2;
        float c1Top = centerY-getRaidus(r1) -20;
        float c1Left = centerX-getRaidus(r1) * 2;
        int color1 = getResources().getColor(R.color.colorGear1);
        Circle circle = new Circle(c1Top,c1Left,getRaidus(r1), false,0,0,color1);
        circles.add(circle);

        r2 = 8;
        updataHeight(r2);
        float c2Top = c1Top + getRaidus(r2) + gearHeight;
        float c2Left = c1Left - getRaidus(r2) - gearHeight;
        int color2 = getResources().getColor(R.color.colorGear2);
        circle = new Circle(c2Top ,c2Left, getRaidus(r2), true,0,3, color2);
        circles.add(circle);

        r3 = 18;
        updataHeight(r3);
        float c3Top = c2Top - getRaidus(r3) -getRaidus(r2) - gearHeight + 5;
        float c3Left = c2Left - getRaidus(r3) - getRaidus(r2)- gearHeight + 5;
        int color3 = getResources().getColor(R.color.colorGear3);
        circle = new Circle(c3Top ,c3Left, getRaidus(r3), false,0,6, color3);
        circles.add(circle);

        r4 = 11;
        updataHeight(r4);
        float c4Top = c1Top - getRaidus(r4) - gearHeight - getRaidus(r1);
        float c4Left = c1Left + getRaidus(r4) + gearHeight - getRaidus(r1);
        int color4 = getResources().getColor(R.color.colorGear4);
        circle = new Circle(c4Top ,c4Left, getRaidus(r4), true,0,-5, color4);
        circles.add(circle);

        r5 = 16;
        updataHeight(r5);
        float c5Top = c4Top  +getRaidus(r5) + gearHeight + 10 ;
        float c5Left = c4Left  + getRaidus(r5)+ gearHeight +10 ;
        int color5 = getResources().getColor(R.color.colorGear5);
        circle = new Circle(c5Top ,c5Left, getRaidus(r5), false,0,2, color5);
        circles.add(circle);

    }

    /**
     * 供外部調用旋轉
     * */
    public void startRotato(float dy){
        int speed = (int) (dy * 4);
        setSpeedArgu(speed);
        startRotato = true;
        isTranslation = false;

        if((speed < 20 && speed >0) || (speed < 0 && speed > -20)){
            speed = 20;
        }
        if(speed <= -20){
            speed = Math.abs(speed);
        }
        if(speed > 100 || speed < -100){
            speed = 100;
        }
        for(int i = 0;i0.01f && scale <0.03f){
            scaleBase = scaleBase -scale +0.01f;
        }
        matrix.postScale(scaleBase,scaleBase);

        matrix.postTranslate(circle.getLeft() + offsetX, circle.getTop() + offsetY);
        canvas.drawBitmap(bitmap,matrix,null);

        fTran+=1.0f * translationArgu;
        Bitmap bitmap1 = bitmaps.get(getRaidus(r2));
        Matrix matrix1 = new Matrix();
        Circle circle1 = circles.get(1);
        matrix1.postTranslate(circle1.getLeft()-fTran,circle1.getTop()+fTran);
        canvas.drawBitmap(bitmap1,matrix1,null);

        Bitmap bitmap2 = bitmaps.get(getRaidus(r3));
        Matrix matrix2 = new Matrix();
        Circle circle2 = circles.get(2);
        matrix2.postTranslate(circle2.getLeft()-fTran,circle2.getTop()-fTran);
        canvas.drawBitmap(bitmap2,matrix2,null);

        Bitmap bitmap3 = bitmaps.get(getRaidus(r4));
        Matrix matrix3 = new Matrix();
        Circle circle3 = circles.get(3);
        matrix3.postTranslate(circle3.getLeft()+fTran,circle3.getTop()-fTran);
        canvas.drawBitmap(bitmap3,matrix3,null);

        Bitmap bitmap4 = bitmaps.get(getRaidus(r5));
        Matrix matrix4 = new Matrix();
        Circle circle4 = circles.get(4);
        matrix4.postTranslate(circle4.getLeft()+fTran,circle4.getTop()+fTran);
        canvas.drawBitmap(bitmap4,matrix4,null);
    }

    /*繪制圓的動畫效果*/
    private void drawCircle(Canvas canvas, Circle circle) {
        float top = circle.getTop();
        float left = circle.getLeft();
        float radius = circle.getRaidus();
        boolean isClockwise = circle.isClockwise();
        float speed = circle.getSpeed();

        canvas.drawColor(Color.TRANSPARENT);
        Paint paint = new Paint(this.paint);
        paint.setColor(Color.YELLOW);
        Bitmap trapezoidBitmap = getTrapezoidBitmap(circle, paint);

        Matrix matrix = new Matrix();
        int offsetX = trapezoidBitmap.getWidth() / 2;
        int offsetY = trapezoidBitmap.getHeight() / 2;
        matrix.postTranslate(-offsetX, -offsetY);

        if (isClockwise) {
            matrix.postRotate(speed+circle.getStartDegree());
        } else {
            matrix.postRotate(-speed+circle.getStartDegree());
        }
        float degree = getDegree(0.1f * speedArgu, radius);
        speed += degree;
        circle.setSpeed(speed);

        matrix.postTranslate(left + offsetX, top + offsetY);
        canvas.drawBitmap(trapezoidBitmap, matrix, null);


    }

    /*繪制圓*/
    private Bitmap getTrapezoidBitmap(Circle circle, Paint paint) {
        float radius = circle.getRaidus();
        if(bitmaps == null){
            bitmaps = new HashMap();
        }
        Bitmap bitmap = bitmaps.get(radius);
        if (bitmap != null) {
            return bitmap;
        }
        Bitmap bitmapTmp = Bitmap.createBitmap((int) (radius * 2 + gearHeight * 2), (int) (radius * 2 + gearHeight * 2), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmapTmp);
        canvas.drawColor(Color.TRANSPARENT);
        canvas.translate(bitmapTmp.getWidth() / 2, bitmapTmp.getHeight() / 2);
        /* 設置漸變色  */
        /*Shader mShader = new LinearGradient(0, 0, 100, 100,
                new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
                        Color.LTGRAY}, null, Shader.TileMode.REPEAT); // 一個材質,打造出一個線性梯度沿著一條線。
        paint.setShader(mShader);*/
        paint.setColor(circle.getColor());
        canvas.drawCircle(0, 0, radius, paint);
        drawGear(canvas,circle, paint);
        bitmaps.put(radius,bitmapTmp);
        return bitmapTmp;
    }

    /*在圓上畫齒輪*/
    private void drawGear(Canvas canvas, Circle circle, Paint paint) {
        updataHeight(circle.getRaidus());
        float radius = circle.getRaidus();
        Path path = new Path();
        path.moveTo(-(gearWidth / 2), -radius + 5);
        path.lineTo(gearWidth / 2, -radius + 5);
        path.lineTo(gearWidth / 2 - 10, -radius - gearHeight + 10);
        path.lineTo(-(gearWidth / 2 - 10), -radius - gearHeight + 10);
        path.lineTo(-(gearWidth / 2), -radius + 5);
        int num = (int) (360 / getDegree(length, radius));
        Paint p = new Paint(paint);
        p.setColor(circle.getColor());
        for (int i = 0; i <= num; i++) {
            canvas.drawPath(path, p);
            canvas.rotate(getDegree(length, radius));
        }
        canvas.save();
    }

    private void updataHeight(float radius) {
        gearHeight = radius/4f;
        if(gearHeight<35){
            gearHeight = 35;
        } else if(gearHeight > 50){
            gearHeight = 50;
        }
    }

    /**
     * 由弧長獲取度數
     */
    public float getDegree(float length, float r) {
        float degree = 360 * length / (2 * PI * r);
        return degree;
    }

    public float getPerimeter(float r) {
        float perimeter = 2 * PI * r;
        return perimeter;
    }

    /**
     * 對圓的半徑有要求
     *
     * @param multiple
     * @return
     */
    public float getRaidus(int multiple) {
        int gearNum = 5;
        gearNum += multiple;//gearNum代表圓上齒輪的個數
        float f1 = length * gearNum;
        float f = f1 / (2 * PI);
        return f;
    }

    public void setGear(int gear) {
        gearHeight = gearHeight + gear*3;
    }

    class Circle {
        float top;//頂部坐標
        float left;//左側坐標
        float raidus;//半徑
        float speed;//旋轉速度
        boolean clockwise;//旋轉方向
        float gearWidth;
        float gearHeight;
        float startDegree;//起始角度
        private int color;

        public int getColor() {
            return color;
        }

        public void setColor(int color) {
            this.color = color;
        }

        public float getStartDegree() {
            return startDegree;
        }

        public void setStartDegree(float startDegree) {
            this.startDegree = startDegree;
        }

        public float getGearWidth() {
            return gearWidth;
        }

        public void setGearWidth(float gearWidth) {
            this.gearWidth = gearWidth;
        }

        public float getGearHeight() {
            return gearHeight;
        }

        public void setGearHeight(float gearHeight) {
            this.gearHeight = gearHeight;
        }

        public Circle(float top, float left, float raidus, boolean clockwise, float speed, float startDegree, int color) {
            this.left = left;
            this.top = top;
            this.raidus = raidus;
            this.clockwise = clockwise;
            this.speed = speed;
            this.startDegree = startDegree;
            this.color = color;
        }

        public boolean isClockwise() {
            return clockwise;
        }

        public void setClockwise(boolean clockwise) {
            this.clockwise = clockwise;
        }

        public float getTop() {
            return top;
        }

        public void setTop(float top) {
            this.top = top;
        }

        public float getLeft() {
            return left;
        }

        public void setLeft(float left) {
            this.left = left;
        }

        public float getRaidus() {
            return raidus;
        }

        public void setRaidus(float raidus) {
            this.raidus = raidus;
        }

        public float getSpeed() {
            return speed;
        }

        public void setSpeed(float speed) {
            this.speed = speed;
        }
    }

}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved