Android 自定义动画 LoadingView
?
項目地址:https://github.com/CuteWiseCode/MyLoadingView
先上效果圖
?
實現思路: 代碼實現主要結合自定義view 以及動畫屬性的方式,根據需求調整動畫的展示方式、加速度等。
一、動畫的布局文件
? ? ? 將白色背景圖以及需要轉動的圖片資源引用到布局文件中。布局文件以FrameLayout 作為父view,默認展示背景圖以及第一個轉動的圖片。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent" android:layout_gravity="center"><ImageViewandroid:layout_gravity="center"android:layout_width="86.0dip"android:layout_height="86.0dip"android:background="@mipmap/bg_animation" /><ImageViewandroid:layout_gravity="center"android:id="@+id/loading_view_01"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/loading_01" /><ImageViewandroid:layout_gravity="center"android:id="@+id/loading_view_02"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/loading_02"android:visibility="invisible" /><ImageViewandroid:layout_gravity="center"android:id="@+id/loading_view_03"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/loading_03"android:visibility="invisible" /><ImageViewandroid:layout_gravity="center"android:id="@+id/loading_view_04"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/loading_04"android:visibility="invisible" /><ImageViewandroid:layout_gravity="center"android:id="@+id/loading_view_05"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/loading_05"android:visibility="invisible" /></FrameLayout>二、創建一個 AnimationView 類
2.1、繼承 FrameLayout ,重寫兩個構造函數? ?AnimationView(Context paramContext) 和?AnimationView(@NonNull Context context, @Nullable AttributeSet attrs) ,了解自定義View的童鞋 應該知道,第一個構造函數用于在代碼中新建時調用,第二個構造函數用戶在布局文件中定義時調用。
//構造函數public AnimationView(Context paramContext){super(paramContext);inflate(getContext(), R.layout.loading_view, this);//layout_loading_viewinitializeView();}public AnimationView(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);inflate(getContext(), R.layout.loading_view, this);//layout_loading_viewinitializeView();}2.2、在構造函數中解析布局文件,并進行初始化
/*** 初始化控件*/private void initializeView(){this.viewf = ((ImageView)findViewById(R.id.loading_view_01));this.viewg = ((ImageView)findViewById(R.id.loading_view_02));this.viewh = ((ImageView)findViewById(R.id.loading_view_03));this.viewi = ((ImageView)findViewById(R.id.loading_view_04));this.viewj = ((ImageView)findViewById(R.id.loading_view_05));this.viewe = this.viewf;//測量控件的大小 UNSPECIFIED = 0 EXACTLY = 1 AT_MOST= 2int m = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);int n = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);this.viewf.measure(m, n);this.floata = (this.viewf.getMeasuredWidth() / 2);//獲取寬的值,除2this.floatb = (this.viewf.getMeasuredHeight() / 2);//獲取高的值除2initView();//開始動畫}2.3、設置并開始動畫,注意這里使用到動畫監聽? ?animationListener
public void initView(){tostartAnimation(this.viewe, 0.0F, 90.0F);} /*** * @param paramView 具體某個view* @param paramFloat1 0.0f* @param paramFloat2 90.0f* * */private void tostartAnimation(View paramView, float paramFloat1, float paramFloat2){AnimationLoad animation = new AnimationLoad(paramFloat1, paramFloat2, this.floata, this.floatb, this.floatc, true);animation.setDuration(this.intk);animation.setFillAfter(true);//true if the animation should apply its transformation after it endsanimation.setInterpolator(new AccelerateInterpolator());//Sets the acceleration curve for this animation. Defaults to a linear interpolation.Parameters:i The interpolator which defines the acceleration curveanimation.setAnimationListener(new animationListener());//the animation listener to be notifiedparamView.startAnimation(animation);}監聽類:animationListener。在動畫結束的時候,啟動runnable,啟動另一個動畫
private final class animationListenerimplements Animation.AnimationListener{private animationListener(){}public void onAnimationEnd(Animation paramAnimation){//The Runnable that will be executed.AnimationView.this.post(new runnable());}public void onAnimationRepeat(Animation paramAnimation){}public void onAnimationStart(Animation paramAnimation){}}runnable 線程:
private final class runnableimplements Runnable{private runnable(){}public void run(){viewf.setVisibility(View.GONE);//1viewg.setVisibility(View.GONE);//2viewh.setVisibility(View.GONE);//3viewi.setVisibility(View.GONE);//4viewj.setVisibility(View.GONE);//5viewe.setVisibility(View.GONE);intd++;if (intd % 5 == 0)//intdsetData(viewf);//第一張while (true){if (1 == intd % 5){setData( viewg); // continue;}if (2 == intd % 5){setData( viewh); // continue;}if (3 == intd % 5){setData( viewi); // continue;}if (4 == intd % 5)setData( viewj);viewe.setVisibility(View.VISIBLE);viewe.requestFocus();AnimationLoad animation = new AnimationLoad(-90.0F, 0.0F, floata, floatb, floatc, false);animation.setDuration(intk);animation.setFillAfter(true);animation.setInterpolator(new DecelerateInterpolator());//減速animation.setAnimationListener(new Animation.AnimationListener(){public void onAnimationEnd(Animation paramAnimation){AnimationView.this.initView();}public void onAnimationRepeat(Animation paramAnimation){}public void onAnimationStart(Animation paramAnimation){}});viewe.startAnimation(animation);return;}}}上述代碼中 AnimationLoad 類如下:繼承了Animation,使用Camera 以及Matrix? 定義了旋轉的方式。
private final float floata;private final float floatb;private final float floatc;private final float floatd;private final float floate;private final boolean boolf;private Camera camerag;public AnimationLoad(float paramFloat1, float paramFloat2, float paramFloat3, float paramFloat4, float paramFloat5, boolean paramBoolean){this.floata = paramFloat1;//0this.floatb = paramFloat2;//90.0fthis.floatc = paramFloat3;//172this.floatd = paramFloat4;//172this.floate = paramFloat5;//0this.boolf = paramBoolean;}protected void applyTransformation(float paramFloat, Transformation paramTransformation){float f1 = this.floata;//0.0ffloat f2 = f1 + paramFloat * (this.floatb - f1);//90float f3 = this.floatc;//172float f4 = this.floatd;//172Camera localCamera = this.camerag;Matrix localMatrix = paramTransformation.getMatrix();localCamera.save();//Saves the camera state. Each save should be balanced with a call to restore().//如果時加速if (this.boolf)localCamera.translate(0.0F, 0.0F, paramFloat * this.floate);//Applies a translation transform on all three axislocalCamera.translate(0.0F, 0.0F, this.floate * (1.0F - paramFloat));while (true){localCamera.rotateY(f2);//Applies a rotation transform around the Y axis.localCamera.getMatrix(localMatrix);//Computes the matrix corresponding to the current transformation and copies it to the supplied matrix object.localCamera.restore();//Restores the saved state, if any // localMatrix.postScale(0.5f, 0.5f);//使原來的圖像縮放成原來的1/2localMatrix.preTranslate(-f3, -f4);localMatrix.postTranslate(f3, f4);return;}}/*** Initialize this animation with the dimensions of the object being animated */public void initialize(int paramInt1, int paramInt2, int paramInt3, int paramInt4){super.initialize(paramInt1, paramInt2, paramInt3, paramInt4);this.camerag = new Camera();}分享到此結束,demo 請前往github,? 記得給個star哦
總結
以上是生活随笔為你收集整理的Android 自定义动画 LoadingView的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kotlin 与 Java 比较
- 下一篇: 第四篇:Mysql查询-多表联合查询-及