看完這篇再不會 View 的動畫框架,我跪搓衣板


引言

眾所周知,一款沒有動畫的 app,就像沒有靈魂的肉體,給用戶的體驗性很差。現在的 android 在動畫效果方面早已空前的發展,1.View 動畫框架 2.屬性動畫框架 3.Drawable 動畫。相比后后兩者,View 動畫框架在 Android 的最開始就已經出現,即有着非常容易學習的有點,卻也有着用法太死的毛病,但對於初學者而言,豬狗實現各種可選的效果了。

“Android animator”的圖片搜索結果


組成

對於 View 的動畫框架而言,最常見的有:

  • AlphaAnimation(透明度動畫)、
  • RotateAnimation(旋轉動畫)、
  • ScaleAnimation(縮放動畫)、
  • TranslateAnimation(平移動畫)四種類型。

除此之外還提供了動畫集合類(AnimationSet),用於將各種基本動畫組合起來進行顯示。


使用

對於現在市面上的書籍 📚,基本都是在活動代碼中,一步一步設置透明度,運行時間。來對控件添加動畫框架。所以我這里還是只講 Java 代碼添加那就太無聊了。所以這里我向大家介紹的使用方法,除了基本的以代碼形式添加之外,更有 xml 文件的格式書寫,並在活動中直接引用🚰的騷操作。

如果大家對其他動畫方式,比如 Drawable 動畫啊,屬性動畫啊感興趣,歡迎查看我以后的博文。

既然是要在 xml 中配置,那我獻給大家介紹下,xml 中各種屬性的意義:在 /res 下建立 名為 “anim” 的 Directory,將以后的 xml 配置文件都放在該目錄下。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true">
    <!--透明度更變動畫-->
    <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>

image.gif

下面,我就開始帶領大家,以 ImageView TextView 為例,展示下使用方法,開始發干貨咯:

在開始前

重點:嘮叨一下

這里給出布局文件以后都是這樣的,就不再給出了

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".AlphaAnimationActivity">

    <!--不建議用 Relativelayout 浪費內存 哈哈哈-->
    <ImageView
        android:id="@+id/image"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:src="@drawable/girl"
        android:scaleType="fitXY"
        android:alpha="1.0"/>

    <!--這里的 alpha 設置的是最大透明度-->
    <TextView
        android:id="@+id/text"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:gravity="center"
        android:text="@string/text"
        android:background="@color/papayawhip"
        android:alpha="0.75"/>

</LinearLayout>

image.gif

** 在布局文件中,對控件設置 alpha 值,表示最大的透明度**


透明度動畫 -> Alpha

在 xml 文件中設置 alpha 動畫,主要分為三個屬性

  1. fromAlpha 表示開始時的透明度
  2. toAlpha     表示結束時的透明度
  3. duration    表示變化經歷過程所占時間

在 /res/anim 下建立 alpha_anim.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="1000"/>
</set>

image.gif

然后直接在活動中實例化 Animate 對象,引用即可

        Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
        animation.setFillAfter(false);// 變化之后是永久更改還是恢復原樣

        ImageView imageView = findViewById(R.id.image);
        imageView.startAnimation(animation);

        TextView textView   = findViewById(R.id.text);
        textView.startAnimation(animation);

image.gif

注意這個 setFillAfter 是用於設定:控件變化之后是永久更改,還是運行完了就恢復原樣

運行一下,看效果:

image


縮放動畫 -> Scale

在屬性文件(xml)中,scale 的標簽主要有一下這幾個

  • duration       運行時間
  • fromXScale 橫軸方向開始變化時的大小
  • toXScale     橫軸方向變化結束時的大小
  • fromYScale 縱軸方向開始變化時的大小
  • toYScale     縱軸方向變化結束時的大小
  • pivotX         按比例確定縮小/放大中心點的橫坐標
  • pivotY         按比例確定縮小/放大中心點的縱坐標
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="2000"
        android:fromXScale="1.0"
        android:toXScale="0.0"
        android:fromYScale="1.0"
        android:toYScale="0.0"
        android:pivotX="50%"
        android:pivotY="50%"/>
</set>

image.gif

如果你願意,可以在布局文件中設置,默認開始是的縮放比例:

見名知意:

  • scaleX 橫向默認縮放比
  • scaleY 縱向默認縮放比
    <ImageView
        android:id="@+id/scale_image"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:src="@drawable/girl"
        android:scaleType="fitXY"
        android:scaleY="0.75"
        android:scaleX="1.15"/>

image.gif

**能達到如下的效果 **

image

同樣的在活動中引用該屬性文件:

和前面無異,改個文件即可

。。。
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
        animation.setFillAfter(false);// 變化之后是永久更改還是恢復原樣

        ImageView imageView = findViewById(R.id.scale_image);
        imageView.startAnimation(animation);
。。。

image.gif

運行一下看看效果:

image


平移動畫 -> Translate

平移動畫相對其他簡單的屬性動畫來說,更為簡單,主要有五個屬性:

  1. duration       運行時間
  2. fromXDelta  在 X 軸的開始位置
  3. toXDelta      在 X 軸的結束位置
  4. fromYDelta  在 Y 軸的開始位置
  5. toYDelta      在 Y 軸的結束位置

注意,這里有個點比較特殊:

在確定位置屬性的時候,有三種類型的賦值方法:

  1. 整型值:如:android:fromXDelta="20" 表示自己與左邊界的距離
  2. 百分比:如:android:fromXDelta="20%" 表示自己與左邊界的距離 和 自己高度的百分比
  3. 百分比+p:如:android:fromXDelta="20%p" 表示自己與父控件(一般為 ViewGroup )左邊界的距離

篇幅問題,這里我只介紹整型值的使用方法

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="2000"
        android:fromXDelta="20"
        android:toXDelta="100"
        android:fromYDelta="20"
        android:toYDelta="100"/>
</set>

image.gif

同樣的也可以在布局文件中加以引用,這頂初始值:

    <ImageView
        android:id="@+id/scale_image"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:src="@drawable/girl"
        android:scaleType="fitXY"
        android:translationX="50sp"
        android:translationY="20sp"/>

image.gif

可以看到,設定了初始位移的 ImageView 相對與未設定的 TextView 發生了偏移

image

同樣的,在活動中加以引用:

...
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
        animation.setFillAfter(false);// 變化之后是永久更改還是恢復原樣

        ImageView imageView = findViewById(R.id.scale_image);
        imageView.startAnimation(animation);
...

image.gif

運行一下看看效果:

image


旋轉動畫 -> Rotate

對於旋轉動畫而言,一切就顯得有趣了起來,我碼字的雙手就顯得疲憊了起來

首先還是設定屬性,對於旋轉動畫,基本的屬性有:

  1. duration         動畫時間
  2. fromDegrees 動畫開始角度
  3. toDegrees     動畫結束偏轉角度
  4. pivotX            旋轉軸心點 X 位置
  5. pivotY            旋轉軸心點 Y 位置

同樣的 旋轉動畫的屬性也有三種設置方法,但這主要是對於 pivot 而言,用於確定軸心點位置

  1. 整型值:如:android:pivotX="20" 表示自己與左邊界的距離
  2. 百分比:如:android:pivotX="20%" 表示自己與左邊界的距離 和 自己高度的百分比
  3. 百分比+p:如:android:pivotX="20%p" 表示自己與父控件(一般為 ViewGroup )左邊界的距離
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:toDegrees="+360"
        android:pivotX="50%"
        android:pivotY="50%"/>
</set>

image.gif

老樣子,添加布局

    <ImageView
        android:id="@+id/scale_image"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:src="@drawable/girl"
        android:scaleType="fitXY"/>

image.gif

在活動中添加代碼

...
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
        animation.setFillAfter(false);// 變化之后是永久更改還是恢復原樣

        ImageView imageView = findViewById(R.id.scale_image);
        imageView.startAnimation(animation);
...

image.gif

同樣的在運行一下

image

這時你可能會揪着我稀疏的秀發問我,這有趣在哪里??!

好的請看!

image

360度無腦大旋轉,好了牛逼吹完了,不告述你咋調的,我先跑了

