android中的動畫

1:逐幀動畫

在res/drawable目錄下新建動畫XML文件经瓷,如下所示

<?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/ic_account_circle_white_24dp" android:duration="1000"/>
<item android:drawable="@drawable/kecheng" android:duration="1000"/>
<item android:drawable="@drawable/faburen" android:duration="1000"/>
</animation-list>

設(shè)置背景,如下:

...
 <ImageView
        android:id="@+id/image"
        android:src="@drawable/zhuzhen"http://設(shè)置src為上面的動畫文件
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
...

在java文件中啟動動畫

...
 ((AnimationDrawable)imageView.getDrawable()).start();
...

2:補間動畫和屬性動畫

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:layout_marginTop="20dp"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <LinearLayout
            android:layout_gravity="right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <Button
                android:text="補間動畫之ScaleAnimation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button"/>
            <Button
                android:text="補間動畫之RotateAnimation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button1"/>
            <Button
                android:text="補間動畫之AlphaAnimation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button2"/>
            <Button
                android:text="補間動畫之TranslateAnimation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button3"/>
            <Button
                android:text="補間動畫集合之AnimationSet"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button6"/>
            <Button
                android:text="屬性動畫之ValueAnimator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button4"/>
            <Button
                android:text="屬性動畫之ObjectAnimator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button5"/>
            <Button
                android:text="屬性動畫集合之AnimatorSet"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button7"/>
        </LinearLayout>

    <ImageView
        android:id="@+id/image"
        android:src="@drawable/ic_launcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</FrameLayout>
注意:在補間動畫中洞难,用setAnimation方法和start方法是不能啟動一個動畫的舆吮,需要用到startAnimation方法才能啟動動畫
public class CeShi extends AppCompatActivity {
    private Button button;
    private Button button1;
    private Button button2;
    private Button button3;
    private Button button4;
    private Button button5;
    private Button button6;
    private Button button7;
    private ImageView imageView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ceshi);
        imageView = (ImageView) findViewById(R.id.image);
        button = (Button) findViewById(R.id.button);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);
        button4 = (Button) findViewById(R.id.button4);
        button5 = (Button) findViewById(R.id.button5);
        button6 = (Button) findViewById(R.id.button6);
        button7 = (Button) findViewById(R.id.button7);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ScaleAnimation scaleAnimation = new ScaleAnimation(0, 2, 1, 0);
                scaleAnimation.setDuration(2000);
                imageView.startAnimation(scaleAnimation);
            }
        });
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RotateAnimation rotateAnimation = new RotateAnimation(0, -360);
                rotateAnimation.setDuration(2000);
                imageView.startAnimation(rotateAnimation);
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
                alphaAnimation.setDuration(2000);
                imageView.startAnimation(alphaAnimation);
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TranslateAnimation translateAnimation = new TranslateAnimation(0, 300, 100, 400);
                translateAnimation.setDuration(2000);
                imageView.startAnimation(translateAnimation);
            }
        });
        button6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AnimationSet animationSet=new AnimationSet(false);
                animationSet.setDuration(1000);
                animationSet.addAnimation(new TranslateAnimation(100,400,100,400));
                animationSet.addAnimation(new ScaleAnimation(0,2,2,0));
                imageView.startAnimation(animationSet);//以下兩句代碼是錯誤的,看似沒毛病队贱,但是并不能播放動畫色冀,需要startAnimation這個方法才能播放動畫
               /* imageView.setAnimation(animationSet);
                animationSet.start();*/
            }
        });
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ValueAnimator valueAnimator = new ValueAnimator();
                valueAnimator.setIntValues(0, 100, 300, 0);
                valueAnimator.setDuration(2000);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        imageView.layout((int) animation.getAnimatedValue(), (int) animation.getAnimatedValue(),
                                (int) animation.getAnimatedValue() + imageView.getWidth(), (int) animation.getAnimatedValue() + imageView.getHeight());
                    }
                });
                valueAnimator.start();
            }
        });
        button5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(imageView,"rotation",-360,100,200,-190,0,200);
                objectAnimator.setDuration(4000);
                objectAnimator.start();
            }
        });
        button7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AnimatorSet animatorSet=new AnimatorSet();
                animatorSet.setDuration(1000);
                List<Animator> list=new ArrayList<>();
                ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(imageView,"alpha",0,1,0.5f,1,0,1);
                ObjectAnimator objectAnimator1=ObjectAnimator.ofFloat(imageView,"translationX",100,200,100,0,500,0);
                list.add(objectAnimator);
                list.add(objectAnimator1);
                animatorSet.playSequentially(list);
                animatorSet.start();
            }
        });
    }
}

