而 Android 5.0 (API level 21) 之後則可以對於以下動畫進行客製化:
Touch feedback
Button 的預設 Touch feedback 是使用 RippleDrawable
若想套用這個動畫效果可以把 xml 裡的 background 屬性設為
?android:attr/selectableItemBackground (View 本身範圍內的波紋)
或 API level 21 的新屬性 ?android:attr/selectableItemBackgroundBorderless (View 本身上面, parent 範圍內的波紋)
或是用 xml 以 ripple 標籤定義 RippleDrawable
ripple 的顏色可以用 android:colorControlHighlight 設定
Circular Reveal
Reveal 動畫可以在顯示或隱藏一組 UI 時為使用者提供視覺延續性
ViewAnimationUtils 只有一個 Public Methods
ViewAnimationUtils.createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)
它可以回傳一個圓形裁剪動畫的 Animator
來看一下範例
// invisible 的 view
View myView = findViewById(R.id.my_view);
// 取得 view 的中心位置做為 clipping circle 的圓心
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;
// 取 view 的長邊尺寸做為 clipping circle 的最終半徑大小
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
// 呼叫 createCircularReveal (startRadius 是 0)
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
// 將設為 visible 然後進行動畫
myView.setVisibility(View.VISIBLE);
anim.start();
如果是隱藏的話就要改成這樣
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
// 在 onAnimationEnd 時把 view 設為 invisible
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
myView.setVisibility(View.INVISIBLE);
}
});
anim.start();
Activity transitions
Activity 間的轉換
可以自訂 enter 跟 exit 以及 shared elements 的 transitions
Android 5.0 (API level 21) 支援的 enter 跟 exit transitions 有:
explode (中心放大/縮小)
slide (滑入/滑出)
fade (淡入/淡出)
只要是繼承自 Visibility 的 Transition 類別都可以做為 enter 跟 exit 的動畫
支援 shared elements 的 transitions 有:
changeBounds (邊界)
changeClipBounds (邊界裁剪)
changeTransform (scale 跟 rotation)
changeImageTransform (圖像的 size 跟 scale)
<style name="BaseAppTheme" parent="android:Theme.Material">
<!-- enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<!-- specify enter and exit transitions -->
<item name="android:windowEnterTransition">@transition/slide</item>
<item name="android:windowExitTransition">@transition/slide</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/shared_element_transition</item>
<item name="android:windowSharedElementExitTransition">
@transition/shared_element_transition</item>
</style>
transition 的 xml 範例如下
shared_element_transition.xml
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="together">
<changeBounds />
<changeTransform />
<changeImageTransform />
</transitionSet>
transition 如果不用 theme 指定的話
也可以用 code 來設定
但要記得 requestFeature
// inside your activity (if you did not enable transitions in your theme) getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); getWindow().setEnterTransition(new Explode()); Window.setSharedElementEnterTransition(); Window.setSharedElementExitTransition(); getWindow().setExitTransition(new Explode());另外 Window.setAllowEnterTransitionOverlap(true) 可以讓 enter transition 盡快進行
Activity 切換的範例 code 如下:
getWindow().setExitTransition(new Explode());
Intent intent = new Intent(this, MyOtherActivity.class);
startActivity(intent,
ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
有 sharedElement 的話請參考這裡:
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(view1, "agreedName1"),
Pair.create(view2, "agreedName2"));
// start the new activity
startActivity(intent, options.toBundle());
Curved motion
Android 5.0 (API level 21) 之後可自訂動畫的時間曲線及補間曲線
新的 PathInterpolator 類別是基於貝茲區線 (Bézier curve) 的 interpolator 或 Path 物件
曲線定義在 1x1 範圍的座標(0, 0)到(1, 1)
自訂 pathInterpolator 的 xml 範例如下:
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0.4"
android:controlY1="0"
android:controlX2="1"
android:controlY2="1"/>
</style>
material design specification 中
系統提供了三種基本曲線的 XML resources:
@interpolator/fast_out_linear_in.xml
@interpolator/fast_out_slow_in.xml
@interpolator/linear_out_slow_in.xml
設定 interpolator 的方法是將 PathInterpolator 物件傳入 Animator.setInterpolator 中
Animator.setInterpolator (TimeInterpolator value)
ObjectAnimator 也提供了一些新的 constructor 讓我們傳入 Path 物件, 例如:
ObjectAnimator mAnimator; mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); ... mAnimator.start();
View state changes
StateListAnimator 讓我們可以在 view 的 state change 間進行動畫
<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="@android:integer/config_shortAnimTime"
android:valueTo="2dp"
android:valueType="floatType"/>
<!-- you could have other objectAnimator elements
here for "x" and "y", or other properties -->
</set>
</item>
<item android:state_enabled="true"
android:state_pressed="false"
android:state_focused="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="100"
android:valueTo="0"
android:valueType="floatType"/>
</set>
</item>
</selector>用法為將這樣的 xml 透過 android:stateListAnimator 屬性指給 view在 code 裡則是透過 AnimationInflater.loadStateListAnimator (Context context, int id) 將 xml 的 StateListAnimator 載入進來
再用 View.setStateListAnimator(StateListAnimator stateListAnimator) 設定
由於 material theme 的 button 都有 Z 屬性
android:stateListAnimator 如果傳入 @null 則 Z 屬性不會有效
AnimatedStateListDrawable 類別則是 state 間的 drawable 動畫
有些 Android 5.0 的 widget 也是利用這樣的動畫方式
範例如下:
<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- provide a different drawable for each state-->
<item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
android:state_pressed="true"/>
<item android:id="@+id/focused" android:drawable="@drawable/drawableF"
android:state_focused="true"/>
<item android:id="@id/default"
android:drawable="@drawable/drawableD"/>
<!-- specify a transition -->
<transition android:fromId="@+id/default" android:toId="@+id/pressed">
<animation-list>
<item android:duration="15" android:drawable="@drawable/dt1"/>
<item android:duration="15" android:drawable="@drawable/dt2"/>
...
</animation-list>
</transition>
...
</animated-selector>這篇好長阿~~~
最後來看一下 AnimatedVectorDrawable
在 xml 檔案中定義 animated vector 有三個要素
1. res/drawable/ 中以 vector 標籤為 root 的 xml 檔
注意它是由裡面的 group 跟 path 標籤組成
而 group 跟 path 標籤都要指定 android:name 屬性才可以
<!-- res/drawable/vectordrawable.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600">
<group
android:name="rotationGroup"
android:pivotX="300.0"
android:pivotY="300.0"
android:rotation="45.0" >
<path
android:name="v"
android:fillColor="#000000"
android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
</group>
</vector>2. res/drawable/ 中以 animated-vector 標籤為 root 的 xml 檔
把 vector 的 xml 檔設定在 android:drawable 屬性
動畫則由 android:animation 屬性來設定
<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vectordrawable" >
<target
android:name="rotationGroup"
android:animation="@anim/rotation" />
<target
android:name="v"
android:animation="@anim/path_morph" />
</animated-vector>3. res/anim/ 中有一個或數個 objectAnimator 標籤的 xml 檔
用來定義動畫
<!-- res/anim/path_morph.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="3000"
android:propertyName="pathData"
android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
android:valueType="pathType" />
</set>相關資料:
Defining Custom Animations
沒有留言:
張貼留言