前言

对于Activity的过度动画都很熟悉了,大多数都是直接使用下面的函数,指定退出的Activity和进入的Activity动画

overridePendingTransition(enterAnim, exitAnim);

这种动画很简单,旋转平移翻转等,这些操作,而且是这个界面的操作。下面介绍一种更加美观的Activity过度动画

Android在新的sdk中给我们提供了另外一种Activity的过度动画——ActivityOptions。并且提供了兼容包——ActivityOptionsCompat。

一、 简介

ActivityOptionsCompat是一个静态类,提供了5个方法,如下:

  1. ActivityOptionsCompat.makeCustomAnimation(Context context, int enterResId, int exitResId)

  2. ActivityOptionsCompat.makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)

  3. ActivityOptionsCompat.makeThumbnailScaleUpAnimation(View source,Bitmap thumbnail, int startX, int startY)

  4. ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)

  5. ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity,Pair

二、函数的使用

这里对这些函数的使用进行讲解:

2.1、makeCustomAnimation

makeCustomAnimation和overridePendingTransition非常类似,在实现效果上和overridePendingTransition也是相同的。

在界面A启动界面B
Activity A ——> Activity B

Activity A 中的代码:

public void click(View view) {      ActivityOptionsCompat compat = ActivityOptionsCompat.makeCustomAnimation(this,              R.anim.translate_in, R.anim.translate_none);      ActivityCompat.startActivity(this,              new Intent(this, Activity2.class), compat.toBundle());}

三个参数,第一个是指当前activity,第二个和第三个参数分别是进入动画和退出动画,

ActivityCompat.startActivity()最后一个参数我们使用compat.toBundle。

Activity B 中的代码:

    @Override    public void onBackPressed() {        super.onBackPressed();        ActivityCompat.finishAfterTransition(this);    }

退出的时候调用ActivityCompat.finishAfterTransition(this)进行退出动画。

2.2、makeScaleUpAnimation 比例放大动画

效果就是不断的 ,放大一个view,进而进行activity的过度,

private void launch(View view) {    ActivityOptionsCompat compat = ActivityOptionsCompat.makeScaleUpAnimation(view,            view.getWidth() / 2, view.getHeight() / 2, 0, 0);    ActivityCompat.startActivity(this, new Intent(this, Activity2.class),            compat.toBundle());}

第1个参数是scale哪个view的大小,
第2和3个参数是以view为基点,从哪开始动画,这里是该view的中心,
第4和5参数是新的activity,从多大开始放大,这里是从无到有的过程。

2.3、makeThumbnailScaleUpAnimation

该方法和上面的makeScaleUpAnimation非常相似,只不过,这里是通过放大一个图片,最后过度到一个新的activity,

第2个参数是指那个图片要放大,
3和4参数表示从哪开始动画。

接下来我们要进入两个稍微复杂点的动画,这两个的方法名相同,都是makeSceneTransitionAnimation。

2.4、makeSceneTransitionAnimation 单个view的过度动画

什么是scene? 就是场景动画,在这里就体现在两个activity中的某些view协同去完成过度动画,先来看一个效果吧

Activity A ——> Activity B

Activity A中的代码

private void launch(View view) {    ActivityOptionsCompat compat =            ActivityOptionsCompat.makeSceneTransitionAnimation(this,                    view, getString(R.string.transition));    ActivityCompat.startActivity(this, new Intent(this,            Activity2.class), compat.toBundle());}

第一个参数:当前的activity
第二个参数:对这个view进行动画,来多过度到Activity B
第三个参数:view上指定的动画名称

因为要协作动画的两个view在不同的activity中,为了让这两个view产生关联,在xml配置项android:transitionName用来指定协作的view

<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=".MainActivity">    <ImageView        android:id="@+id/image"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        android:scaleType="fitXY"        android:src="@drawable/show"        android:transitionName="@string/image" />RelativeLayout>

看ImageView的android:transitionName属性,为”@string/image”

Activity B中的代码

<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=".MainActivity">    <ImageView        android:id="@+id/image"        android:layout_width="match_parent"        android:layout_height="200dp"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:scaleType="fitXY"        android:src="@drawable/show"        android:transitionName="@string/image" />RelativeLayout>

也有一个android:transitionName属性,为”@string/image”的view

在makeSceneTransitionAnimation 的第三个参数是getString(R.string.transition)。这样这两个view就可以进行过渡动画了

2.5、makeSceneTransitionAnimation 多个view的协作

既然能指定一个view来进行协作,那肯定也能指定多个view了,来看看效果,

Activity A ——> Activity B

Activity A中的代码

private void launch() {    Pair<View, String> imagePair = Pair.create(mImageView, getString(R.string.image));    Pair<View, String> textPair = Pair.create(mTextView, getString(R.string.name));    ActivityOptionsCompat compat = ActivityOptionsCompat            .makeSceneTransitionAnimation(this, imagePair, textPair);    ActivityCompat.startActivity(this, new Intent(this, Activity2.class),            compat.toBundle());}
  1. 通过Pair.create静态方法创建了两个Pair对象,这里有两个泛型,分别指定为View和String类型,create方法接受两个参数,第一个是参与动画的View,第二个是该View上的transitionName,和前面单一协作的类似,

  2. 用makeSceneTransitionAnimation方法创建一个compat,第二个参数是Pair类型,并且可以传入多个Pair类型的参数

  3. 最后用ActivityCompat.startActivity启动新的activity。

