你們好!wo又來了。。。幾天不見甚是想念!!!最近因爲比較忙,請原諒個人懶惰!!!寫關於MaterialDesign的文章已經有好幾篇了。昨天無心間看見了一個關於過分動畫的概念,因此今天想和你們分享一下關於過分動畫的實戰!這裏嘮叨一下,網上不少文章都是針對於頁面跳轉的動畫,其實過渡動畫不光能夠實現頁面跳轉,對一些控件也是能夠生效的。android
若是你想直接案例解析的話,能夠直接從第三條開始看!!!git
先簡單看一下效果:github
關於過分動畫,是在Android5.0中提出的。它經過運動和切換不一樣狀態之間的元素來產生各類動畫效果。開始的時候,沒有對低版本進行適配,github上有位大神進行了相應的適相似配(使用方式) 地址以下,後來在support包中添加了對低版本的適配,因此使用的時候要注意,不然會出現警告的。。。bash
大致的繼承關係以下:markdown
這個動畫管理類,主要協調相應的動畫管理。重要的API有如下幾個:app
這個主要是針對根試圖的過渡方法:這裏主要是處理一個頁面中的過渡! 這個方法還有一個重載的方法:ide
beginDelayedTransition(@NonNull final ViewGroup sceneRoot)
beginDelayedTransition(@NonNull final ViewGroup sceneRoot, @Nullable Transition transition)
複製代碼
這裏的動畫過渡類型有如下幾類:oop
具體代碼以下:佈局
mCl_root = findViewById(R.id.cl_root); mTvText = findViewById(R.id.tv_text); // Slide slide = new Slide(Gravity.BOTTOM); // Explode explode = new Explode(); Fade fade = new Fade(); TransitionManager.beginDelayedTransition(mCl_root, fade); if (mTvText.getVisibility() == View.VISIBLE) { mTvText.setVisibility(View.GONE); } else { mTvText.setVisibility(View.VISIBLE); } 複製代碼
上面會有三種效果,這裏建議你們本身設置如下看看效果!測試
若是你想設置動畫的一些其餘屬性的話,能夠這樣:
fade.setDuration(300);//設置動畫時長
fade.setInterpolator(new FastOutSlowInInterpolator());//設置插值器
fade.setStartDelay(200);//設置延時
複製代碼
上面全部都有這些屬性的!!!
這裏注意一點,若是你想要使用縮放、顏色、旋轉變化的話,那個適配的庫中有!其實就是繼承了Transition這個類,本身去實現罷了!感興趣的童鞋能夠去試試。。。
說實話,這個東西我研究了很久,各類百度才理解了怎麼用,原諒個人愚笨。。。先說說我對這個東西的理解啊!從一個佈局文件過渡到另外一個佈局文件(注意,這裏是佈局文件的過渡)。我不知道怎麼用語言去形容。。。
我們看圖吧!
上面的圖你們都看懂了吧!其實就是兩個佈局文件的過渡,中間全部的過渡都是TransitionManager幫咱們封裝完成的,你能夠選擇相應的樣式進行顯示!咱們看看具體的代碼實現吧!
首先要給你們說個類,這個類在此過分動畫中起着相當重要的做用,這個類就是
Scene
,註釋裏解釋爲一個視圖層次,也就至關於上面提到的佈局文件過渡中的佈局,其實這個東西你理解成佈局也是能夠的!
Scene getSceneForLayout(@NonNull ViewGroup sceneRoot, @LayoutRes int layoutId, @NonNull Context context)
複製代碼
這樣就能夠建立一個相應的視圖層級了!下面咱們來講代碼:
由於是兩個佈局文件的過渡,因此這裏咱們須要一個總佈局,兩個供切換的佈局,這裏你可能不太明白,一會就明白了!!!相信我,不行你向我丟BUG;
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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:id="@+id/cl_root" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.jinlong.newmaterialdesign.animation.TransitionManagerActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimaryDark" app:title="展現動畫效果" app:titleTextColor="@android:color/white" /> <Button android:id="@+id/btn_animation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="animation" android:text="實現動畫變換" app:layout_constraintTop_toBottomOf="@id/toolbar" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="scene" android:text="變換動畫" app:layout_constraintLeft_toRightOf="@id/btn_animation" app:layout_constraintTop_toBottomOf="@id/toolbar" /> <TextView android:id="@+id/tv_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" android:text="請注意這些文字的變化" app:layout_constraintTop_toBottomOf="@id/btn_animation" /> <FrameLayout android:id="@+id/rl_root" android:layout_width="match_parent" app:layout_constraintTop_toBottomOf="@id/tv_text" android:layout_height="200dp"> <include layout="@layout/scene1" /> </FrameLayout> </android.support.constraint.ConstraintLayout> 複製代碼
這裏主要看FrameLayout中包裹的那個佈局,這是一個佈局文件!都是基於這裏來的!!!
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/civ_1" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@mipmap/heard_1" /> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/civ_2" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="20dp" android:layout_marginRight="20dp" android:src="@mipmap/heard_2" /> </RelativeLayout> 複製代碼
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/civ_2" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@mipmap/heard_2" /> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/civ_1" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="20dp" android:layout_marginRight="20dp" android:src="@mipmap/heard_1" /> </RelativeLayout> 複製代碼
兩個佈局的展示形式是這樣的。仔細的小夥伴可能看到了,兩個佈局的展現形式是同樣的,只是兩個控件的位置互換了一下。其實動畫的表現形式就是那個男孩的頭像從左上角移動到右下角,女孩的頭像從右下角移動到左上角,正好的兩個佈局的展示形式。因此講到這裏我像你就會明白爲何我一直強調是佈局文件的移動了吧!
FrameLayout layout = findViewById(R.id.rl_root);
mScene1 = Scene.getSceneForLayout(layout, R.layout.scene1, this);
mScene2 = Scene.getSceneForLayout(layout, R.layout.scene2, this);
TransitionManager.go(mScene1);
複製代碼
這裏建立了兩個視圖層次,開始的時候,直接默認顯示到視圖圖層1,點擊按鈕進行以下操做:
TransitionManager.go(isScene2 ? mScene1 : mScene2,new ChangeBounds());
isScene2 = !isScene2;
複製代碼
這裏經過一個變量進行判斷,若是顯示的是視圖圖層2就切換到圖層1,不然相反!就能實現上面的效果了!!!總體代碼就不貼了,本身動手試一下,這樣記得牢靠!其實不僅侷限於這種表現形式。若是三個的話,你建立三個視圖圖層也是能夠切換的。這個你就要發揮想象空間了!
關於這個類,能夠簡單理解爲動畫集合,能夠合併多個動畫一塊兒顯示出來。
TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(slide);
transitionSet.addTransition(fade);
複製代碼
這樣就能直接把上面的過渡疊加起來了!
這裏我以爲有必要說明如下xml的使用,首先要明確,這個佈局的放置位置res/transition/xxx.xml。這裏先貼一個總體的xml我在逐一講解:
<?xml version="1.0" encoding="utf-8"?> <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="sequential"><!--是否按照順序執行--> <fade android:duration="500"> <targets> <target android:targetId="@id/toolBar"/> <target android:targetId="@android:id/statusBarBackground"/> <target android:targetId="@id/tv_show"/> </targets> </fade> <slide android:startDelay="600"> <targets> <target android:targetId="@id/icon_sf"/> </targets> </slide> <slide android:startDelay="700"> <targets> <target android:targetId="@id/icon_bh"/> </targets> </slide> <slide android:slideEdge="left" android:startDelay="500"> <targets> <target android:targetId="@id/tv_show"/> </targets> </slide> </transitionSet> 複製代碼
基本上能用到的屬性就這麼多!!!其實這個清單文件裏面主要維護的是哪一個控件須要那種過渡。就醬紫!!!
講了這麼多你是否是仍是一臉懵逼,其實我也是,不知道怎麼去表達,因此我準備用實例去講解,便於本身的記憶和你的理解!!!
終於到了本文的重點了,其實我開始學這個東西的時候也是一臉懵逼,不太理解,可是後來看到代碼的時候,就不那麼費勁了。。。。先從首頁頂部那個圖片開始提及吧!
關於上面的動畫效果,主要記住共享這個概念,爲何這麼說呢?由於上面這個動畫是根據共享去關聯的。所謂的依靠共享,主要是這個View過渡到下一個View的相應展示形式!那麼就存在一個問題了,共享你必須兩個View有共同的一個View,而後存在共同的ID。不然下個頁面怎麼知道你想要拿什麼和我共享呢?這裏暫時定一下Activity頁面A(後面用A代替)和Activity頁面B(後面用B代替)。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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:id="@+id/cl_root" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.jinlong.newmaterialdesign.animation.TransitionManagerActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimaryDark" app:title="展現動畫效果" app:titleTextColor="@android:color/white" /> <LinearLayout android:id="@+id/ll_shared" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:onClick="sharedAnimation" android:orientation="horizontal" app:layout_constraintTop_toBottomOf="@id/toolbar"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/civ_heard" android:layout_width="50dp" android:layout_height="50dp" android:src="@mipmap/heard_1" /> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="30dp" android:text="這是一個標題欄目" /> </LinearLayout> </android.support.constraint.ConstraintLayout> 複製代碼
這裏注意上面的CircleImageView控件的ID和TextView控件的ID,上面說了,後面會用到!
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" tools:context="com.jinlong.newmaterialdesign.animation.SharedActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimaryDark" app:title="展現動畫效果" app:titleTextColor="@android:color/white" /> <LinearLayout android:id="@+id/fl_top" android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center" android:orientation="vertical" app:layout_constraintTop_toBottomOf="@id/toolbar"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/civ_heard" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/heard_1" android:transitionName="shared_image" /> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="這也是相應的標題" android:transitionName="shared_textview" /> </LinearLayout> </android.support.constraint.ConstraintLayout> 複製代碼
這裏的ID和上面的ID是同樣的。而且注意這裏面設置的transitionName標籤,這個標籤是設置共享內容的,立刻你就會知道爲何了。。。
CircleImageView civHead = findViewById(R.id.civ_heard); TextView tvTitle = findViewById(R.id.tv_title); Intent intent = new Intent(this, SharedActivity.class); ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this, new Pair<View, String>(civHead, "shared_image"), new Pair<View, String>(tvTitle, "shared_textview")); startActivity(intent, optionsCompat.toBundle()); 複製代碼
看了上面的內容,我相信你能寫出下面的動畫效果了!
其實後面那個圓形擴散的效果是在5.0之後纔有的效果(使用的是ViewAnimationUtils),因此要使用的話,必須在5.0機器上測試。不然是沒有效果的!!!代碼是這樣的...
Animator circularReveal = ViewAnimationUtils.createCircularReveal(mImage_bg, 0, mImage_bg.getHeight(), 0, Math.max(mImage_bg.getHeight(), mImage_bg.getWidth()));
mImage_bg.setBackgroundColor(Color.BLACK);
circularReveal.setDuration(600);
circularReveal.start();
複製代碼
其實用到的只有一個API方法Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)
這裏面的參數基本上就是中心點座標,擴散半徑的肯定,這裏就不作太多解釋了!這個你能夠在在21的版本試一下就能夠了!
在B頁面其實也是能夠設置相應的入場動畫的
穿插一個問題,就是Transition怎麼從xml中引入
TransitionInflater.from(this).inflateTransition(R.transition.return_slide)
複製代碼
這裏的Transition能夠是一個具體的子類,也能夠是一個清單文件。剩下的就是發揮你們的想象空間了!把上面的頁面剩下的代碼貼一下,就結束今天的內容吧!感受篇幅有點長,感興趣的同窗,能夠看看我GitHub裏面的項目!!!
這篇文章我寫了好幾天,不知道該怎麼去寫,感受寫的有點亂,但願你們不要介意,有什麼不懂的留言給我,我必定及時回覆......今天就醬紫了!