最近看到一個(gè)項(xiàng)目上的界面切換時(shí)的過(guò)渡效果很炫,決定實(shí)現(xiàn)一下,先放上效果圖:

效果就是在跳轉(zhuǎn)到另一個(gè)Activity時(shí) 控件并沒有消失,而是直接位移到指定位置,這個(gè)過(guò)渡效果就非常的自然,這就是”共享動(dòng)畫”。廢話不多說(shuō),來(lái)看實(shí)現(xiàn)步驟
這邊分為兩個(gè)界面:MainActivity 和 ActivityDetails,從 MainActivity 跳轉(zhuǎn)到 ActivityDetails
首先來(lái)說(shuō) MainActivity:
這邊的列表我是用的 RecyclerView 來(lái)實(shí)現(xiàn)的,用RecyclerView來(lái)顯示數(shù)據(jù)這個(gè)太簡(jiǎn)單就不用說(shuō)了吧,注意,這里有個(gè)不同的地方在于在列表的 Item 布局文件中 還要稍微加一點(diǎn)東西
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp">
<ImageView
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:transitionName="image"
android:src="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="標(biāo)題"
android:transitionName="name"
android:textSize="16dp"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2017-08-01"
android:layout_marginTop="5dp"/>
<TextView
android:id="@+id/sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這只是一個(gè)說(shuō)明"
android:layout_marginTop="5dp"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
不知道大家有沒有注意到,在布局文件中 id 為 image 和 name 的控件中多了一句 android:transitionName=”” 那么這個(gè)是干什么用的呢 ? 這個(gè)的作用就是和第二個(gè)Activity中的 顯示圖片和 文字的控件關(guān)聯(lián)起來(lái)的,我這邊ImageView控件的 transitionName=”image” TextView控件寫的是 transitionName=”name”,那么第二個(gè)Activity中的布局文件中 對(duì)應(yīng)的 ImageView 控件和 TextView 也要寫上這么一句話,這樣 跳轉(zhuǎn)的時(shí)候,第一個(gè)界面的控件才會(huì)以移動(dòng)的方式過(guò)渡到第二個(gè)界面的對(duì)應(yīng)的位置,否則,是不起效果的。當(dāng)然 這種動(dòng)畫一般只是在兩個(gè)Activity中有相同控件的時(shí)候使用,這兩個(gè)相同的控件就被稱為”共享元素”
在看看第二個(gè)界面的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yinshuai.sharinganimation.ActivityDetails">
<LinearLayout
android:id="@+id/head"
android:layout_width="match_parent"
android:layout_height="47dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="詳情"
android:textSize="25dp" />
</LinearLayout>
<ImageView
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="@+id/head"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp"
android:transitionName="image" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:text=""
android:textSize="16dp"
android:transitionName="name" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/name"
android:layout_marginTop="10dp"
android:padding="18dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/context" />
</LinearLayout>
</RelativeLayout>
我在相對(duì)應(yīng)的控件上同樣寫了 android:transitionName=”” 的這樣一句話。布局文件寫好了,事情就成功一半了
接著在列表的 Item 點(diǎn)擊事件里面寫跳轉(zhuǎn)的代碼:
m.setOnItemOnclick(new MyAdapter.OnItemOnclick() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onclick(String url, String name, View image, View names) {
Intent in = new Intent();
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,
Pair.create(image, "image"),
Pair.create(names, "name")).toBundle();
in.setClass(MainActivity.this, ActivityDetails.class);
in.putExtra("url", url);
in.putExtra("name", name);
startActivity(in, bundle);
}
這個(gè)點(diǎn)擊事件是自己自定義的,為了方便,我就直接把那兩個(gè)共享元素給回調(diào)回來(lái)了,方便使用!
再來(lái)看看跳轉(zhuǎn)的代碼,跟以前跳轉(zhuǎn)是不是有點(diǎn)不一樣,多了一個(gè)
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,
Pair.create(image, "image"),
Pair.create(names, "name")).toBundle();
那么這是干什么用的呢,可以發(fā)現(xiàn),在makeSceneTransitionAnimation()里面有三個(gè)參數(shù),第一個(gè)是當(dāng)前的Activity,第二個(gè)就是共享元素了,因?yàn)槲疫@里有兩個(gè)共享元素,所以使用了Pair.create(),如果只有一個(gè)共享元素的話,那么這樣寫就可以了:
ActivityOptions.makeSceneTransitionAnimation(this,image,"image").toBundle()
不止一個(gè)的話就要用Pair.create()去添加不同的共享元素了,Pair.create()也有兩個(gè)參數(shù),第一個(gè)是共享元素的View,第二個(gè)就是你的transitionName ,這樣寫完就可以去看看切換的效果了
效果出來(lái)之后發(fā)現(xiàn)一個(gè)問(wèn)題,按手機(jī)的返回鍵是退出是有動(dòng)畫效果的,但是有自定義的返回按鈕調(diào)用 finish(); 關(guān)閉Activity返回的話動(dòng)畫效果就會(huì)失效,這里我們可以調(diào)用 finishAfterTransition(); 方法銷毀 Activity,這個(gè)就是等到把動(dòng)畫執(zhí)行完成之后再銷毀Activity。
好了,實(shí)現(xiàn)的過(guò)程就是這樣了!
個(gè)人博客:小白的博客
Demo地址:SharingAnimation