Activity之间的动画切换学习笔记(一)

本文介绍了安卓5.0中Activity间动画切换的Transition框架,包括场景(scenes)和变换(transitions)的概念,以及如何启用和设置exit、enter、return和reenter四种transition。文章通过示例展示了explode、slide、fade等动画效果,并探讨了元素共享和常见问题的解决方案,提供了相关学习资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Activity之间的动画切换

首先什么是Transition?

安卓5.0中Activity和Fragment变换是建立在名叫Transitions的安卓新特性之上的。这个诞生于4.4的transition框架为在不同的UI状态之间产生动画效果提供了非常方便的API。该框架主要基于两个概念:场景(scenes)和变换(transitions)。场景(scenes)定义了当前的UI状态,变换(transitions)则定义了在不同场景之间动画变化的过程。虽然transition翻译为变换似乎很确切,但是总觉得还是没有直接使用transition直观,为了更好的理解下面个别地方直接用transition代表变换。

当一个场景改变的时候,transition主要负责:

1)捕捉每个View在开始场景和结束场景时的状态。
(2)根据两个场景(开始和结束)之间的区别创建一个Animator

transition框架的两个主要优点。第一、Transitions抽象和封装了属性动画,Animator的概念对开发者来说是透明的,因此它极大 的精简了代码量。开发者所做的所有事情只是改变一下view前后的状态数据,Transition就会自动的根据状态的区别去生成动画效果。第二、不同场 景之间变换的动画效果可以简单的通过使用不同的Transition类来改变。一般的transition有explode,fade,slide。

在开始讲解之前我们先做一些约定,虽然下面的约定是针对activity的,但是在Fragment中也是一样的约定。
AB表示两个Activity,现在假设A跳转B。这里的进入和退出一个有两种方式。
Activity transition API围绕退出(exit),进入(enter),返回(return)和再次进入(reenter)四种transition。按照上面对A和B的约定,我这样描述这一过程。

Activity A的退出变换(exit transition)决定了在A调用B的时候,A中的View是如何播放动画的。
Activity B的进入变换(enter transition)决定了在A调用B的时候,B中的View是如何播放动画的。
Activity B的返回变换(return transition)决定了在B返回A的时候,B中的View是如何播放动画的。
Activity A的再次进入变换(reenter transition)决定了在B返回A的时候,A中的View是如何播放动画的。

具体的使用步骤:
1.在调用与被调用的activity中,通过设定Window.FEATURE_ACTIVITY_TRANSITIONS 和 Window.FEATURE_CONTENT_TRANSITIONS 来启用transition api ,可以通过代码也可以通过设置主题来启用:
A.代码方式,在setContentView之前调用:
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
B.主题xml
item name=”android:windowContentTransitions”>true

2.分别在调用与被调用的activity中设置exit 和enter transition。Material主题默认会将exit的transition设置成null而enter的transition设 置成Fade .如果reenter 或者 return transition没有明确设置,则将用exit 和enter的transition替代。

            getWindow().setExitTransition(explode);
            getWindow().setEnterTransition(explode);

开始一个activity的content transaction需要调用startActivity(Context, Bundle)方法,将下面的bundle作为第二个参数:
只是单纯的slide或者fade效果以及只有一个view元素共享,
Bundle=ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
Bundle= ActivityOptions.makeSceneTransitionAnimation(this, view, “transitionName”).toBundle());
但是如果是多个view进行元素共享,用pari更方便
Pari:import android.support.v4.util.Pair;
//比如三个view同时设置共享元素

Pair first=new Pair<>(small, ViewCompat.getTransitionName(small));
Pair second=new Pair<>(small1, ViewCompat.getTransitionName(small1));
Pair thid=new Pair<>(small2, ViewCompat.getTransitionName(small2));
ActivityOptionsCompat optionsMore = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, first,second,thid);

熟悉基本的步骤后下面整理几个学习的demo
1.explode|slide|fade

explode:

final Transition explode = TransitionInflater.from(this).inflateTransition(R.transition.explode);
   /*
  退出时使用
   */
  getWindow().setExitTransition(explode);
   /*
   第一次进入时使用
   */
  getWindow().setEnterTransition(explode);
  /*
   再次进入时使用
   */
 getWindow().setReenterTransition(explode);
 startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(StartActivity.this).toBundle());

这里写图片描述
fade:

 final Transition fade = TransitionInflater.from(this).inflateTransition(R.transition.fade);

 findViewById(R.id.fade).setOnClickListener(new View.OnClickListener() {
    @Override
  public void onClick(View v) {
   getWindow().setExitTransition(fade);
  getWindow().setEnterTransition(fade);
  getWindow().setReenterTransition(fade);
  startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(StartActivity.this).toBundle());
    }
});

这里写图片描述

slide:

 final Transition slide= TransitionInflater.from(this).inflateTransition(R.transition.slide);
 findViewById(R.id.slide).setOnClickListener(new View.OnClickListener() {
    @Override
  public void onClick(View v) {
   getWindow().setExitTransition(slide);
  getWindow().setEnterTransition(slide);
  getWindow().setReenterTransition(slide);
  startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(StartActivity.this).toBundle());
    }
});

这里写图片描述

元素共享:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        final Intent intent = new Intent(MainActivity.this, Main2Activity.class);
        small= (TextView) findViewById(R.id.small);
        small1= (TextView) findViewById(R.id.small1);
        small2= (TextView) findViewById(R.id.small2);



        //多个view同时分享元素,就要用到pari

    findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
      Pair first=new Pair<>(small, ViewCompat.getTransitionName(small));
      Pair second=new Pair<>(small1, ViewCompat.getTransitionName(small1));
      Pair thid=new Pair<>(small2, ViewCompat.getTransitionName(small2));
      ActivityOptionsCompat optionsMore = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, first,second,thid);
                startActivity(intent,optionsMore.toBundle());
            }
        });
    }

这里写图片描述

这里注意,这个时候使用的不是ActivityOptions而是ActivityOptionsCompat

这里写共享元素的时候出现两个问题:
第一个:
这里写图片描述
这个是由于所有的TransitionName设置的值都是一样的,感觉起来第二只有
第二个问题:
这里写图片描述

我打印了Activity1中的log,发现控件的可见值发生了变化,但是具体原因我不清楚….还在找:

    是否可见----第一个8  第二个8   第三个0
    是否可见----第一个4  第二个0   第三个0

以上,我们都是主要在Activity1中设置动画,还有一个问题就是假设不在点击事件中进行startActivity,就会有一个异常,这个问题我也在找….(好多问题还不清楚…..还在学习…..).
这里写图片描述
这个效果,是不是感觉像侧滑菜单,这个就是直接在Activity2中调用setupWindowAnimations即可

 private void setupWindowAnimations() {
        Transition fade = TransitionInflater.from(this).inflateTransition(R.transition.slide);
        getWindow().setReturnTransition(fade);//返回上一个activity 时本activity的效果
        getWindow().setEnterTransition(fade);//进入本activity时本activity的效果
    }

以上,就是现在的一个学习整理,还有好多不清楚的地方还在查找学习,加油~

参考数据:
https://github.com/lgvalle/Material-Animations/blob/master/README.md
http://www.jianshu.com/p/1b5212d84a15
http://blog.youkuaiyun.com/u013675234/article/details/50472282
http://blog.youkuaiyun.com/huachao1001/article/details/51659963
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0201/2394.html
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0113/2310.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值