心得:都可以以xml文件的形式來實現(xiàn)動畫, 補間動畫調(diào)用AnimationUtils.loadAnimation來加載xml動畫文件柱嫌,屬性動畫調(diào)用AnimatorInflater.loadAnimator來加載xml動畫文件

補充:屬性動畫中用到的屬性名如下:(只是部分屬性锋恬,這里的屬性對應(yīng)的就是xml文件中的屬性名)
參考博客如下:

https://mp.weixin.qq.com/s/HQ0Z_RpSzbYzuqdJjw3FLQ
http://www.reibang.com/p/41d61a9b4a60 (這個里面有的東西就錯的了,不可以全看)

-------------------------------------------------------------------------

閱讀拋物線大神的文章之后的總結(jié)编丘,如下(屬性動畫)

1:ViewPropertyAnimator對象

imageView.animate().translationX(500);//只要是繼承自View的視圖就都有animate()方法与学,這個方法的返回值為ViewPropertyAnimator,看ViewPropertyAnimator的源碼可知嘉抓,調(diào)用了translationX()方法后索守,最后我們所設(shè)置動畫的view將會調(diào)用view自身的postOnAnimation來實現(xiàn)動畫。另外imageView.setTranslationX(500)也能實現(xiàn)平移掌眠,但是效果比較生硬蕾盯,一下子就平移過去了,沒有ViewPropertyAnimator中的translationX的效果好蓝丙,ViewPropertyAnimator中的translationX的平移能夠讓人看清平移的過程级遭。當然也可以同時設(shè)置view的多個屬性,如imageView.animate().translationX(800).alpha(0.3f).rotation(90).scaleX(3).setDuration(2000).setStartDelay(1000).setInterpolator(new CycleInterpolator(0.5f));//設(shè)置了延遲開始時間渺尘,持續(xù)時間挫鸽,速度插值器,添加監(jiān)聽器等鸥跟。

圖中可以看到丢郊, View 的每個方法都對應(yīng)了 ViewPropertyAnimator 的兩個方法盔沫,其中一個是帶有 -By 后綴的,例如枫匾,View.setTranslationX() 對應(yīng)了ViewPropertyAnimator.translationX() 和 ViewPropertyAnimator.translationXBy() 這兩個方法架诞。其中帶有 -By() 后綴的是增量版本的方法,例如干茉,translationX(100) 表示用動畫把 View 的 translationX 值漸變?yōu)?100谴忧,而 translationXBy(100) 則表示用動畫把 View 的 translationX 值漸變地增加 100。

2:ObjectAnimator對象

可以通過ObjectAnimator對象來實現(xiàn)動畫角虫,ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(imageView,"TranslationX",300,200,500,100);//也可以給動畫設(shè)置延遲開始時間沾谓,監(jiān)聽器,持續(xù)時間戳鹅,速度插值器之類的屬性均驶,同ViewPropertyAnimator對象的屬性,另外ObjectAnimator對象還多了一個暫停的監(jiān)聽器枫虏,ViewPropertyAnimator對象沒有該監(jiān)聽器妇穴,(插點ViewPropertyAnimator的知識點,ViewPropertyAnimator對象還有兩個特有的方法隶债,就是withStartAction/withEndAction()方法伟骨,是一次性的,在動畫執(zhí)行結(jié)束后就自動棄掉了,withEndAction() 設(shè)置的回調(diào)只有在動畫正常結(jié)束時才會被調(diào)用燃异,而在動畫被取消時不會被執(zhí)行携狭。這點和 AnimatorListener.onAnimationEnd() 的行為是不一致的),最后objectAnimator.start();啟用動畫回俐。

