日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android之动画

發布時間:2023/12/20 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android之动画 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android的動畫可以分為三種,View動畫、幀動畫、屬性動畫。View動畫通過對場景里的對象不斷做圖像變化(平移、縮放、旋轉、透明度)從而產生動畫效果,它是一種漸進式動畫,而且View動畫支持自定義。幀動畫可以理解為圖片切換動畫(如果圖片過多,會導致OOM)。屬性動畫為API11的新特性,屬性動畫通過通過動態地改變對象的屬性從而達到動畫效果。

  • View動畫

View動畫的種類:View動畫的四種變換效果對應著Animation的四個子類。TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation。這四種動畫可以通過XML來定義,也可以通過代碼動態創建。對于View動畫來說,建議XML來定義,這是因為XML格式的動畫可讀性好。

View動畫的四種變換
名稱標簽子類效果
平移動畫<translate>TranslateAnimation移動View
縮放動畫<scale>ScaleAnimation放大或縮小View
旋轉動畫<rotate>RotateAnimation旋轉View
透明度動畫<alpha>AlphaAnimation改變View的透明度

?

?

?

?

?

?

?

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:shareInterpolator="true"android:duration="1000"android:fillAfter="false"><alpha android:fromAlpha="float"android:toAlpha="float" /><scale android:fromXScale="float"android:toXScale="float"android:fromYScale="float"android:toYScale="float"android:pivotX="float"android:pivotY="float" /><translate android:fromXDelta="float"android:toXDelta="float"android:fromYDelta="float"android:toYDelta="float" /><rotate android:fromDegrees="float"android:toDegrees="float"android:pivotX="float"android:pivotY="float" /> </set>

View動畫可以是單個動畫,也可以是一系列動畫組成。<set>表示動畫集合,對應AnimationSet類。

android:interpolator:表示動畫集合所使用的插值器,插值器影響動畫的速度,比如非勻速動畫就需要通過插值器來控制動畫的播放速度。

android:shareInterpolator:表示集合中的動畫是否共享同一個插值器。如果不指定插值器,那么子動畫就需要單獨指定所需要的插值器或者使用默認值。

AlphaAnimation anim = (AlphaAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_test); TextView tv = findViewById(R.id.tv); tv.startAnimation(anim);

除了XML定義動畫之外,還可以使用代碼創建動畫。

AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1); alphaAnimation.setDuration(300); TextView tv = findViewById(R.id.tv); tv.startAnimation(alphaAnimation);

?

?注意:通過Animation的setAnimationListener的方法可以給View動畫添加過程監聽。如適用于帶動畫的啟動頁,監聽動畫完成后進入MainActivity。

anim.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {} });

?

自定義View動畫:

自定義View動畫是一件簡單而復雜的事情。說簡單是:因為派生一種新動畫只需要集成Animation這個抽象類,然后重寫它的initialize和applyTransformation方法。在initialize中進行初始化工作,在applyTransformation中進行相應的矩陣變換即可。很多時候需要Camera來簡化矩陣變換過程。說復雜,是因為需要運用到矩陣變換的過程,使用到數學上的概念。之后再做相關的分析講解。

?

  • 幀動畫

幀動畫順序播放一組預先定義好的圖片,類似電影播放。不同于View動畫,系統提供另外一個類AnimationDrawable來使用幀動畫。幀動畫的使用比較簡單,先使用XML來定義一個AnimationDrawable。在drawable目錄下創建:

<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false"><item android:drawable="@drawable/img1" android:duration="500"/><item android:drawable="@drawable/img2" android:duration="500"/><item android:drawable="@drawable/img3" android:duration="500"/> </animation-list>

將上述的Drawable作為View的背景并通過Drawable來播放動畫。

TextView tv = findViewById(R.id.tv); tv.startAnimation(alphaAnimation); AnimationDrawable animationDrawable = (AnimationDrawable) tv.getBackground(); animationDrawable.start();

注意幀動畫比較容易引起OOM,所以避免使用尺寸較大的圖片。

?

  • View動畫的特殊場景使用

在一些特殊場景下,如ViewGroup中控制子元素的出場效果,在Activity中實現不同Activity之間的切換效果。

?

LayoutAnimation作用于ViewGroup,作為ViewGroup指定一個動畫,這樣當它的子元素出場時都具有這樣的效果。常見的ListView的Item的出場以一定的動畫效果出現。

定義LayoutAnimation如下:

//res/anim/anim_layout.xml
<?
xml version="1.0" encoding="utf-8"?> <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"android:delay="0.5"android:animationOrder="normal"android:animation="@anim/anim_item" />

delay表示子元素開始動畫的時間延遲。比如說元素入場動畫周期為300ms,那么0.5表示每個子元素都需要延遲150ms才能播放入場動畫。第一個子元素延遲150ms開始播放入場動畫,第二個子元素延遲300m開始播放入場,以此類推。

animationOrder:子元素動畫順序,normal, reverse和random。

android:animation: 為元素指定具體的入場動畫。

為ViewGroup指定android:layoutAnimation屬性,對于ListView而言,指定之后就是Item的出場動畫了。除了XML中指定LayoutAnimation之外,還可以通過LayoutAnimationController來實現,具體如下:

ListView listView = findViewById(R.id.list_view); Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item); LayoutAnimationController controller = new LayoutAnimationController(animation); controller.setDelay(0.5f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL); listView.setLayoutAnimation(controller);

?

?

Activity的切換效果:

Activity有默認的切換效果,但是這個效果是可以自定義的,主要用到overridePendingTransition(int enterAnim, int exitAnim)這個方法,這個必須在startActivity(intent)和finish()之后被調用才能生效,它的參數含義如下:

enterAnim - Activity被打開時,所需要的動畫資源id

exitAnim - Activity被暫停時,所需要的動畫資源id

當啟動一個Activity時,可以按照如下方式為其添加自定義的切換效果:

Intent intent = new Intent(this, TestActivity.class); startActivity(intent); overridePendingTransition(R.anim.enter_anim, R.anim.exitAnim);

?

當Activityt退出時,也可以為其指定自定義的切換效果:

@Override public void finish() {super.finish();overridePendingTransition(R.anim.enter_anim, R.anim.exitAnim); }

?

Fragment也可以添加切換效果,可以通過FragmentTransaction中的setCustomAnimations()方法來添加切換動畫,這個切換動畫需要時View動畫。還有其他的方法為Activity和Fragment添加切換動畫,但是需要考略兼容為題。

?

  • 屬性動畫

屬性動畫是API11新加入的特性,和View動畫不同,它對作用的對象進行擴展,屬性動畫可以對任何對象做動畫,甚至還可以沒有對象。屬性動畫可以對任意對象的屬性進行動畫而不僅僅是View。屬性動畫中有ValueAnimator, ObjectAnimator和AnimatorSet等概念。為兼容之前的版本,采用nineoldandroids源動畫庫。

ObjectAnimator繼承自ValueAnimator,AnimatorSet是動畫集合。屬性動畫需要定義在res/animator/目錄下。

  • 改變一個對象myObject的translationY屬性,讓其沿著Y軸向上移動一段距離,在默認的時間完成。
  • ObjectAnimator.ofFloat(tv, "translationY", -myObject.getHeight()).start();
  • 改變一個對象背景色屬性,典型的改變View背景,下面的動畫可以讓背景色在3s內實現從0xFFFF8080到0xFF8080FF的漸變,動畫會無限循環而且會有反轉的效果。
  • ValueAnimator colorAnim = ObjectAnimator.ofInt(myObject, "backgroundColor", 0xFFFF8080, 0xFF8080FF);colorAnim.setDuration(3000);colorAnim.setEvaluator(new ArgbEvaluator());colorAnim.setRepeatCount(ValueAnimator.INFINITE);colorAnim.setRepeatMode(ValueAnimator.REVERSE);colorAnim.start();
  • 動畫集合,5秒內對View的旋轉,平移,縮放和透明度都進行改變。
  • AnimatorSet set = new AnimatorSet(); set.playTogether(ObjectAnimator.ofFloat(view, "rotationX", 0, 360),ObjectAnimator.ofFloat(view, "rotationY", 0, 180),ObjectAnimator.ofFloat(view, "rotation", 0, -90),ObjectAnimator.ofFloat(view, "translationX", 0, 100),ObjectAnimator.ofFloat(view, "translationY", 0, 100),ObjectAnimator.ofFloat(view, "scaleX", 1, 1.5f),ObjectAnimator.ofFloat(view, "scaleY", 1, 0.5f),ObjectAnimator.ofFloat(view, "alpha", 1, 0.5f, 1) ); set.setDuration(5 * 1000).start();
  • 屬性動畫除了代碼實現之外,還可以通過XML來定義。

    eg.

    <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"><objectAnimator android:propertyName="x"android:duration="300"android:valueTo="300"android:valueType="intType" /><objectAnimator android:propertyName="y"android:duration="300"android:valueTo="300"android:valueType="intType"/> </set>

    加載上面的屬性動畫:

    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.property_animator); set.setTarget(view); set.start();

    建議:屬性動畫采用代碼來實現,這是因為代碼的方式會比較簡單,更重要的是,在一個屬性起始值無法確定的情況下,將無法將屬性定義在xml文件中。

    • 插值器和估值器

    ?TimeInterpolater:時間插值器,它的作用是根據時間流逝的百分比來計算出當前屬性改變的百分比,系統預置的有LinearInterpolator(線性插值器:勻速動畫)、AccelerateDecelerateInterpolator(加速減速插值器:動畫兩頭慢,中間快),DeceleratrInterpolator(減速插值器:動畫越來越慢)等。

    TypeEvaluator:類型估值算法,也叫做估值器。它的作用是根據當前屬性改變的百分比來計算改變后的屬性值,系統預置的有IntEvaluator(針對整型屬性),FloatEvaluator(針對浮點型屬性),ArgbEvaluator(針對Color屬性)。

    ?

    線性差值器,屬于勻速動畫,其源碼為:

    /*** An interpolator where the rate of change is constant*/ @HasNativeInterpolator public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {public LinearInterpolator() {}public LinearInterpolator(Context context, AttributeSet attrs) {}public float getInterpolation(float input) {return input; /** 輸入值和返回值一樣 */}/** @hide */@Overridepublic long createNativeInterpolator() {return NativeInterpolatorFactoryHelper.createLinearInterpolator();} }

    那到底輸入數值是什么?這需要估值算法來確定,如整型估值器的源碼為:

    public class IntEvaluator implements TypeEvaluator<Integer> {/*** This function returns the result of linearly interpolating the start and end values, with* <code>fraction</code> representing the proportion between the start and end values. The* calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,* where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,* and <code>t</code> is <code>fraction</code>.** @param fraction The fraction from the starting to the ending values* @param startValue The start value; should be of type <code>int</code> or* <code>Integer</code>* @param endValue The end value; should be of type <code>int</code> or <code>Integer</code>* @return A linear interpolation between the start and end values, given the* <code>fraction</code> parameter.*/public Integer evaluate(float fraction, Integer startValue, Integer endValue) {int startInt = startValue;return (int)(startInt + fraction * (endValue - startInt));} }

    evaluate方法的三個參數分別是估值小數,起始值,結束值。例子:勻速動畫,對象從0位置到100,當估值小數位0.5的時候,根據算法result = 0 + 0.5(100 - 0) = 50。

    屬性動畫要求對象有該屬性的set方法和get方法(可選)。除了系統預置的插值器和估值算法外,我們還可以自定義。自定義差值算法需要實現Interpolator或TimeInterpolator;自定義估值算法需要實現TypeEvaluator。

    屬性動畫的監聽:

    有兩個常用的屬性動畫監聽:AnimatorListener, AnimatorUpdateListener

    ObjectAnimator animator = new ObjectAnimator(); animator.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {} });

    從AnimatorListener的定義來看,它可以監聽動畫的開始,結束,取消和重復動畫。

    public static interface AnimatorUpdateListener {/*** <p>Notifies the occurrence of another frame of the animation.</p>** @param animation The animation which was repeated.*/void onAnimationUpdate(ValueAnimator animation);}

    AnimatorUpdateListener比較特殊,它會監聽整個動畫過程,動畫是由許多幀組成的,每播放一幀onAnimationUpdate()就會被調用一次,利用這個特征,我們可以做一些特殊事情。

    ?

    • 對任意屬性做動畫

    ?例如TextView的寬度動畫變為800的動畫,當layout_width的屬性為wrap_content時,是有動畫的,但是如果設置為固定值之后,下面的屬性動畫就沒有效果了。

    //高度從原來的默認值變為800 ObjectAnimator objectAnimator = ObjectAnimator.ofInt(textView, "width", 800); objectAnimator.setDuration(500); objectAnimator.start();

    ?

    ?這是因為:

    public void setWidth(int pixels) {mMaxWidth = mMinWidth = pixels;mMaxWidthMode = mMinWidthMode = PIXELS;requestLayout();invalidate(); } public final int getWidth() {return mRight - mLeft;}

    setWidth不是所謂意義上的寬度設置,所以就不會產生動畫。對任意屬性做動畫,一般需要有set和get方法,設置流程如下:

    ?如果沒有屬性設置獲取權限,可以定義一個包裹類進行封裝,實現set和get方法;如:

    public static class ViewWrapper{private View mTarget;public ViewWrapper(View target){mTarget = target;}public void setWidth(int width){mTarget.getLayoutParams().width = width;mTarget.requestLayout();}public int getWidth(){return mTarget.getLayoutParams().width;} } ViewWrapper viewWrapper = new ViewWrapper(view); ObjectAnimator widthAnimator = ObjectAnimator.ofInt(viewWrapper, "width", btn.getWidth(), 800).setDuration(500); widthAnimator.start();

    這樣,上面的TextView就可以實現寬度的動畫效果了。

    自定義View設置相關屬性,進行動畫案例:

    /*** 自定義圓環* 對屬性progress設置set和get方法* 就可以對CircleProgress的progress進行屬性動畫*/ public class CircleProgress extends View{private Paint mPaint;private RectF rectF;private int progress = 270;int width, height;public CircleProgress(Context context) {super(context);init();}public CircleProgress(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init(){mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(20);mPaint.setColor(Color.RED);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);if (widthMode == MeasureSpec.EXACTLY){width = widthSize;}else{width = 100; //設置為默認值 }if (heightMode == MeasureSpec.EXACTLY){height = heightSize;}else{height = 100; //設置為默認值 }rectF = new RectF(20, 20, width-20, height-20);setMeasuredDimension(Math.min(width, height), Math.min(width, height)); //矩形 }@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawArc(rectF, -90, progress, false, mPaint);invalidate();}public void setProgress(int progress){this.progress = progress;}public int getProgress(){return progress;} }

    ?

    轉載于:https://www.cnblogs.com/denluoyia/p/8978045.html

    總結

    以上是生活随笔為你收集整理的Android之动画的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。