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

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

Activity之间的动画切换学习笔记(一)_第1张图片
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());
    }
});

Activity之间的动画切换学习笔记(一)_第2张图片

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

Activity之间的动画切换学习笔记(一)_第3张图片

元素共享:

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

Activity之间的动画切换学习笔记(一)_第4张图片

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

这里写共享元素的时候出现两个问题:
第一个:
Activity之间的动画切换学习笔记(一)_第5张图片
这个是由于所有的TransitionName设置的值都是一样的,感觉起来第二只有
第二个问题:
Activity之间的动画切换学习笔记(一)_第6张图片

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

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

以上,我们都是主要在Activity1中设置动画,还有一个问题就是假设不在点击事件中进行startActivity,就会有一个异常,这个问题我也在找….(好多问题还不清楚…..还在学习…..).
Activity之间的动画切换学习笔记(一)_第7张图片
这个效果,是不是感觉像侧滑菜单,这个就是直接在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.csdn.net/u013675234/article/details/50472282
http://blog.csdn.net/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

你可能感兴趣的:(Android)