再來個示例代碼逛腿,注意看代碼后面的備注,setRepeatCount仅颇,setRepeatMode单默,setEvaluator這三個方法ViewPropertyAnimator對象是沒有的,但是ObjectAnimator對象有忘瓦。

 ObjectAnimator objectAnimator = ObjectAnimator.ofInt(textView, "textColor", 0xffff0000, 0xff00ff00);
//這里的第二個參數(shù)的屬性對應(yīng)的就是xml文件中view的屬性搁廓,這里的屬性必須是視圖所擁有的屬性才行,
//也就是說在xml文件中能找到視圖的該屬性才行耕皮。比如 ObjectAnimator.ofFloat(textView, "textSize",100,10,300,20,0);
//給textview的textsize做動畫境蜕,因為textview有textsize屬性,所以就能做屬性動畫凌停,屬性動畫很強大粱年。
        objectAnimator.setDuration(2000);
        objectAnimator.setRepeatCount(10);
        objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);
        objectAnimator.setEvaluator(new ArgbEvaluator());//在這里設(shè)置估值器
        objectAnimator.start();

如果用ObjectAnimator在一個動畫中改變多個屬性的話,這時就用到了PropertyValuesHolder

        PropertyValuesHolder p=PropertyValuesHolder.ofFloat("scaleX", 2);
        PropertyValuesHolder p1=PropertyValuesHolder.ofFloat("scaleY", 2);
        PropertyValuesHolder p2=PropertyValuesHolder.ofFloat("alpha", 0.5f);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(textView,p,p1,p2);
        objectAnimator.setDuration(2000);
        objectAnimator.setRepeatCount(10);
        objectAnimator.start();

可以用AnimatorSet將多個ObjectAnimator動畫配合執(zhí)行

        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView,"scaleX",3);
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(textView,"scaleY",2);
        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(textView,"translationX",200,400,10);
        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(2000);
        animatorSet.playTogether(objectAnimator,objectAnimator1,objectAnimator2);//動畫同時執(zhí)行
        //animatorSet.playSequentially(objectAnimator,objectAnimator1,objectAnimator2);//動畫依次執(zhí)行
        animatorSet.start();

PropertyValuesHolders.ofKeyframe() 把同一個屬性拆分

        Keyframe keyframe=Keyframe.ofFloat(0,100);//第一個參數(shù)0表示時間剛開始的時候
        Keyframe keyframe1=Keyframe.ofFloat(0.5f,200);//0.5表示時間執(zhí)行到一半的時候
        Keyframe keyframe2=Keyframe.ofFloat(1,150);//1表示時間結(jié)束的時候
        PropertyValuesHolder propertyValuesHolder=PropertyValuesHolder.ofKeyframe("textSize",keyframe,keyframe1,keyframe2);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(textView,propertyValuesHolder);
        objectAnimator.setDuration(2000);
        objectAnimator.start();

TypeEvaluator估值器的說明

系統(tǒng)有IntEvaluato(當執(zhí)行ObjectAnimator.ofInt時罚拟,系統(tǒng)自動調(diào)用IntEvaluator)台诗,F(xiàn)loatEvaluator(當執(zhí)行ObjectAnimator.ofFloat時完箩,系統(tǒng)自動調(diào)用FloatEvaluator,其他的類似)等估值器拉队,如果是自己自定義估值器的話弊知,那就調(diào)用ObjectAnimator.ofObject,通過setEvaluator來設(shè)置自定義的估值器粱快。

ObjectAnimator的總結(jié):

使用 PropertyValuesHolder 來對多個屬性同時做動畫吉捶;
使用 AnimatorSet 來同時管理調(diào)配多個動畫;
PropertyValuesHolder 的進階使用:使用 PropertyValuesHolder.ofKeyframe() 來把一個屬性拆分成多段皆尔,執(zhí)行更加精細的屬性動畫。

3:ValueAnimator對象

ValuesAnimator币励。很多時候慷蠕,你用不到它,只是在你使用一些第三方庫的控件食呻,而你想要做動畫的屬性卻沒有 setter / getter 方法的時候流炕,會需要用到它。
除了 ViewPropertyAnimator 和 ObjectAnimator仅胞,還有第三個選擇是 ValueAnimator每辟。ValueAnimator 并不常用,因為它的功能太基礎(chǔ)了干旧。ValueAnimator 是 ObjectAnimator 的父類渠欺,實際上,ValueAnimator 就是一個不能指定目標對象版本的 ObjectAnimator椎眯。ObjectAnimator 是自動調(diào)用目標對象的 setter 方法來更新目標屬性的值挠将,以及很多的時候還會以此來改變目標對象的 UI,而 ValueAnimator 只是通過漸變的方式來改變一個獨立的數(shù)據(jù)编整,這個數(shù)據(jù)不是屬于某個對象的舔稀,至于在數(shù)據(jù)更新后要做什么事,全都由你來定掌测,你可以依然是去調(diào)用某個對象的 setter 方法(別這么為難自己)内贮,也可以做其他的事,不管要做什么汞斧,都是要你自己來寫的夜郁,ValueAnimator 不會幫你做。功能最少粘勒、最不方便舱痘,但有時也是束縛最少、最靈活偿凭。比如有的時候,你要給一個第三方控件做動畫剑勾,你需要更新的那個屬性沒有 setter 方法,只能直接修改赵颅,這樣的話 ObjectAnimator 就不靈了啊虽另。怎么辦?這個時候你就可以用 ValueAnimator饺谬,在它的 onUpdate() 里面更新這個屬性的值捂刺,并且手動調(diào)用 invalidate()。

示范代碼募寨,只有當要修改的屬性沒有被定義的時候才會用到ValueAnimator來修改族展,否則直接用ObjectAnimator就行
ValueAnimator valueAnimator=new ValueAnimator();
        valueAnimator.setFloatValues(10,100,50,300);
        valueAnimator.setDuration(3000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                textView.setTextSize((float)animation.getAnimatedValue());
            }
        });
        valueAnimator.start();

最終總結(jié)

ViewPropertyAnimator、ObjectAnimator拔鹰、ValueAnimator 這三種 Animator仪缸,它們其實是一種遞進的關(guān)系:從左到右依次變得更加難用,也更加靈活列肢。但我要說明一下恰画,它們的性能是一樣的,因為 ViewPropertyAnimator 和 ObjectAnimator 的內(nèi)部實現(xiàn)其實都是 ValueAnimator瓷马,ObjectAnimator 更是本來就是 ValueAnimator 的子類拴还,它們?nèi)齻€的性能并沒有差別。它們的差別只是使用的便捷性以及功能的靈活性欧聘。所以在實際使用時候的選擇片林,只要遵循一個原則就行:盡量用簡單的。能用 View.animate() 實現(xiàn)就不用 ObjectAnimator怀骤,能用 ObjectAnimator 就不用 ValueAnimator拇厢。

小提示:在android的view包下有個類ViewAnimationUtils,這個工具類很好用晒喷,示例代碼如下:
Animator anim = ViewAnimationUtils.createCircularReveal(imageView, imageView.getWidth()/2, imageView.getHeight()/2, 0, imageView.getWidth()/2>imageView.getHeight()/2?imageView.getHeight()/2:imageView.getWidth()/2);
anim.setDuration(2000);
anim.start();

參考文章
http://hencoder.com/ui-1-7/

-------------------------------------------------------------------

過渡動畫

activity之間的過渡動畫

(科普:5.0以前孝偎,activity之間的跳轉(zhuǎn)動畫可以在startActivity方法后加上overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);即可)