開個玩笑啦,其實很簡單,在布局文件中,設置下傾斜角就行了

  1. rotationX 橫向傾斜角
  2. rotationY 縱向傾斜角
    <ImageView
        android:id="@+id/scale_image"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:src="@drawable/girl"
        android:scaleType="fitXY"
        android:rotationX="50"
        android:rotationY="20"/>

image.gif


時間插值器

好了,到此為止基本動畫就結束了,現在咱來點猛的:對就是:時間插值器

什么是時間插值器?我剛學時其實也很懵逼,現在發覺還是給大家看例子方便

使用

首先教大家下使用方法,完了在以咋們透明度動畫為例做纖細的介紹

首先看,這時我們原來透明度的代碼:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="1000"/>
</set>

image.gif

運行效果,我們可以看到這是個比較均勻的變化過程

image

我們簡單的添加一行:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_interpolator">
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="5000"/>
</set>

image.gif

再來 這次時間加到10s,方便看效果;

image

可以看到,變化的數獨越來越快,這就是時間插值器:

常見的時間插值器有:

  • android:interpolator="@android:anim/accelerate_interpolator" 設置動畫為加速動畫(動畫播放中越來越快)

就是這例子,這里不在說了

  • android:interpolator="@android:anim/decelerate_interpolator" 設置動畫為減速動畫(動畫播放中越來越慢)

image

  • android:interpolator="@android:anim/accelerate_decelerate_interpolator" 設置動畫為先加速在減速(開始速度最快 逐漸減慢)

image

  • android:interpolator="@android:anim/anticipate_interpolator" 先反向執行一段,然后再加速反向回來(相當於我們彈簧,先反向壓縮一小段,然后在加速彈出)

image

  • android:interpolator="@android:anim/anticipate_overshoot_interpolator" 同上先反向一段,然后加速反向回來,執行完畢自帶回彈效果(更形象的彈簧效果)

image

  • android:interpolator="@android:anim/bounce_interpolator" 執行完畢之后會回彈跳躍幾段(相當於我們高空掉下一顆皮球,到地面是會跳動幾下)

image

  • android:interpolator="@android:anim/cycle_interpolator" 循環,動畫循環一定次數,值的改變為一正弦函數:Math.sin(2* mCycles* Math.PI* input)

image

  • android:interpolator="@android:anim/linear_interpolator" 線性均勻改變

image

  • android:interpolator="@android:anim/overshoot_interpolator" 加速執行,結束之后回彈

image


補間動畫 -> Tween animation

摳完了上面每個的細節,我們玩波大的,首先我們先定義一個動畫集合:

首先們還是,定義一個屬性文件,但這里我們集合了 縮放 透明度 兩種效果:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/bounce_interpolator" >

    <scale
        android:duration="500"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0" />

    <alpha
        android:duration="500"
        android:fromAlpha="0"
        android:toAlpha="1.0" />

</set>

image.gif

然后我們在代碼中,對 RecyclerView 設置它,對於 RecyclerView Adapter 的寫法這里略去了,設置的詳細方法如下:

    private List<String> list;

    private void iniList(){
        list = new ArrayList<>();
        for (int i = 0 ; i < 30 ; i ++){
            list.add(i + " -- tween 測試 --");
        }
    }

    private void iniRecyclerView(){
        recyclerView = findViewById(R.id.recycler);
        GridLayoutManager manager = new GridLayoutManager(this,1);
        recyclerView.setLayoutManager(manager);

        LayoutAnimationController lac=new LayoutAnimationController(AnimationUtils
                .loadAnimation(this, R.anim.in_anim));
        lac.setDelay(0.5f);
        lac.setOrder(LayoutAnimationController.ORDER_RANDOM);
        recyclerView.setLayoutAnimation(lac);

        TweenRecyclerAdapter adapter = new TweenRecyclerAdapter(list);
        recyclerView.setAdapter(adapter);
    }

image.gif

讓我們運行下看看酷炫的效果:

image


如果文中有誤,歡迎在評論區指出

怎么樣,我不用貴搓衣板了吧,哈哈哈,點個贊唄么么噠~

本文以同步發布到我的 CSDN 博客,歡迎大家來捧場:
點擊跳轉 https://blog.csdn.net/qq_43377749/article/details/91890323


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM