Android實(shí)現(xiàn)雅虎新聞?wù)虞d視差動畫效果
基礎(chǔ)知識
繼 Android實(shí)現(xiàn)旋轉(zhuǎn)動畫的兩種方式 我們了解了 Android實(shí)現(xiàn)旋轉(zhuǎn)的兩種基本方法之后,我們來寫一個(gè)綜合案例
效果展示
代碼實(shí)現(xiàn)
實(shí)現(xiàn)思路
從效果中我們可以看到 可以將其分為三個(gè)動畫:
1、旋轉(zhuǎn)動畫(Android實(shí)現(xiàn)旋轉(zhuǎn)動畫的兩種方式)
2、聚合動畫
3、擴(kuò)展動畫
代碼展示
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)動畫 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(); } } //聚合動畫 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ò)展動畫 public class ExtentState extends LoadingState{ public ExtentState() { //初始化對角線 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);//元的半徑只會到達(dá)線寬的中間,所以要乘2 mCirclePaint.setStyle(Paint.Style.STROKE); canvas.drawCircle(getWidth()/2,getHeight()/2,mDiagonal,mCirclePaint); } } public void dismiss() { if (mLoadingState instanceof RotateState){ //取消旋轉(zhuǎn)值動畫 va.cancel(); //創(chuàng)建縮放動畫 mLoadingState = new ScaleState(); //刷新布局、可以寫也可以不寫 // invalidate(); } } }
到此這篇關(guān)于Android實(shí)現(xiàn)雅虎新聞?wù)虞d視差動畫效果的文章就介紹到這了,更多相關(guān)android視覺動畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android:TextView簡單設(shè)置文本樣式和超鏈接的方法
這篇文章主要介紹了android:TextView簡單設(shè)置文本樣式和超鏈接的方法,涉及TextView常見文字屬性的相關(guān)操作技巧,需要的朋友可以參考下2016-08-08橫豎屏切換導(dǎo)致頁面頻繁重啟screenLayout解析
這篇文章主要為大家介紹了橫豎屏切換導(dǎo)致頁面頻繁重啟screenLayout解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android短信備份及數(shù)據(jù)插入實(shí)現(xiàn)代碼解析
這篇文章主要介紹了Android短信備份及數(shù)據(jù)插入實(shí)現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Android開發(fā)之開發(fā)者頭條(一)啟動頁實(shí)現(xiàn)
這篇文章主要介紹了Android開發(fā)之開發(fā)者頭條(一)啟動頁實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-04-04Android開發(fā)中TextView文本過長滾動顯示實(shí)現(xiàn)方法分析
這篇文章主要介紹了Android開發(fā)中TextView文本過長滾動顯示實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Android項(xiàng)目開發(fā)中TextView顯示超長文本的具體操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-02-02Android12四大組件之Activity生命周期變化詳解
雖然說我們天天都在使用Activity,但是你真的對Activity的生命機(jī)制完全了解了嗎?Activity的生命周期方法只有七個(gè),但是其實(shí)那只是默認(rèn)的情況。也就是說在其他情況下,Activity的生命周期可能不會是按照我們以前所知道的流程,本章著重講解Activity的生命周期變化2022-07-07Android App開發(fā)中ViewPager組件的入門使用教程
這篇文章主要介紹了Android App開發(fā)中ViewPager組件的入門使用教程,ViewPager主要用來實(shí)現(xiàn)通過滑動來切換頁面的效果,需要的朋友可以參考下2016-03-03Android開發(fā)實(shí)現(xiàn)的Intent跳轉(zhuǎn)工具類實(shí)例
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的Intent跳轉(zhuǎn)工具類,簡單描述了Intent組件的功能并結(jié)合實(shí)例形式給出了頁面跳轉(zhuǎn)、拍照、圖片調(diào)用等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11