Android的共享动画

作者: 哥只是个小白 | 来源:发表于2017-08-02 14:39 被阅读142次

    最近看到一个项目上的界面切换时的过渡效果很炫,决定实现一下,先放上效果图:

    sharinganimations.gif

    效果就是在跳转到另一个Activity时 控件并没有消失,而是直接位移到指定位置,这个过渡效果就非常的自然,这就是”共享动画”。废话不多说,来看实现步骤

    这边分为两个界面:MainActivity 和 ActivityDetails,从 MainActivity 跳转到 ActivityDetails

    首先来说 MainActivity:

    这边的列表我是用的 RecyclerView 来实现的,用RecyclerView来显示数据这个太简单就不用说了吧,注意,这里有个不同的地方在于在列表的 Item 布局文件中 还要稍微加一点东西

    <?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="标题"
                    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="这只是一个说明"
                    android:layout_marginTop="5dp"/>
    
            </LinearLayout>
    
    
        </LinearLayout>
    
    </android.support.v7.widget.CardView>
    

    不知道大家有没有注意到,在布局文件中 id 为 image 和 name 的控件中多了一句 android:transitionName=”” 那么这个是干什么用的呢 ? 这个的作用就是和第二个Activity中的 显示图片和 文字的控件关联起来的,我这边ImageView控件的 transitionName=”image” TextView控件写的是 transitionName=”name”,那么第二个Activity中的布局文件中 对应的 ImageView 控件和 TextView 也要写上这么一句话,这样 跳转的时候,第一个界面的控件才会以移动的方式过渡到第二个界面的对应的位置,否则,是不起效果的。当然 这种动画一般只是在两个Activity中有相同控件的时候使用,这两个相同的控件就被称为”共享元素”

    在看看第二个界面的布局文件:

    <?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>
    

    我在相对应的控件上同样写了 android:transitionName=”” 的这样一句话。布局文件写好了,事情就成功一半了

    接着在列表的 Item 点击事件里面写跳转的代码:

    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);
                }
    

    这个点击事件是自己自定义的,为了方便,我就直接把那两个共享元素给回调回来了,方便使用!

    再来看看跳转的代码,跟以前跳转是不是有点不一样,多了一个

    Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,
                            Pair.create(image, "image"),
                            Pair.create(names, "name")).toBundle();
    

    那么这是干什么用的呢,可以发现,在makeSceneTransitionAnimation()里面有三个参数,第一个是当前的Activity,第二个就是共享元素了,因为我这里有两个共享元素,所以使用了Pair.create(),如果只有一个共享元素的话,那么这样写就可以了:

    ActivityOptions.makeSceneTransitionAnimation(this,image,"image").toBundle()
    

    不止一个的话就要用Pair.create()去添加不同的共享元素了,Pair.create()也有两个参数,第一个是共享元素的View,第二个就是你的transitionName ,这样写完就可以去看看切换的效果了

    效果出来之后发现一个问题,按手机的返回键是退出是有动画效果的,但是有自定义的返回按钮调用 finish(); 关闭Activity返回的话动画效果就会失效,这里我们可以调用 finishAfterTransition(); 方法销毁 Activity,这个就是等到把动画执行完成之后再销毁Activity。

    好了,实现的过程就是这样了!

    个人博客:小白的博客
    Demo地址:SharingAnimation

    相关文章

      网友评论

      • 97e9b333db5a:以前的网易云音乐就是用的这个动画,后来某个版本更新就不见了。
        哥只是个小白:@一叶知秋丶lo 按手机上的返回按钮是调onBackPressed();你可以试下在返回按钮的点击事件里面调用这个方法,但这个方法和finish还是有些区别的,使用的时候注意
        6f6b938b6355:您好,我想请问下,我在第二个页面通过点击按钮返回上一个界面,怎么才能够也能够这样的返回效果呢?直接finish的话是默认的activity的返回效果qwq
        哥只是个小白:可能换设计师了:smile:

      本文标题:Android的共享动画

      本文链接:https://www.haomeiwen.com/subject/fhaelxtx.html