第一步,在style.xml文件中給主題配置<item name="android:windowContentTransitions">true</item>

第二步凉敲,在源activity中設(shè)置activity退出過渡效果衣盾,如下三種

getWindow().setExitTransition(new Explode().setDuration(2000));//分解動畫效果
getWindow().setExitTransition(new Fade().setDuration(2000));//淡入淡出動畫效果
getWindow().setExitTransition(new Slide().setDuration(2000));//滑動動畫效果

第三步,給跳轉(zhuǎn)的intent設(shè)置Bundle參數(shù)爷抓,如下三種

startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());//配合第二步中的代碼使用
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this,button,"anniu").toBundle());//一個共享元素動畫效果势决,不用配合第二步中的代碼使用,記得在布局文件中給參與共享元素的view設(shè)置transitionName屬性蓝撇,源activity和目的activity中都要設(shè)置果复,并且名字要一樣
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, Pair.create((View)textView,"text"),Pair.create((View)button,"anniu")).toBundle());//多個共享元素動畫效果,不用配合第二步中的代碼使用

第四步渤昌,在目的activity中設(shè)置進入的activity過渡動畫

getWindow().setEnterTransition(new Explode().setDuration(2000));//分解動畫效果
getWindow().setEnterTransition(new Fade().setDuration(2000));//淡入淡出動畫效果
getWindow().setEnterTransition(new Slide().setDuration(2000));//滑動動畫效果

參考文章

https://blog.csdn.net/u012702547/article/details/51289789

activity中布局元素的過渡動畫

第一種虽抄,給整個layout添加過渡動畫用scene和go走搁,go方法是用來過渡整個布局文件的,不是過渡某個view的屬性的迈窟,步驟如下:

第一步:Scene場景的兩種定義方式

Scene scene = Scene.getSceneForLayout(linearLayout, R.layout.guodu, MainActivity.this);//Scene的第一種定義方式
Scene scene=newScene(linearLayout,getLayoutInflater().inflate(R.layout.guodu,null));//Scene的第二種定義方式

第二步:添加過渡動畫
給整個布局添加過渡動畫:

TransitionManager.go(scene,new Fade());

第二種私植,給布局中的某個view添加過渡動畫用beginDelayedTransition,代碼如下:

@Override
public void onClick(View v) {
/*TransitionManager.beginDelayedTransition(linearLayout,new Slide(Gravity.RIGHT));//視圖的顯示情況用Slide车酣,或Fade曲稼,或Explode
imageView.setVisibility(View.INVISIBLE);//這里只有改變了原來視圖的顯示狀態(tài)才能觸發(fā)動畫效果了,不然是觸發(fā)不了的*/
/*TransitionManager.beginDelayedTransition(linearLayout,new ChangeImageTransform());//圖片縮放比例發(fā)生變化用ChangeImageTransform          
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);//解釋同上*/
/* TransitionManager.beginDelayedTransition(linearLayout,new ChangeBounds());//視圖的位置發(fā)生變化用ChangeBounds
imageView.layout(30,20,200,10);//解釋同上*/
}
xml文件中ImageView的屬性如下:
        <ImageView
            android:id="@+id/image"
            android:layout_width="200sp"
            android:layout_height="200sp"
            android:src="@mipmap/touxiang"/>

系統(tǒng)中Transition的實現(xiàn)類如下

參考文章如下
http://www.reibang.com/p/b72718bade45
https://blog.csdn.net/wuyuxing24/article/details/78857912
https://github.com/lgvalle/Material-Animations(這個網(wǎng)址中就將activity跳轉(zhuǎn)的過渡動畫講的很詳細)
https://github.com/andkulikov/Transitions-Everywhere(這個網(wǎng)址是將布局中視圖的過渡動畫進行了更多的擴展湖员,比系統(tǒng)提供的Transition的實現(xiàn)類要多贫悄,http://www.reibang.com/p/98f2ec280945這個網(wǎng)址就對這個庫進行了詳細講解)

-----------------------------------------------------------------------

android開發(fā)藝術(shù)中對動畫的介紹

1:LayoutAnimation,LayoutAnimation作用于ViewGroup娘摔,為ViewGroup指定一個動畫窄坦,這樣當它的子元素出場時就會具有這種動畫效果。

定義LayoutAnimation晰筛,如下所示:



其中屬性的具體含義如下所示:
delay:表示子元素開始動畫的時間延遲;
animationOrder:表示子元素動畫的順序拴袭,有三種選項:normal读第,reverse,random拥刻,其中normal表示順序顯示怜瞒,reverse表示逆向顯示,random表示隨機播放入場動畫般哼;
animation:為子元素指定具體的入場動畫吴汪;
另外記得給ViewGroup指定android:layoutAnimation屬性。
除了在xml中指定LayoutAnimation外蒸眠,還可以通過LayoutAnimationController來實現(xiàn)漾橙,具體代碼如下所示:


2:Activity的切換效果:


3:android中的屬性動畫:

屬性動畫除了代碼實現(xiàn)以外(具體看上方的代碼實現(xiàn)),還可以通過xml來定義楞卡,屬性動畫需要定義在res/animator目錄下(視圖動畫是定義在res/anim目錄下)霜运,它的語法如下所示:



其中<set>標簽對應(yīng)AnimatorSet,<animator>標簽對應(yīng)ValueAnimator蒋腮,而<objectAnimator>則對應(yīng)ObjectAnimator淘捡。<set>標簽的android:ordering屬性有兩個可選值:together和sequentially,默認值是together池摧。
對于<objectAnimator>標簽的屬性的說明:
valueType:表示propertyName所指定的屬性的類型焦除,有intType和floatType兩個可選項,另外作彤,如果propertyName所指定的屬性表示的是顏色膘魄,那么不需要指定android:valueType乌逐,系統(tǒng)會自動對顏色類型的屬性做處理。
對于一個動畫來說瓣距,repeatCount黔帕,它表示動畫循環(huán)的次數(shù),默認值為0蹈丸,其中-1表示無限循環(huán)成黄;



如果不滿足以上兩個條件,但是想給屬性做動畫的話逻杖,可以使用以下3種解決方式:



使用動畫的注意事項:1--View動畫是對View的影像做動畫奋岁,并不是真正地改變View的狀態(tài),因此有時候會出現(xiàn)動畫完成后View無法隱藏的現(xiàn)象荸百,即setVisibility(View.GONE)失效了闻伶,這個時候只要調(diào)用view.clearAnimation()清除View動畫即可解決此問題;2--在進行動畫的過程中够话,要盡量使用dp蓝翰,使用px會導(dǎo)致在不同的設(shè)備上有不同的效果;3--使用動畫的過程中女嘲,建議開啟硬件加速畜份,提高動畫流暢度;4--在屬性動畫中有一類無限循環(huán)的動畫欣尼,這類動畫需要在Activity退出時及時停止爆雹,否則將導(dǎo)致Activity無法釋放從而造成內(nèi)存泄漏,通過驗證后發(fā)現(xiàn)視圖動畫并不存在此問題愕鼓。

--------------------------------------------------------------------------------------------------------------------

android群英傳中對動畫的介紹钙态,上面沒有提到的知識點。

1:布局動畫

所謂布局動畫是指作用在ViewGroup上菇晃,給ViewGroup增加View時添加一個動畫過渡效果册倒。最簡單的布局動畫是在ViewGroup的XML中,使用android:animateLayoutChanges="true"來打開布局動畫磺送。示例代碼如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layoutAnimation="@anim/viewgroup"
    android:animateLayoutChanges="true"
    android:id="@+id/lin">

    <Button
        android:text="增加"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button"/>
</LinearLayout>
...
        button=findViewById(R.id.button);
        linearLayout=findViewById(R.id.lin);
        ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1);
        scaleAnimation.setDuration(2000);
        LayoutAnimationController layoutAnimationController=new LayoutAnimationController(scaleAnimation,0.5f);
        layoutAnimationController.setOrder(LayoutAnimationController.ORDER_NORMAL);//當LayoutAnimationController的構(gòu)造方法的第二個參數(shù)不為0時剩失,就可以在這里設(shè)置子View顯示的順序,ORDER_NORMAL(順序)册着,ORDER_RANDOM(隨機)拴孤,ORDER_REVERSE(反序)。
        linearLayout.setLayoutAnimation(layoutAnimationController);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TextView textView=new TextView(CeShi.this);
                textView.setText("你好");
                textView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                linearLayout.addView(textView);
            }
        });
...

2:自定義動畫

創(chuàng)建自定義動畫甲捏,只需要繼承自Animation演熟,實現(xiàn)它的applyTransformation的邏輯就可以了,不過通常情況下,還需要覆蓋父類的initalize方法來實現(xiàn)一些初始化工作芒粹。

        MyAnimation myAnimation=new MyAnimation();
        myAnimation.setDuration(2000);
        button.startAnimation(myAnimation);
public class MyAnimation extends Animation {
    private Matrix matrix;
    private int width;
    private int height;

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        this.width = width;
        this.height = height;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        matrix = t.getMatrix();
        matrix.preScale(1, 1-interpolatedTime, width / 2, height / 2);//interpolatedTime的取值范圍為0到1.0
        matrix.postRotate(45);
    }
}

編寫自定義動畫時遇到的問題:

1:始終不執(zhí)行自定義動畫中的applyTransformation方法兄纺,原因:父布局中已經(jīng)有動畫效果了,我的LinearLayout布局中有android:layoutAnimation="@anim/viewgroup"化漆,當把父布局的動畫效果移除后估脆,就正常了。
2:當動畫結(jié)束后座云,出現(xiàn)了OpenGLRenderer: Error: Spot pair overflow!!! used 40, total 21異常疙赠,解決方法是在父布局中加入android:layerType="software",參考文章:https://blog.csdn.net/tiramisu_ljh/article/details/70229347

3:SVG矢量動畫

SVG是可伸縮矢量圖形朦拖,圖像在放大或改變尺寸的情況下其圖形質(zhì)量不會有所損失圃阳,相比于Bitmap來說,Bitmap通過在每個像素點上存儲色彩信息來表達圖像璧帝,而SVG是一個繪圖標準捍岳,其最大的優(yōu)點就是放大不會失真,而且Bitmap需要為不同分辨率設(shè)計多套圖標睬隶,而矢量圖不需要锣夹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市苏潜,隨后出現(xiàn)的幾起案子银萍,更是在濱河造成了極大的恐慌,老刑警劉巖窖贤,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砖顷,死亡現(xiàn)場離奇詭異贰锁,居然都是意外死亡赃梧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門豌熄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來授嘀,“玉大人,你說我怎么就攤上這事锣险√阒澹” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵芯肤,是天一觀的道長巷折。 經(jīng)常有香客問我,道長崖咨,這世上最難降的妖魔是什么锻拘? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上署拟,老公的妹妹穿的比我還像新娘婉宰。我一直安慰自己,他們只是感情好推穷,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布心包。 她就那樣靜靜地躺著,像睡著了一般馒铃。 火紅的嫁衣襯著肌膚如雪蟹腾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天骗露,我揣著相機與錄音岭佳,去河邊找鬼。 笑死萧锉,一個胖子當著我的面吹牛珊随,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柿隙,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叶洞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了禀崖?” 一聲冷哼從身側(cè)響起衩辟,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎波附,沒想到半個月后艺晴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡掸屡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年封寞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仅财。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡狈究,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盏求,到底是詐尸還是另有隱情抖锥,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布碎罚,位于F島的核電站磅废,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荆烈。R本人自食惡果不足惜拯勉,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谜喊,春花似錦潭兽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诵次,卻和暖如春账蓉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逾一。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工铸本, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遵堵。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓箱玷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陌宿。 傳聞我的和親對象是個殘疾皇子锡足,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容