溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android怎么實(shí)現(xiàn)加載視差動(dòng)畫效果

發(fā)布時(shí)間:2021-08-09 20:01:31 來源:億速云 閱讀:136 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“Android怎么實(shí)現(xiàn)加載視差動(dòng)畫效果”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Android怎么實(shí)現(xiàn)加載視差動(dòng)畫效果”吧!

基礎(chǔ)知識(shí)

繼 Android實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫的兩種方式 我們了解了 Android實(shí)現(xiàn)旋轉(zhuǎn)的兩種基本方法之后,我們來寫一個(gè)綜合案例

效果展示

Android怎么實(shí)現(xiàn)加載視差動(dòng)畫效果

代碼實(shí)現(xiàn) 

實(shí)現(xiàn)思路

從效果中我們可以看到 可以將其分為三個(gè)動(dòng)畫:

1、旋轉(zhuǎn)動(dòng)畫(Android實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫的兩種方式)

2、聚合動(dòng)畫

3、擴(kuò)展動(dòng)畫

代碼展示

package com.wust.mydialog;
 
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.LinearInterpolator;
 
import androidx.annotation.Nullable;
 
 
/**
 * ClassName: com.wust.mydialog.MyRotateView <br/>
 * Description: <br/>
 * date: 2021/8/7 12:13<br/>
 *
 * @author yiqi<br />
 * @QQ 1820762465
 * @微信 yiqiideallife
 * @技術(shù)交流QQ群 928023749
 */
public class MyRotateView extends View {
 
    //設(shè)置旋轉(zhuǎn)間隔時(shí)間
    private int SPLASH_CIRCLE_ROTATE_TIME = 1000;
    //設(shè)置中心圓半徑
    private float CENTER_CIRCLE_RADIUS;
    private float SMALL_CIRCLE_RADIUS;
    private float mCurrentSingle = 0f;
    private int[] mColorArray;
    private Paint mCirclePaint;
    private ValueAnimator va;
    private Matrix mSpaceMatrix;
 
    private LoadingState mLoadingState;
    //當(dāng)前中心圓半徑
    private float mCurCenterRadius;
    private float mDiagonal;
    private float mLineWidth;
 
    public MyRotateView(Context context) {
        super(context);
    }
 
    public MyRotateView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
 
    public MyRotateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
 
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
 
        //初始化參數(shù)
        initParams(width, height);
 
        setMeasuredDimension(width, height);
    }
 
    private void initParams(int w, int h) {
        //設(shè)置中心圓半徑
        CENTER_CIRCLE_RADIUS = 1 / 4.0f * w;
        //設(shè)置小圓的半徑
        SMALL_CIRCLE_RADIUS = 1 / 25.0f * w;
        //獲取小球顏色
        mColorArray = getResources().getIntArray(R.array.splash_circle_colors);
        //初始化畫筆
        mCirclePaint = new Paint();
        mCirclePaint.setDither(true);
        mCirclePaint.setAntiAlias(true);
        //初始化旋轉(zhuǎn)矩陣
        mSpaceMatrix = new Matrix();
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        if (mLoadingState == null) {
            mLoadingState = new RotateState();
        }
        mLoadingState.onDraw(canvas);
    }
 
    //定義 狀態(tài) 抽象類
    private abstract class LoadingState {
        public abstract void onDraw(Canvas canvas);
    }
 
    //旋轉(zhuǎn)動(dòng)畫
    private class RotateState extends LoadingState {
 
        public RotateState() {
            //計(jì)算每個(gè)小球的間隔
            double spaceAngle = 360.0d / mColorArray.length;
            //初始化旋轉(zhuǎn)矩陣
            mSpaceMatrix.reset();
            mSpaceMatrix.postRotate((float) spaceAngle, getWidth() / 2, getHeight() / 2);
 
            va = ObjectAnimator.ofFloat(0f, 360.0f);
            va.setDuration(SPLASH_CIRCLE_ROTATE_TIME);
            va.setRepeatCount(ValueAnimator.INFINITE);
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurrentSingle = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            va.setInterpolator(new LinearInterpolator());
            va.start();
        }
 
        @Override
        public void onDraw(Canvas canvas) {
            //繪制背景
            canvas.drawColor(Color.WHITE);
            //利用旋轉(zhuǎn)畫布法
            canvas.save();
            canvas.rotate(mCurrentSingle, getWidth() / 2, getHeight() / 2);
            for (int i = 0; i < mColorArray.length; i++) {
                canvas.concat(mSpaceMatrix);
                //為 每個(gè)球 畫筆 設(shè)置顏色
                mCirclePaint.setColor(mColorArray[i]);
                //利用旋轉(zhuǎn)畫布法
                float cx = getWidth() / 2 + CENTER_CIRCLE_RADIUS;
                float cy = getHeight() / 2;
 
                canvas.drawCircle(cx, cy, SMALL_CIRCLE_RADIUS, mCirclePaint);
            }
            canvas.restore();
        }
    }
 
    //聚合動(dòng)畫
    private class ScaleState extends LoadingState {
 
        public ScaleState() {
            va = ObjectAnimator.ofFloat(CENTER_CIRCLE_RADIUS,0);
            va.setDuration(SPLASH_CIRCLE_ROTATE_TIME);
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurCenterRadius = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            va.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mLoadingState = new ExtentState();
                }
            });
            va.setInterpolator(new AnticipateInterpolator());
            va.start();
        }
 
        @Override
        public void onDraw(Canvas canvas) {
            //繪制背景
            canvas.drawColor(Color.WHITE);
            //繪制小圓
            canvas.save();
            //這句話也不能調(diào),要不然不連貫
            canvas.rotate(mCurrentSingle,getWidth()/2,getHeight()/2);
            for (int i = 0; i < mColorArray.length; i++) {
                mCirclePaint.setColor(mColorArray[i]);
                canvas.concat(mSpaceMatrix);
                canvas.drawCircle(mCurCenterRadius+getWidth()/2,getHeight()/2,SMALL_CIRCLE_RADIUS,mCirclePaint);
            }
            canvas.restore();
        }
    }
 
    //擴(kuò)展動(dòng)畫
    public class ExtentState extends LoadingState{
 
        public ExtentState() {
            //初始化對(duì)角線
            float cx = getWidth()/2.0f;
            float cy = getHeight()/2.0f;
            mDiagonal = (float) Math.sqrt(Math.pow(cx,2)+Math.pow(cy,2));
 
            va = ObjectAnimator.ofFloat(mDiagonal,0);
            va.setDuration(3000);
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mLineWidth = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            va.setInterpolator(new LinearInterpolator());
            va.start();
        }
 
        @Override
        public void onDraw(Canvas canvas) {
            mCirclePaint.setColor(Color.WHITE);
            mCirclePaint.setStrokeWidth(mLineWidth*2);//元的半徑只會(huì)到達(dá)線寬的中間,所以要乘2
            mCirclePaint.setStyle(Paint.Style.STROKE);
            canvas.drawCircle(getWidth()/2,getHeight()/2,mDiagonal,mCirclePaint);
        }
    }
 
    public void dismiss() {
        if (mLoadingState instanceof RotateState){
            //取消旋轉(zhuǎn)值動(dòng)畫
            va.cancel();
            //創(chuàng)建縮放動(dòng)畫
            mLoadingState = new ScaleState();
            //刷新布局、可以寫也可以不寫
//            invalidate();
        }
    }
}

到此,相信大家對(duì)“Android怎么實(shí)現(xiàn)加載視差動(dòng)畫效果”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI