Android自定控件之動畫總結(一)

前言

  Android的動畫實現主要有三種,幀動畫、補間動畫、屬性動畫。幀動畫和補間動畫很早之前就有了,但是它們兩存在侷限性,很多功能都是實現不了,於是就有了屬性動畫,屬性動畫相比較於前兩者,能夠很方便地實現我們想要的動畫效果。

幀動畫

  幀動畫顧名思義就是將預先設置的一組圖片逐幀的播放出來,我們需要在drawable文件夾裏面自己添加xml資源文件,然後是由animation-list標籤以及他的的子標籤item。
  然後子啊activity文件裏面使用AnimationDrawable類,通過(animationDrawable = (AnimationDrawable)imageView.getbackground())得到animationDrawable對象,使用start()和stop()就可以對幀動畫進行控制了。

補間動畫

  補間動畫主要有一下四種操作,alpha、scale、translate、rotate,我們通過在res資源文件裏面創建anim文件夾,然後根據需要創建對應的xml動畫資源文件。每一個文件可以單獨對應一種動畫類型,同時也可以對應多個動畫類型。對應多個動畫類型需要用到set標籤,使用方式如下;

<?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">


    <scale
        android:pivotY="50%"
        android:pivotX="50%"
        android:fromXScale="0"
        android:fromYScale="0"
        android:toYScale="1"
        android:toXScale="1"
        android:duration="1000"/>

<!-- 會覆蓋前面的scale動畫-->

    <scale
        android:pivotY="50%"
        android:pivotX="50%"
        android:fromXScale="1"
        android:fromYScale="1"
        android:toYScale="0"
        android:toXScale="0"
        android:duration="1000"/>

    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="1000"/>
</set>

  在java代碼裏面主要用到Animation這個類,然後使用AnimationUtils.loadAnimation(this, R.anim.xxx)來創建Animation實例對象。最後通過控件的startAnimation方法開始動畫效果。
  以上對於補間動畫的敘述是關於如何靜態使用補間動畫的方法,相對應的還有動態使用補間動畫的方法,前者比較後者顯得更加方便,調用簡介,特別是在一個動畫效果需要調用多次的情況下,靜態創建更好。而動態創建自然也有它的好處,就是可以根據需求動態的創建我們需要的動畫,這樣的話就不會有太多的侷限。不管的使用哪一種方式,根據目前的需要選擇性的創建纔是明智的。
  對於動態創建這裏就不羅嗦,只需要知道alpha、scale、rotate、translate對應的類分別是AlphaAnimation、Scale Animation、Rotate Animation、TranslateAnimation。

屬性動畫

  屬性動畫是現在用的比較多的。同樣的屬性動畫也有靜態創建和動態創建兩種方法。

  • 動態使用屬性動畫

  這裏需要了解到ValueAnimator、ObjectAnimator、PropertyValuesHolder、AnimatorSet、這四個類,以及他們之間的用法。

  • ValueAnimator

    public void Onstart(View view){
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 400);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int curint = (int)valueAnimator.getAnimatedValue();

                tv1.layout(curint, curint, curint + tv1.getWidth(), curint + tv1.getHeight());
                //根據上面OfFloat方法裏面參數相應的設置tv1.setText() tv1.setBackground()、、、、
            }
        });

        valueAnimator.setDuration(2000);
        
        valueAnimator.start();
    }

ValueAnimator用的比較少

  • ObjectAnimator

    public void OnStart(View View){
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv1, "translationY", 0f, 400f);
        
        objectAnimator.setDuration(2000);
        
        objectAnimator.setInterpolator(new BounceInterpolator());
        
        objectAnimator.start();
    }

ObjectAnimator也可以設置監聽,它有兩種監聽,一種和ValueAnimator一樣,一種是Animator.AnimatorListener接口。兩者監聽的功能不一樣,同時後者也可以用AnimatorListenerAdapter代替。

  • PropertyValuesHolder

 //創建PropertyValuesHolder實例
        PropertyValuesHolder valuesHolder1 = PropertyValuesHolder.ofInt("backgroundColor", 0xffff00ff, 0xffffff00, 0xff0000ff);
        valuesHolder1.setEvaluator(new ArgbEvaluator());
        PropertyValuesHolder valuesHolder2 = PropertyValuesHolder.ofFloat("scaleX", 0f, 2f, 0f, 3f, 1f);
        PropertyValuesHolder valuesHolder3 = PropertyValuesHolder.ofFloat("scaleY", 0f, 2f, 0f, 3f, 1f);
        //將創建PropertyValuesHolder實例添加到ObjectAnimator中
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mTextView1, valuesHolder1, valuesHolder2, valuesHolder3);
        objectAnimator.setDuration(2000);
        objectAnimator.start();

PropertyValuesHolder的意義就是保存動畫過程中所需要的屬性和值,其實ofInt()和ofFloat()的內部實現就是通過封裝PropertyValuesHolder實例來保存動畫狀態的,後面的操作也是以PropertyValuesHolder爲主。

  • AnimatorSet

    public void OnStart(View view){
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(tv1, "translationY", 0f, 400f);

        ObjectAnimator objectAnimator3 = ObjectAnimator.ofInt(tv2, "BackgroundColor",0xffffff, 0x000000);

        objectAnimator1.setDuration(1000000);

        AnimatorSet animatorSet = new AnimatorSet();
        
        animatorSet.setDuration(2000);//會覆蓋objectAnimator1的設置。

        //按順序播放
//        animatorSet.playSequentially(objectAnimator1, objectAnimator2, objectAnimator3);
        //同時播放
//        animatorSet.playTogether(objectAnimator1, objectAnimator2, objectAnimator3);
        //既有同時播放又有順序播放
        AnimatorSet.Builder builder = animatorSet.play(objectAnimator1);
        builder.with(objectAnimator2).after(objectAnimator3);
        //也可以寫成這樣
        animatorSet.play(objectAnimator1).with(objectAnimator2).after(objectAnimator3);
    }

靜態創建

  我們只要記住這個,就能很好的理解了。

<animator />:對應ValueAnimator
<objectAnimator />:對應ObjectAnimator
<set />:對應AnimatorSet

  以其中的的objectAnimator爲例說明一下。先在res文件夾裏面創建見animator文件夾,然後創建相應的資源文件。如下所示:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/bounce_interpolator"
    android:propertyName="BackgroundColor"
    android:duration="2000"
    android:valueFrom="#000000"
    android:valueTo="#999999"
    android:valueType="colorType" />

  然後再java代碼這樣實現

public void onStart(View view ){
        objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);

        objectAnimator.setTarget(tv1);

        objectAnimator.start();

    }

最後

  由於Android動畫有太多的內容,這裏只是大概的講了一下里面的東西,想要深入必須瞭解其實現的細節。特別時屬性動畫,需要熟悉各種插值器、Evaluate等等,還有屬性動畫的實現的過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章