Android 5.0自定義動畫


材料設計中的動畫對用戶的操作給予了反饋,並且在與應用交互時提供了持續的可見性。材料主題提供了一些按鈕動畫和活動過渡,Android 5.0允許你自定義動畫並且可以創建新的動畫:

    Touch Feedback
    Circular Reveal
    Activity Transitions
    Curved Motion
    View State Changes

 

自定義觸摸反饋

 

在用戶與UI元素交互時,從接觸的角度來看,材料設計中的觸摸反饋提供了瞬間的視覺確認。按鈕的默認觸摸動畫使用了新的RippleDrawable類,使得按鈕采用漣漪效果在不同的狀態之間過渡。

在大多數情況下,你應該像下面那樣在xml中通過設置視圖背景來應用這個功能:

  • ?android:attr/selectableItemBackground用於有界漣漪效果。
  • ?android:attr/selectableItemBackgroundBorderless用於拓展到視圖外面的漣漪效果。這個效果將被繪制並局限於此視圖具有非空背景的最近的你控件中。

注意:selectableItemBackgroundBorderless是API 21中的新屬性。

另外,你也可以通過使用ripple元素的xml資源來定義RippleDrawable

你可能給RippleDrawable對象布置顏色。要想改變默認的觸摸反饋顏色,得使用該主題的android:colorControlHighlight屬性。

 

使用揭露效果

 

在你想要顯示或者隱藏一組UI元素時,揭露動畫向用戶提供了持續地可見性。ViewAnimationUtils.createCircularReveal()方法使你在揭露或隱藏視圖時產生一個裁剪圈似的動畫。

使用如下效果來揭露之前不可見的視圖:

 1 // previously invisible view
 2 View myView = findViewById(R.id.my_view);
 3 // get the center for the clipping circle
 4 int cx = (myView.getLeft() + myView.getRight()) / 2;
 5 int cy = (myView.getTop() + myView.getBottom()) / 2;
 6 // get the final radius for the clipping circle
 7 int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
 8 // create the animator for this view (the start radius is zero)
 9 Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
10 // make the view visible and start the animation
11 myView.setVisibility(View.VISIBLE);
12 anim.start();
View Code

使用如下效果來隱藏之前可見的視圖:

 1 // previously visible view
 2 final View myView = findViewById(R.id.my_view);
 3 // get the center for the clipping circle
 4 int cx = (myView.getLeft() + myView.getRight()) / 2;
 5 int cy = (myView.getTop() + myView.getBottom()) / 2;
 6 // get the initial radius for the clipping circle
 7 int initialRadius = myView.getWidth();
 8 // create the animation (the final radius is zero)
 9 Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
10 // make the view invisible when the animation is done
11 anim.addListener(new AnimatorListenerAdapter() {
12     @Override
13     public void onAnimationEnd(Animator animation) {
14         super.onAnimationEnd(animation);
15         myView.setVisibility(View.INVISIBLE);
16     }
17 });
18 // start the animation
19 anim.start();
View Code

 

自定義Activity過渡效果

 

符合材料設計的應用中的Activity過渡效果,在不同狀態之間,通過常用元素之間的動作和轉換,提供了視覺連接。你可以為Activity之間出入過渡和共享元素過渡效果指定自定義動畫。

進入過渡效果決定了activity中的視圖組是如何進入屏幕的。例如,在explode進入過渡效果中,視圖從外面進入屏幕,並飛入屏幕中心。

退出過渡效果決定了activity中的視圖組是如何退出屏幕的。例如,在explode退出過渡效果中,視圖是從中心位置退出屏幕的。

共享元素過渡效果決定了兩個activity之間共享的視圖在這些activity之間是如何過渡的。例如,如果兩個activity擁有不同的位置和尺寸的相同的圖片,共享元素的changeImageTransform過渡效果將在這些activity之間順滑地平移和縮放這些圖片。

