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

組成
對于 View 的動畫框架而言,最常見的有:
- AlphaAnimation(透明度動畫)、
- RotateAnimation(旋轉(zhuǎn)動畫)、
- ScaleAnimation(縮放動畫)、
- TranslateAnimation(平移動畫)四種類型。
除此之外還提供了動畫集合類(AnimationSet),用于將各種基本動畫組合起來進(jìn)行顯示。
使用
對于現(xiàn)在市面上的書籍 ??,基本都是在活動代碼中,一步一步設(shè)置透明度,運(yùn)行時間。來對控件添加動畫框架。所以我這里還是只講 Java 代碼添加那就太無聊了。所以這里我向大家介紹的使用方法,除了基本的以代碼形式添加之外,更有 xml 文件的格式書寫,并在活動中直接引用??的騷操作。
如果大家對其他動畫方式,比如 Drawable 動畫啊,屬性動畫啊感興趣,歡迎查看我以后的博文。
既然是要在 xml 中配置,那我獻(xiàn)給大家介紹下,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" />
<!--旋轉(zhuǎn)動畫-->
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<!--...-->
</set>

下面,我就開始帶領(lǐng)大家,以 ImageView TextView 為例,展示下使用方法,開始發(fā)干貨咯:
在開始前
重點:嘮叨一下
這里給出布局文件以后都是這樣的,就不再給出了
<?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 浪費(fèi)內(nèi)存 哈哈哈-->
<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 設(shè)置的是最大透明度-->
<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>

** 在布局文件中,對控件設(shè)置 alpha 值,表示最大的透明度**
透明度動畫 -> Alpha
在 xml 文件中設(shè)置 alpha 動畫,主要分為三個屬性
- fromAlpha 表示開始時的透明度
- toAlpha 表示結(jié)束時的透明度
- duration 表示變化經(jīng)歷過程所占時間
在 /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>

然后直接在活動中實例化 Animate 對象,引用即可
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
animation.setFillAfter(false);// 變化之后是永久更改還是恢復(fù)原樣
ImageView imageView = findViewById(R.id.image);
imageView.startAnimation(animation);
TextView textView = findViewById(R.id.text);
textView.startAnimation(animation);

注意這個 setFillAfter 是用于設(shè)定:控件變化之后是永久更改,還是運(yùn)行完了就恢復(fù)原樣
運(yùn)行一下,看效果:

縮放動畫 -> Scale
在屬性文件(xml)中,scale 的標(biāo)簽主要有一下這幾個
- duration 運(yùn)行時間
- fromXScale 橫軸方向開始變化時的大小
- toXScale 橫軸方向變化結(jié)束時的大小
- fromYScale 縱軸方向開始變化時的大小
- toYScale 縱軸方向變化結(jié)束時的大小
- pivotX 按比例確定縮小/放大中心點的橫坐標(biāo)
- pivotY 按比例確定縮小/放大中心點的縱坐標(biāo)
<?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>

如果你愿意,可以在布局文件中設(shè)置,默認(rèn)開始是的縮放比例:
見名知意:
- scaleX 橫向默認(rèn)縮放比
- scaleY 縱向默認(rèn)縮放比
<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"/>

**能達(dá)到如下的效果 **
同樣的在活動中引用該屬性文件:
和前面無異,改個文件即可
。。。
Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
animation.setFillAfter(false);// 變化之后是永久更改還是恢復(fù)原樣
ImageView imageView = findViewById(R.id.scale_image);
imageView.startAnimation(animation);
。。。

運(yùn)行一下看看效果:

平移動畫 -> Translate
平移動畫相對其他簡單的屬性動畫來說,更為簡單,主要有五個屬性:
- duration 運(yùn)行時間
- fromXDelta 在 X 軸的開始位置
- toXDelta 在 X 軸的結(jié)束位置
- fromYDelta 在 Y 軸的開始位置
- toYDelta 在 Y 軸的結(jié)束位置
注意,這里有個點比較特殊:
在確定位置屬性的時候,有三種類型的賦值方法:
- 整型值:如:android:fromXDelta="20" 表示自己與左邊界的距離
- 百分比:如:android:fromXDelta="20%" 表示自己與左邊界的距離 和 自己高度的百分比
- 百分比+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>

同樣的也可以在布局文件中加以引用,這頂初始值:
<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"/>

可以看到,設(shè)定了初始位移的 ImageView 相對與未設(shè)定的 TextView 發(fā)生了偏移
同樣的,在活動中加以引用:
...
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
animation.setFillAfter(false);// 變化之后是永久更改還是恢復(fù)原樣
ImageView imageView = findViewById(R.id.scale_image);
imageView.startAnimation(animation);
...

運(yùn)行一下看看效果:

旋轉(zhuǎn)動畫 -> Rotate
對于旋轉(zhuǎn)動畫而言,一切就顯得有趣了起來,我碼字的雙手就顯得疲憊了起來
首先還是設(shè)定屬性,對于旋轉(zhuǎn)動畫,基本的屬性有:
- duration 動畫時間
- fromDegrees 動畫開始角度
- toDegrees 動畫結(jié)束偏轉(zhuǎn)角度
- pivotX 旋轉(zhuǎn)軸心點 X 位置
- pivotY 旋轉(zhuǎn)軸心點 Y 位置
同樣的 旋轉(zhuǎn)動畫的屬性也有三種設(shè)置方法,但這主要是對于 pivot 而言,用于確定軸心點位置
- 整型值:如:android:pivotX="20" 表示自己與左邊界的距離
- 百分比:如:android:pivotX="20%" 表示自己與左邊界的距離 和 自己高度的百分比
- 百分比+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>

老樣子,添加布局
<ImageView
android:id="@+id/scale_image"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="@drawable/girl"
android:scaleType="fitXY"/>

在活動中添加代碼
...
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
animation.setFillAfter(false);// 變化之后是永久更改還是恢復(fù)原樣
ImageView imageView = findViewById(R.id.scale_image);
imageView.startAnimation(animation);
...

同樣的在運(yùn)行一下

這時你可能會揪著我稀疏的秀發(fā)問我,這有趣在哪里??!
好的請看!

360度無腦大旋轉(zhuǎn),好了牛逼吹完了,不告述你咋調(diào)的,我先跑了
開個玩笑啦,其實很簡單,在布局文件中,設(shè)置下傾斜角就行了
- rotationX 橫向傾斜角
- 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"/>

時間插值器
好了,到此為止基本動畫就結(jié)束了,現(xiàn)在咱來點猛的:對就是:時間插值器
什么是時間插值器?我剛學(xué)時其實也很懵逼,現(xiàn)在發(fā)覺還是給大家看例子方便
使用
首先教大家下使用方法,完了在以咋們透明度動畫為例做纖細(xì)的介紹
首先看,這時我們原來透明度的代碼:
<?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>

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

我們簡單的添加一行:
<?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>

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

可以看到,變化的數(shù)獨越來越快,這就是時間插值器:
常見的時間插值器有:
- android:interpolator="@android:anim/accelerate_interpolator" 設(shè)置動畫為加速動畫(動畫播放中越來越快)
就是這例子,這里不在說了
- android:interpolator="@android:anim/decelerate_interpolator" 設(shè)置動畫為減速動畫(動畫播放中越來越慢)

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

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

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

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

- android:interpolator="@android:anim/cycle_interpolator" 循環(huán),動畫循環(huán)一定次數(shù),值的改變?yōu)橐徽液瘮?shù):Math.sin(2* mCycles* Math.PI* input)

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

- android:interpolator="@android:anim/overshoot_interpolator" 加速執(zhí)行,結(jié)束之后回彈

補(bǔ)間動畫 -> Tween animation
摳完了上面每個的細(xì)節(jié),我們玩波大的,首先我們先定義一個動畫集合:
首先們還是,定義一個屬性文件,但這里我們集合了 縮放 透明度 兩種效果:
<?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>

然后我們在代碼中,對 RecyclerView 設(shè)置它,對于 RecyclerView Adapter 的寫法這里略去了,設(shè)置的詳細(xì)方法如下:
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);
}

讓我們運(yùn)行下看看酷炫的效果:

如果文中有誤,歡迎在評論區(qū)指出
怎么樣,我不用貴搓衣板了吧,哈哈哈,點個贊唄么么噠~
本文以同步發(fā)布到我的 CSDN 博客,歡迎大家來捧場:
點擊跳轉(zhuǎn) https://blog.csdn.net/qq_43377749/article/details/91890323