新聞中心
本文轉(zhuǎn)載自微信公眾號(hào)「Android開(kāi)發(fā)編程」,作者Android開(kāi)發(fā)編程。轉(zhuǎn)載本文請(qǐng)聯(lián)系A(chǔ)ndroid開(kāi)發(fā)編程公眾號(hào)。

創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),銀海企業(yè)網(wǎng)站建設(shè),銀海品牌網(wǎng)站建設(shè),網(wǎng)站定制,銀海網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,銀海網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
前言
這次我們介紹一下android中動(dòng)畫(huà)的分類:
View Animation(補(bǔ)間動(dòng)畫(huà));
Drawable Animation(幀動(dòng)畫(huà));
Property Animation(屬性動(dòng)畫(huà));
一、幀動(dòng)畫(huà)
幀動(dòng)畫(huà)是順序播放一組預(yù)先定義好的圖片,不同于View動(dòng)畫(huà),系統(tǒng)提供了另外一個(gè)類AnimationDrawable來(lái)使用幀動(dòng)畫(huà);
幀動(dòng)畫(huà)顧名思義就是通過(guò)順序一幀一幀播放圖片從而產(chǎn)生動(dòng)畫(huà)效果,效果類似放電影;
該動(dòng)畫(huà)缺點(diǎn)比較明顯,就是如果圖片過(guò)大過(guò)多會(huì)導(dǎo)致OOM。幀動(dòng)畫(huà)xml文件放置在drawable目錄下而非anim文件夾下;
幀動(dòng)畫(huà)的使用
首先我們找一組幀動(dòng)畫(huà)的圖片放入drawable-xhdpi文件夾下,其次在drawable文件夾下創(chuàng)建xml文件,如下所示:
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- ...
- view = findViewById(R.id.test);
- view.setBackgroundResource(R.drawable.drawable_test_anim);
- view.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- AnimationDrawable animationDrawable = (AnimationDrawable) view.getBackground();
- animationDrawable.start();
- }
- });
屬性介紹
必須是根節(jié)點(diǎn),包含一個(gè)或者多個(gè) - 元素,屬性有:
- android:oneshot true代表只執(zhí)行一次,false循環(huán)執(zhí)行;
- 類似一幀的動(dòng)畫(huà)資源;
- animation-list的子項(xiàng),包含屬性如下:
- android:drawable 一個(gè)frame的Drawable資源;
- android:duration 一個(gè)frame顯示多長(zhǎng)時(shí)間;
二、補(bǔ)間動(dòng)畫(huà)
補(bǔ)間動(dòng)畫(huà)是通過(guò)對(duì)view進(jìn)行旋轉(zhuǎn)、縮放、漸變、透明度變化,而達(dá)到的一種動(dòng)畫(huà)效果;
是一種漸進(jìn)式動(dòng)畫(huà)。并且可以通過(guò)組合以上四種操作,完成復(fù)雜的自定義動(dòng)畫(huà)效果;
缺點(diǎn)就是只是改變的view的展示狀態(tài),但是不會(huì)改變view的位置;
- android:duration="4000"
- android:fillAfter="true"
- android:fillBefore="true"
- android:interpolator="@[package:]anim/interpolator_resource"
- android:repeatMode="restart | reverse"
- android:repeatCount = “0”
- android:shareInterpolator="true"
- android:startOffset="float">
- android:fromAlpha="float"
- android:toAlpha="float" />
- android:fromXScale="float"
- android:fromYScale="float"
- android:pivotX="float"
- android:pivotY="float"
- android:toXScale="float"
- android:toYScale="float" />
- android:fromDegrees="float"
- android:pivotX="float"
- android:pivotY="float"
- android:toDegrees="float" />
- android:fromXDelta="float"
- android:fromYDelta="float"
- android:toXDelta="float"
- android:toYDelta="float" />
通用屬性說(shuō)明:
- android:duration=""動(dòng)畫(huà)時(shí)長(zhǎng),單位毫秒
- android:fillAfter="true"動(dòng)畫(huà)完成后是否停留在結(jié)束位置,默認(rèn)false
- android:fillBefore="true"動(dòng)畫(huà)完成后是否停留在起點(diǎn)位置。默認(rèn)true,優(yōu)先級(jí)低于fillAfter
- android:interpolator為動(dòng)畫(huà)的變化速度【可以單獨(dú)設(shè)置,可以直接放在set里面】
- android:repeatMode="restart | reverse"動(dòng)畫(huà)重復(fù)策略 restart從起點(diǎn)位置(正序)重復(fù),reverse從結(jié)束位置(倒序)重復(fù)
- android:repeatCount = “0”重復(fù)次數(shù) “infinite”為無(wú)線重復(fù)
- android:shareInterpolator="true"動(dòng)畫(huà)集合中的動(dòng)畫(huà)是否公用一個(gè)差值器
- android:startOffset="float"動(dòng)畫(huà)延遲時(shí)間
透明度動(dòng)畫(huà)
- 透明度動(dòng)畫(huà),通過(guò)改變view的透明度展示動(dòng)畫(huà)。對(duì)應(yīng)AlphaAnimation和 xml標(biāo)簽
- android:fromAlpha="float" 起始透明度,取值范圍(-1.0~1.0)
- android:toAlpha="float"結(jié)束時(shí)透明度,取值范圍(-1.0~1.0)
縮放動(dòng)畫(huà)
- 縮放動(dòng)畫(huà),通過(guò)修改view的大小展示動(dòng)畫(huà)。對(duì)應(yīng)ScaleAnimation類和 xml表情
- android:fromXScale="float"動(dòng)畫(huà)在水平方向X的起始縮放倍數(shù)
- android:fromYScale="float"動(dòng)畫(huà)在水平方向Y的結(jié)束縮放倍數(shù)
- android:toXScale="float"動(dòng)畫(huà)在豎直方向X的結(jié)束縮放倍數(shù)
- android:toYScale="float"動(dòng)畫(huà)在豎直方向Y的結(jié)束縮放倍數(shù)
- android:pivotX="float"縮放中心點(diǎn)的x坐標(biāo)
- android:pivotY="float"縮放中心點(diǎn)的y坐標(biāo)
旋轉(zhuǎn)動(dòng)畫(huà)
- 通過(guò)旋轉(zhuǎn)view展示動(dòng)畫(huà)。對(duì)應(yīng)RotateAnimation類和 xml標(biāo)簽
- android:fromDegrees="float"動(dòng)畫(huà)開(kāi)始時(shí) 視圖的旋轉(zhuǎn)角度(正數(shù) = 順時(shí)針,負(fù)數(shù) = 逆時(shí)針)
- android:toDegrees="float"動(dòng)畫(huà)結(jié)束時(shí) 視圖的旋轉(zhuǎn)角度(正數(shù) = 順時(shí)針,負(fù)數(shù) = 逆時(shí)針)
- android:pivotX="float"旋轉(zhuǎn)中心點(diǎn)的x坐標(biāo) 具體如上縮放中心點(diǎn)參數(shù)解釋
- android:pivotY="float"旋轉(zhuǎn)中心點(diǎn)的y坐標(biāo) 具體如上縮放中心點(diǎn)參數(shù)解釋
平移動(dòng)畫(huà)
- 平移動(dòng)畫(huà),更改view的展示位置展示動(dòng)畫(huà)。對(duì)應(yīng)TranslateAnimation類和 xml表情
- android:fromXDelta="float"view在水平x方向的起始值
- android:fromYDelta="float"view在水平y(tǒng)方向的起始值
- android:toXDelta="float"view在水平x方向的結(jié)束值
- android:toYDelta="float" view在水平y(tǒng)方向的結(jié)束值
具體動(dòng)畫(huà)的使用
應(yīng)用動(dòng)畫(huà)xml配置
- TextView textDemo = findViewById(R.id.text_demo);
- Animation animation = AnimationUtils.loadAnimation(getapplicationContext(),R.anim.rotate_animation_test);
- textDemo.startAnimation(animation);
使用java類配置動(dòng)畫(huà),具體參數(shù)類同xml參數(shù),建議使用xml配置動(dòng)畫(huà)
- AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 2.0f);
- textDemo.startAnimation(alphaAnimation);
監(jiān)聽(tīng)動(dòng)畫(huà)
- alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- //動(dòng)畫(huà)開(kāi)始回調(diào)
- }
- @Override
- public void onAnimationEnd(Animation animation) {
- //動(dòng)畫(huà)結(jié)束回調(diào)
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- //動(dòng)畫(huà)重復(fù)時(shí)回調(diào)
- }
- });
三、屬性動(dòng)畫(huà)
屬性動(dòng)畫(huà)本質(zhì)是通過(guò)改變對(duì)象的屬性(例如:x,y等屬性),來(lái)實(shí)現(xiàn)動(dòng)畫(huà)的,所以基本上是無(wú)所不能的,只要對(duì)象有這個(gè)屬性,就能實(shí)現(xiàn)動(dòng)畫(huà)效果;
屬性動(dòng)畫(huà)是在api 11的新特性,通過(guò)動(dòng)態(tài)的改變view的屬性從而達(dá)到動(dòng)畫(huà)效果。雖然可以使用nineoldandroid庫(kù)向下兼容,但是兼容本質(zhì)是使用補(bǔ)間動(dòng)畫(huà)完成,也就是說(shuō)不會(huì)更改view的屬性,也不會(huì)更改view的位置;
屬性動(dòng)畫(huà)比較常用的類:ValueAnimator、ObjectAnimator、AnimationSet,其中ObjectAnimator是ValueAnimator的子類,而AnminationSet是動(dòng)畫(huà)集合;
1.單個(gè)動(dòng)畫(huà)
- ObjectAnimator animator = ObjectAnimator
- .ofInt(textDemo, "backgroundColor", 0XffFF0000, 0Xff0000FF)
- .setDuration(2000);
- animator.setRepeatMode(ValueAnimator.RESTART);
- animator.setRepeatCount(10);
- animator.start();
2.動(dòng)畫(huà)集合
- AnimatorSet animatorSet = new AnimatorSet();
- ValueAnimator translationX = ObjectAnimator.ofFloat(textDemo, "translationX", 200f);
- ValueAnimator animator = ObjectAnimator
- .ofInt(textDemo, "backgroundColor", 0XffFF0000, 0Xff0000FF);
- animatorSet.playTogether(translationX,animator);
- animatorSet.setDuration(1000).start();
動(dòng)畫(huà)配置同樣可以使用xml配置;
3.差值器和估值器
差值器(Interpolator)
根據(jù)時(shí)間流逝百分比計(jì)算當(dāng)前屬性改變百分比。同xml配置動(dòng)畫(huà)中的 android:interpolator屬性配置,常見(jiàn)有LinearInterpolator(線性差值器)、AccelerateDecelerateInterpolator(加速減速差值器)等。自定義需要實(shí)現(xiàn)Interpolator或者TimeInterpolator。Interpolator接口繼承TimeInterpolator;
- // Interpolator接口
- public interface Interpolator extends TimeInterpolator{
- // 內(nèi)部只有一個(gè)方法
- float getInterpolation(float input) {
- // 參數(shù)說(shuō)明
- // input值值變化范圍是0-1,且隨著動(dòng)畫(huà)進(jìn)度(0% - 100% )均勻變化
- // 即動(dòng)畫(huà)開(kāi)始時(shí),input值 = 0;動(dòng)畫(huà)結(jié)束時(shí)input = 1
- // 而中間的值則是隨著動(dòng)畫(huà)的進(jìn)度(0% - 100%)在0到1之間均勻增加
- ...// 插值器的計(jì)算邏輯
- return xxx;
- // 返回的值就是用于估值器繼續(xù)計(jì)算的fraction值,下面會(huì)詳細(xì)說(shuō)明
- }
- // TimeInterpolator接口
- // 同上
- public interface TimeInterpolator {
- float getInterpolation(float input);
- }
估值器(TypeEvaluator)
根據(jù)當(dāng)前屬性改變百分比計(jì)算改變后的屬性值。屬性動(dòng)畫(huà)特有的屬性;自定義估值器需要實(shí)現(xiàn)TypeEvaluator接口;
- public interface TypeEvaluator {
- public Object evaluate(float fraction, Object startValue, Object endValue) {
- // 參數(shù)說(shuō)明
- // fraction:插值器getInterpolation()的返回值
- // startValue:動(dòng)畫(huà)的初始值
- // endValue:動(dòng)畫(huà)的結(jié)束值
- ....// 估值器的計(jì)算邏輯
- return xxx;
- // 賦給動(dòng)畫(huà)屬性的具體數(shù)值
- // 使用反射機(jī)制改變屬性變化
可以對(duì)任意屬性做屬性動(dòng)畫(huà),屬性動(dòng)畫(huà)要求動(dòng)畫(huà)作用的對(duì)象提供該屬性的get()和set()方法。因?yàn)閷傩詣?dòng)畫(huà)本質(zhì)就是根據(jù)外界傳遞的對(duì)象屬性的初始值和終點(diǎn)值,然后根據(jù)估值器和差值器計(jì)算屬性值,不斷調(diào)用屬性的set方法,通過(guò)時(shí)間的推移所傳遞的值,越來(lái)越近終點(diǎn)值;
注意:
對(duì)象屬性必須提供對(duì)應(yīng)的set方法,而且如果沒(méi)有初始值傳入的情況下必須要設(shè)置get方法,因?yàn)?系統(tǒng)要獲取初始值,如果沒(méi)有滿足條件則程序cash;
對(duì)象屬性的set方法對(duì)屬性做出改變,需要能夠通過(guò)某種方法表示出來(lái)。帶來(lái)ui展示效果的改變。否則動(dòng)畫(huà)不會(huì)生效;
ValueAnimator
使用ValueAnimator通過(guò)監(jiān)聽(tīng)動(dòng)畫(huà)過(guò)程,自己改變對(duì)象屬性完成動(dòng)畫(huà)
- ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
- valueAnimator.setDuration(2000);//動(dòng)畫(huà)持續(xù)時(shí)間
- valueAnimator.setRepeatCount(0);//重復(fù)次數(shù)
- valueAnimator.setRepeatMode(ValueAnimator.REVERSE);//重復(fù)方式,
- valueAnimator.setStartDelay(20);//開(kāi)始前延遲時(shí)間
- valueAnimator.setEvaluator(new IntEvaluator());//估值器
- valueAnimator.setInterpolator(new LinearInterpolator());//差值器
- valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- //獲取當(dāng)前動(dòng)畫(huà)屬性值,即1~100
- Integer animatedValue = (Integer) animation.getAnimatedValue();
- //獲取動(dòng)畫(huà)的百分比
- float animatedFraction = animation.getAnimatedFraction();
- ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
- int width = layoutParams.width;
- int height = layoutParams.height;
- layoutParams.height = height + 1;
- layoutParams.width=width+1;
- Log.e(TAG,"animatedValue: "+animatedValue+" animatedFraction : "+animatedFraction
- +" width : "+layoutParams.width+" height : "+layoutParams.height);
- textView.requestLayout();
- }
- });
- valueAnimator.start();
- }
四、注意事項(xiàng)
OOM注意,在幀動(dòng)畫(huà)中如果圖片過(guò)大、數(shù)量過(guò)多容易出現(xiàn);
內(nèi)存泄漏, 切記在activity銷毀時(shí),停止動(dòng)畫(huà)。否則一些無(wú)限循環(huán)動(dòng)畫(huà)將導(dǎo)致activity不能釋放而內(nèi)存泄漏。出現(xiàn)在屬性動(dòng)畫(huà)中,view動(dòng)畫(huà)不存在此類問(wèn)題;
View動(dòng)畫(huà)即補(bǔ)間動(dòng)畫(huà),是改變view的視覺(jué)位置,改變view的影像展示位置,而不改變真實(shí)位置;注意交互體驗(yàn)??赡軙?huì)出現(xiàn)view動(dòng)畫(huà)結(jié)束后,view無(wú)法隱藏的問(wèn)題及setVisibility(View.GONE)失效。此時(shí)調(diào)用view.clearAnimation()清除動(dòng)畫(huà)??尚迯?fù)此類問(wèn)題;
總結(jié)
公眾號(hào)里面是系統(tǒng)的總結(jié),但是要系統(tǒng)學(xué)習(xí)一類的知識(shí)點(diǎn)了,又不是很好;
于是就想寫(xiě)個(gè)小冊(cè)-掘金小冊(cè),這樣老鐵們就可以系統(tǒng)的學(xué)習(xí)某個(gè)知識(shí)點(diǎn)了;
文章標(biāo)題:App開(kāi)發(fā)中三種動(dòng)畫(huà)使用和屬性詳解
轉(zhuǎn)載來(lái)源:http://www.5511xx.com/article/ccddcoo.html


咨詢
建站咨詢