Android 5.0(API 21)支持這些出入過渡效果:

  • explode—從屏幕中心位置移入移出視圖;
  • slide—從屏幕地邊緣位置移入移出視圖;
  • fade—通過改變視圖的透明度從屏幕中添加或刪除視圖;

任何繼承了Visibility類的過渡效果都可以作為出入過渡效果。

Android 5.0(API 21)支持這些共享元素過渡效果:

  • changeBounds—使目標視圖的布局邊緣變化生成動畫效果;
  • changeClipBounds—使目標視圖的剪裁邊緣變化生成動畫效果;
  • changeTransform—使目標視圖的縮放和旋轉變化生成動畫效果;
  • changeImageTransform—使目標視圖的尺寸和縮放變化生成動畫效果;

當你在應用中使用activity過渡效果時,在Activity的進入和退出之間默認的交錯退色效果被激活。

 

指定自定義過渡效果

 

首先,在你定義一個繼承自材料主題的風格時,通過android:windowContentTransitions屬性激活窗口內容過渡效果。你也可以在風格定義中指定出入和共享元素過渡效果:

 1 <style name="BaseAppTheme" parent="android:Theme.Material">
 2   <!-- enable window content transitions -->
 3   <item name="android:windowContentTransitions">true</item>
 4 
 5   <!-- specify enter and exit transitions -->
 6   <item name="android:windowEnterTransition">@transition/explode</item>
 7   <item name="android:windowExitTransition">@transition/explode</item>
 8 
 9   <!-- specify shared element transitions -->
10   <item name="android:windowSharedElementEnterTransition">
11     @transition/change_image_transform</item>
12   <item name="android:windowSharedElementExitTransition">
13     @transition/change_image_transform</item>
14 </style>
View Code

這個例子子中的change_image_transform過渡效果定義如下:

1 <!-- res/transition/change_image_transform.xml -->
2 <!-- (see also Shared Transitions below) -->
3 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
4   <changeImageTransform/>
5 </transitionSet>
View Code

changeImageTransform元素對應於ChangeImageTransform類。

要想激活代碼中的窗口內容過渡效果,得調用Window.requestFeature()方法:

1 // inside your activity (if you did not enable transitions in your theme)
2 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
3 // set an exit transition
4 getWindow().setExitTransition(new Explode());
View Code

要在代碼中指定過渡效果,調用這些方法使用Transition類:

  • Window.setEnterTransition();
  • Window.setExitTransition();
  • Window.setSharedElementEnterTransition();
  • Window.setSharedElementExitTransition();

方法setEnterTransition()setSharedElementExitTransition()給調用者Acivity定義了退出過渡效果,而方法setEnterTransition()setSharedElementEnterTransition()為被調用者定義了進入過渡效果。

為了獲取過渡的全部效果,你必須激活調用和被調用Activity的窗口內容過渡效果。否則的話,否則的話,調用者Activity將會啟動退出過渡效果,但是你會看到這個窗口過渡效果的(例如縮放或者褪色)。

為了盡可能早的啟動進入過渡效果,得在被調用Activity中使用Window.setAllowEnterTransitionOverlap()。這將使你擁有更多戲劇般美妙的進入過渡效果。

 

啟動使用過渡效果的Activity

 

如果你對Activity啟動並設置了退出過渡效果,過渡效果將如下所示一樣,在你啟動另外一個Activity時被激活:
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
如果你對第二個Activity設置了進入過渡效果,這個過渡效果將會在該Activity啟動時被激活。要想在啟動另外一個Activity時取消過渡效果,你需要提供null的候選Bundle

 

 

啟動擁有共享元素的Activity

 

為了在擁有共享元素的兩個Activity之間的過渡產生動畫效果:

    1,主題中支持窗口內容過渡效果。
    2,風格中指定共享元素過渡效果。
    3,在xml中定義過渡效果。
    4,在包含屬性的兩個布局文件中,給共享元素分配相同的名字。
    5,使用ActivityOptions.makeSceneTransitionAnimation() 方法。
 1 // get the element that receives the click event
 2 final View imgContainerView = findViewById(R.id.img_container);
 3 // get the common element for the transition in this activity
 4 final View androidRobotView = findViewById(R.id.image_small);
 5 // define a click listener
 6 imgContainerView.setOnClickListener(new View.OnClickListener() {
 7     @Override
 8     public void onClick(View view) {
 9         Intent intent = new Intent(this, Activity2.class);
10         // create the transition animation - the images in the layouts
11         // of both activities are defined with android:transitionName="robot"
12         ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, androidRobotView, "robot");
13         // start the new activity
14         startActivity(intent, options.toBundle());
15     }
16 });
View Code


對於代碼中生成的動態共享視圖而言,要在兩個Activity中使用View.setTransitionName()方法指定共同的元素名字。

為了結束掉第二個Activity時逆轉屏幕過渡效果動畫,要調用Activity.finishAfterTransition()方法而非Activity.finish()

 

 

啟動擁有多個共享元素的Activity

 

要使擁有多於一個共享元素的兩個Activity的屏幕過渡產生動畫效果,要在擁有android:transitionName屬性(或者在兩個Activity中使用View.setTransitionName()方法)的兩個布局文件中定義共享元素,並且要按照如下所示創建ActivityOptions對象:

 1 ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2")); 

 

 

使用弧形運動

 

材料設計中的動畫依賴於實現了時間加速和空間運動的弧形。Android 5.0(API 21)以上,你可以給動畫自定義計時弧形和弧形運動模式。

PathInterpolator類是新的基於貝賽爾曲線或者Path類的加速器。這個加速器詳細說明了在1x1方格中的動作曲線,它的錨頭指在(0, 0)(1, 1)之間,並且控制點使用了構造函數中聲明的值。你也可以在xml文件中定義路徑加速器:

1 <pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
2     android:controlX1="0.4"
3     android:controlY1="0"
4     android:controlX2="1"
5     android:controlY2="1"/>
View Code

系統為材料設計中的三個基礎弧線提供了xml資源:

1 @interpolator/fast_out_linear_in.xml
2 @interpolator/fast_out_slow_in.xml
3 @interpolator/linear_out_slow_in.xml
View Code

你可以把PathInterpolator對象傳給Animator.setInterpolator()方法。

ObjectAnimator對象擁有新的構造器,使得你能夠坐標沿着一個一次使用兩個或者多個屬性的路徑。例如,下面的動畫使用了Path對象使得視圖的XY屬性產生動畫效果:

1 ObjectAnimator mAnimator;
2 mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
3 ...
4 mAnimator.start();
View Code

 

將視圖的狀態變化產生動畫效果

 

StateListAnimator對象讓你定義在視圖狀態變化時運行的動畫。下面的例子向你展示如何將StateListAnimator定義成xml資源:

 1 <!-- animate the translationZ property of a view when pressed -->
 2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 3   <item android:state_pressed="true">
 4     <set>
 5       <objectAnimator android:propertyName="translationZ"
 6         android:duration="@android:integer/config_shortAnimTime"
 7         android:valueTo="2dp"
 8         android:valueType="floatType"/>
 9         <!-- you could have other objectAnimator elements
10              here for "x" and "y", or other properties -->
11     </set>
12   </item>
13   <item android:state_enabled="true"
14     android:state_pressed="false"
15     android:state_focused="true">
16     <set>
17       <objectAnimator android:propertyName="translationZ"
18         android:duration="100"
19         android:valueTo="0"
20         android:valueType="floatType"/>
21     </set>
22   </item>
23 </selector>
View Code

要將自定義的視圖狀態動畫添加到視圖上,要像上述例子一樣,將一個動畫使用xml資源文件中的selector元素定義出來,而且把它通過android:stateListAnimator屬性分配到你的視圖上。要在代碼中把狀態列表動畫分配到視圖中,要使用AnimationInflater.loadStateListAnimator()方法,並且使用View.setStateListAnimator()方法把動畫分配到你的視圖中。

當你的主題繼承自材料主題時,按鈕在默認情況下有Z動畫。要在你的按鈕中避免這種行為,需要把android:stateListAnimator屬性設置成@null

AnimatorStateListDrawable類讓你創建相關聯狀態變化時展示動畫的drawableAndroid 5.0中的某些系統控件默認使用這些動畫。下面的例子展示了如何使用xml資源定義AnimatedStateListDrawable類:

 1 <!-- res/drawable/myanimstatedrawable.xml -->
 2 <animated-selector
 3     xmlns:android="http://schemas.android.com/apk/res/android">
 4 
 5     <!-- provide a different drawable for each state-->
 6     <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
 7         android:state_pressed="true"/>
 8     <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
 9         android:state_focused="true"/>
10     <item android:id="@id/default"
11         android:drawable="@drawable/drawableD"/>
12 
13     <!-- specify a transition -->
14     <transition android:fromId="@+id/default" android:toId="@+id/pressed">
15         <animation-list>
16             <item android:duration="15" android:drawable="@drawable/dt1"/>
17             <item android:duration="15" android:drawable="@drawable/dt2"/>
18             ...
19         </animation-list>
20     </transition>
21     ...
22 </animated-selector>
View Code

 

使矢量Drawable產生動畫

 

矢量圖可縮放但卻不損失精度。AnimatedVectorDrawable類讓你將矢量圖的屬性產生動畫。

你通常情況下在下面三個xml文件中定義動畫矢量圖:

  • res/drawable/目錄下定義擁有元素的矢量圖;
  • res/drawable/目錄下定義擁有元素的可動畫矢量圖;
  • res/anim/目錄下定義擁有元素的一個或者多個對象動畫。

可動畫矢量圖能夠將 等元素的屬性產生動畫。元素定義了一系列的pathgroup,而 元素定義了要被繪制的path

當你定義想要產生動畫的矢量圖時,要使用android:name屬性對grouppath分配唯一的名字。由此,你可以用從你的動畫定義中引用它們,例如:

 1 !-- res/drawable/vectordrawable.xml -->
 2 <vector xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:height="64dp"
 4     android:width="64dp"
 5     android:viewportHeight="600"
 6     android:viewportWidth="600">
 7     <group
 8         android:name="rotationGroup"
 9         android:pivotX="300.0"
10         android:pivotY="300.0"
11         android:rotation="45.0" >
12         <path
13             android:name="v"
14             android:fillColor="#000000"
15             android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
16     </group>
17 </vector>
View Code

可動畫矢量圖定義通過他們的名字引用了grouppath

 1 <!-- res/drawable/animvectordrawable.xml -->
 2 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
 3   android:drawable="@drawable/vectordrawable" >
 4     <target
 5         android:name="rotationGroup"
 6         android:animation="@anim/rotation" />
 7     <target
 8         android:name="v"
 9         android:animation="@anim/path_morph" />
10 </animated-vector>
View Code

這些動畫定義表示ObjectAnimatorAnimatorSet對象。這個例子中的第一個動畫器將目標group旋轉了360度:

1 <!-- res/anim/rotation.xml -->
2 <objectAnimator
3     android:duration="6000"
4     android:propertyName="rotation"
5     android:valueFrom="0"
6     android:valueTo="360" />
View Code

例子中的第二個動畫器使矢量圖的路徑從一種形狀變化為另外一種。兩個路徑必須兼容於產生形變:它們必須擁有相同數量的命令,每個命令必須有相同數量的參數:

1 <!-- res/anim/path_morph.xml -->
2 <set xmlns:android="http://schemas.android.com/apk/res/android">
3     <objectAnimator
4         android:duration="3000"
5         android:propertyName="pathData"
6         android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
7         android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
8         android:valueType="pathType" />
9 </set>
View Code

 

 


免責聲明!

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



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