接到一個需求,需要向tumblr 發佈內容頁和標籤頁的切換學習,然後找到shared element transition這個東西。翻譯爲共享元素轉換。
看了很多的資源,我的理解是a頁面跳轉到b頁面是,b中存在和a頁顯示效果極爲相似的控件,所以這兩個控件就可以看成是共享的。但由於這兩個控件會存在差異,所以會有一個轉換的效果。
接下來是實際使用。首先這個東西只適用於v21以上的的系統版本,兼容的話,我的做法是通過建立values-v21文件夾,並在其中建立新的style文件將21支持的共享元素轉換的item加進去。
<!-- Base application theme. --> <style name="AppTheme" parent="@android:style/Theme.Material"> <!-- enable window content transitions --> <item name="android:windowContentTransitions">true</item> <!-- specify shared element transitions --> <item name="android:windowSharedElementEnterTransition">@transition/transition</item> <item name="android:windowSharedElementExitTransition">@transition/transition</item> </style>然後是transition的使用
transition也是一個資源文件,在res文件夾下面創建一個名transition的文件夾,在transition文件夾下建立一個xml資源文件,在這裏我建立的文件名爲transition.xml其中內容爲
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> <!--ChangeBounds -捕獲共享元素的layout bound,然後播放layout bound變化動畫。ChangeBounds 是共享元素變換中用的最多的,因爲前後兩個activity中共享元素的大小和位置一般都是不同的。--> <!--ChangeTransform - 捕獲共享元素的縮放(scale)與旋轉(rotation)屬性 ,然後播放縮放(scale)與旋轉(rotation)屬性變化動畫。--> <!--ChangeClipBounds - 捕獲共享元素clip bounds,然後播放clip bounds變化動畫。--> <!--ChangeImageTransform - 捕獲共享元素(ImageView)的transform matrices 屬性,然後播放ImageViewtransform matrices 屬性變化動畫。與ChangeBounds相結合,這個變換可以讓ImageView在動畫中高效實現大小,形狀或者ImageView.ScaleType 屬性平滑過度。--> <!--@android:transition/move - 將上述所有變換同時進行的一個TransitionSet 。就如在第一章中所講的一樣,如果共享元素的進入和返回變換沒有特別聲明,框架將使用它作爲默認的變換。--> <changeBounds /> <!--<changeImageTransform />--> </transitionSet>其中 ChangeBounds, ChangeTransform , ChangeClipBounds , ChangeImageTransform 這幾個屬性都是對共享元素的動畫的處理。因爲兩個界面的共享元素的狀態是不一樣的,所以需要一個轉換的動畫。 接下來是在java代碼中的使用 首先a頁面
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 允許使用transitions getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); setContentView(R.layout.activity_main); initView(); }
其中getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);這句和style中的設置有重複
如果不在style中加入,則需要在代碼中寫入這句話。
接下來是設置需要共享的view以及跳轉
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, view, "title");
Intent intent = new Intent(this,Main2Activity.class); ActivityCompat.startActivity(this, intent, options.toBundle());
說明:這裏ActivityOptionsCompat中的方法不止這一種,其他的方法還有其他的功能,這裏只是用於共享元素才使用這個方法。
b頁面
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); tv_title = (TextView)findViewById(R.id.tv_title); ViewCompat.setTransitionName(tv_title,"title"); }
ViewCompat.setTransitionName(tv_title,"title");這句話是爲了表明共享的元素,很重要,沒有它達不到預期效果。最後,這裏只是單個元素的共享,還可以共享多個元素,更多更好的內容可以參考http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0201/2394.html