<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=".MainActivity">    <TextView        android:id="@+id/text"        android:textSize="20sp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        android:transitionName="@string/name"        android:text="LOADER!!" />    <ImageView        android:id="@+id/image"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_above="@id/text"        android:layout_centerHorizontal="true"        android:src="@drawable/show"        android:transitionName="@string/image" />RelativeLayout>

Activity B中的代码

<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=".MainActivity">    <ImageView        android:id="@+id/image"        android:layout_width="wrap_content"        android:layout_height="300dp"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:src="@drawable/show"        android:scaleType="fitXY"        android:transitionName="@string/image" />    <TextView        android:id="@+id/text"        android:textSize="20sp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/image"        android:transitionName="@string/name"        android:layout_centerHorizontal="true"        android:text="LOADER!!" />RelativeLayout>

点击item ,其中多个元素过度到新的Activity

想要点击列表中的item,以过度动画的形式打开新的Activity,不能在item的xml布局文件中指定android:transitionName属性

因为屏幕中显示出来的item都会声明这个属性,只有第一个item的android:transitionName生效,就会导致所以的item的过度动画的开始位置,都是在第一个。

Activity A(列表界面) ——> Activity B(详情界面)

需要为不同的item创建不同的过度动画名称,代码如下:
1、在adapter中为每一个item的共享元素创建动画名称

    class ListViewHolder(view: View) : RecyclerView.ViewHolder(view) {        fun bind(post: PostWithUser, picasso: Picasso) {            with(post) {                itemView.tvTitle.text = postTitle                itemView.tvBody.text = getFormattedPostBody()                itemView.tvAuthorName.text = userName                picasso.load(getAvatarPhoto()).into(itemView.ivAvatar)                //SharedItem transition                ViewCompat.setTransitionName(itemView.tvTitle, postTitle)                ViewCompat.setTransitionName(itemView.tvBody, postBody)                ViewCompat.setTransitionName(itemView.tvAuthorName, userName)                ViewCompat.setTransitionName(itemView.ivAvatar, getAvatarPhoto())            }        }    }

2、Activity A中的代码

val intent = Intent(context, DetailsActivity::class.java)intent.putExtra(SELECTED_POST, post)//Transitionsintent.putExtra(TITLE_TRANSITION_NAME, ViewCompat.getTransitionName(tvTitle))intent.putExtra(BODY_TRANSITION_NAME, ViewCompat.getTransitionName(tvBody))intent.putExtra(AUTHOR_TRANSITION_NAME, ViewCompat.getTransitionName(tvAuthorName))intent.putExtra(AVATAR_TRANSITION_NAME, ViewCompat.getTransitionName(ivAvatar))val p1 = Pair.create(tvTitle as View, ViewCompat.getTransitionName(tvTitle))val p2 = Pair.create(tvBody as View, ViewCompat.getTransitionName(tvBody))val p3 = Pair.create(tvAuthorName as View, ViewCompat.getTransitionName(tvAuthorName))val p4 = Pair.create(ivAvatar as View, ViewCompat.getTransitionName(ivAvatar))val options = ActivityOptionsCompat.makeSceneTransitionAnimation(context as Activity,p1,p2,p3,p4)context.startActivity(intent, options.toBundle())

3、Activity B 中的代码

可以在xml中,指定共享view的动画名称,也可以通过代码来指定,如下,该函数在onCreate中调用

private fun handleTransition(extras: Bundle?) {     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {            tvTitle.transitionName = extras?.getString(TITLE_TRANSITION_NAME)            tvBody.transitionName = extras?.getString(BODY_TRANSITION_NAME)            tvAuthorName.transitionName = extras?.getString(AUTHOR_TRANSITION_NAME)            ivAvatar.transitionName = extras?.getString(AVATAR_TRANSITION_NAME)        }}

该代码来自示例:https://github.com/karntrehan/Posts

参考:

这篇文章实现的效果挺不错的 项目需求讨论 — 用Transition做一个漂亮的登录界面

Android自定义Transition动画
你所不知道的Activity转场动画——ActivityOptions
Android Transition(Android过渡动画)

使用Circular Reveal为你的应用添加揭露动画效果

关注我的公众号,轻松了解和学习更多技术

更多相关文章

  1. android 开发 - 对图片进行虚化(毛玻璃效果,模糊)
  2. android实现通知栏下载更新app示例
  3. Android实现语音识别代码
  4. Android(安卓)recycleview实现左右切换时的条目滑动效果,条目是固
  5. Android(安卓)Asynchronous Http Client 中文手册
  6. React Native在Android当中代码集成
  7. PullToRefreshListView怎么设置各个item之间的间距
  8. Android:overridePendingTransition()函数介绍
  9. Android倒计时功能的实现(CountDownTimer)

随机推荐

  1. 如何在android中调用数据库资源
  2. Android(安卓)异步处理
  3. Android作为Socket服务器端
  4. Android快速设置中添加隐藏状态栏和导航
  5. Android(安卓)签名详解
  6. Android(安卓)App 获取 root权限
  7. 如何在android中实现swipe的手势功能及页
  8. [Android算法] Android蓝牙开发浅谈
  9. Android(安卓)Activity生命周期图解
  10. 非常详细的测试unity与android之间的通讯