Android动画:转场动画(过度动画) ActivityOptionsCompat

ActivityOptionsCompat

参考:
你所不知道的Activity转场动画——ActivityOptions
Github项目解析(九)–>实现Activity跳转动画的五种方式

简介

Actiivty转场动画可以使用overridePendingTransition (int enterAnim, int exitAnim),但这种方式太老了,接下来介绍另一种方式ActivityOptions,和兼容类(V4)ActivityOptionsCompat

总效果图

4个静态方法

Android动画:转场动画(过度动画) ActivityOptionsCompat_第1张图片

makeCustomAnimation(Context context, int enterResId, int exitResId)
makeScaleUpAnimation(View source, int startX, int startY, int startWidth, int startHeight)
makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)
makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)
makeSceneTransitionAnimation(Activity activity, Pair...String> sharedElements)

1 makeCustomAnimation(…)

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第2张图片

Demo

View是Button

ActivityOptionsCompat options = ActivityOptionsCompat.makeCustomAnimation(context, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
ActivityCompat.startActivity(context, new Intent(context, Activity_I.class), options.toBundle());

2 makeScaleUpAnimation(…)

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第3张图片

Demo

View是Button

ActivityOptionsCompat options2 = ActivityOptionsCompat.makeScaleUpAnimation(view, view.getWidth() / 2, view.getHeight() / 2, 1000, 1000);
ActivityCompat.startActivity(context, new Intent(context, Activity_I.class), options2.toBundle());

3 makeThumbnailScaleUpAnimation(…)

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第4张图片

Demo

View是Button

ActivityOptionsCompat options3 = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(view, BitmapFactory.decodeResource(getResources(), R.mipmap.b), 0, 0);
ActivityCompat.startActivity(context, new Intent(context, Activity_I.class), options3.toBundle());

4 makeClipRevealAnimation(…)

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第5张图片

Demo

View是Button

ActivityOptionsCompat options4 = ActivityOptionsCompat.makeClipRevealAnimation(view, view.getWidth() / 2, view.getHeight() / 2, 1000, 1000);
ActivityCompat.startActivity(context, new Intent(context, Activity_I.class), options4.toBundle());

transitionName

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第6张图片

Demo

View是Button

ActivityOptionsCompat options5 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, iv, "options5");
ActivityCompat.startActivity(context, new Intent(context, Activity_A.class), options5.toBundle());

//多个view
ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this, new Pair<View, String>(iv1, "iv1"), new Pair<View, String>(iv2), "iv2");

在Actiivty_A中设置transitionName

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    context = this;

    iv_a = (ImageView) findViewById(R.id.iv_a);
    //也可以在xml中配置
//        ViewCompat.setTransitionName(iv_a,"options5");
}

XML中设置transitionName

<ImageView
    android:id="@+id/iv_a"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:transitionName="options5"
    android:src="@mipmap/b"/>

6 makeSceneTransitionAnimation(…) Transition

注意:

API>=21

//退出时使用
getWindow().setExitTransition(explode);
//第一次进入时使用
getWindow().setEnterTransition(explode);
//再次进入时使用
getWindow().setReenterTransition(explode);

当然,你也可以在style中配置

当前页是A,点击A页面的Button,打开B,在按back键,回到A.整个过程中,windowEnterTransition是B要执行的动画,windowExitTransition是A要退出的页面的动画。按back键,B退出是有退出动画的,不需要在设置。

"android:windowEnterTransition">@android:transition/slide_left
"android:windowExitTransition">@android:transition/slide_right

注意:是windowEnterTransition,不是windowEnterAnimation

"android:windowEnterAnimation">@android:anim/slide_in_left
"android:windowExitAnimation">@android:anim/slide_out_right

多个view的都需要这样的效果

ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
        this,
        new Pair(view.findViewById(R.id.imageview_item),
                DetailActivity.VIEW_NAME_HEADER_IMAGE),
        new Pair(view.findViewById(R.id.textview_name),
                DetailActivity.VIEW_NAME_HEADER_TITLE));
ViewCompat.setTransitionName(mHeaderImageView, VIEW_NAME_HEADER_IMAGE);
ViewCompat.setTransitionName(mHeaderTitle, VIEW_NAME_HEADER_TITLE);

6-1 explode

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第7张图片

Demo

View是Button

ActivityOptionsCompat options6 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_B.class), options6.toBundle());

需要在被开启的activity中设置

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 设置contentFeature,可使用切换动画
    // getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);  或者
    requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    Transition explode = TransitionInflater.from(this).inflateTransition(android.R.transition.explode);
    getWindow().setEnterTransition(explode);

    setContentView(R.layout.activity_b);
}

可以给transition添加监听

explode.addListener(transitionListener);

private Transition.TransitionListener transitionListener = new Transition.TransitionListener() {
   @Override
    public void onTransitionStart(Transition transition) {

    }

    @Override
    public void onTransitionEnd(Transition transition) {
        loginApp();
    }

    @Override
    public void onTransitionCancel(Transition transition) {

    }

    @Override
    public void onTransitionPause(Transition transition) {

    }

    @Override
    public void onTransitionResume(Transition transition) {

    }
};

6-2 fade

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第8张图片

demo

View是Button

ActivityOptionsCompat options6 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_C.class), options6.toBundle());

需要在被开启的activity中设置

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    Transition fade = TransitionInflater.from(this).inflateTransition(android.R.transition.fade);
    getWindow().setEnterTransition(fade);

    setContentView(R.layout.activity_b);
}

6-3 move

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第9张图片

Demo

View是Button

ActivityOptionsCompat options6 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_D.class), options6.toBundle());

需要在被开启的activity中设置

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    Transition move = TransitionInflater.from(this).inflateTransition(android.R.transition.move);
    getWindow().setEnterTransition(move);

    setContentView(R.layout.activity_b);
}

6-4 slide_bottom

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第10张图片

Demo

View是Button

ActivityOptionsCompat options6 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_E.class), options6.toBundle());

Activity_E 需要在被开启的activity中设置

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    Transition slide_bottom = TransitionInflater.from(this).inflateTransition(android.R.transition.slide_bottom);
    getWindow().setEnterTransition(slide_bottom);

    setContentView(R.layout.activity_b);
}

6-5 slide_right

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第11张图片

Demo

View是Button

ActivityOptionsCompat options10 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_F.class), options10.toBundle());

需要在被开启的activity中设置

public class Activity_F extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        Transition slide_right = TransitionInflater.from(this).inflateTransition(android.R.transition.slide_right);
        getWindow().setEnterTransition(slide_right);

        setContentView(R.layout.activity_b);
    }
}

6-6 slide_top

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第12张图片

Demo

View是Button

ActivityOptionsCompat options11 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_G.class), options11.toBundle());

需要在被开启的activity中设置

public class Activity_G extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        Transition slide_top = TransitionInflater.from(this).inflateTransition(android.R.transition.slide_top);
        getWindow().setEnterTransition(slide_top);

        setContentView(R.layout.activity_b);
    }
}

6-7 slide_left

效果图

Android动画:转场动画(过度动画) ActivityOptionsCompat_第13张图片

Demo

View是Button

ActivityOptionsCompat options12 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this);
ActivityCompat.startActivity(context, new Intent(context, Activity_H.class), options12.toBundle());

需要在被开启的activity中设置

public class Activity_H extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        Transition slide_left = TransitionInflater.from(this).inflateTransition(android.R.transition.slide_left);
        getWindow().setEnterTransition(slide_left);

        setContentView(R.layout.activity_b);
    }
}

其他

优雅的退出

由A进到到B,我们使用的是转场动画,在B页面,如果按back键,B页面的退出也是转场动画,但是通常Activity顶部有个Titlte,左侧是返回箭头,那么怎么让B退出的时候像进入时那样使用转场东动画呢?
解决方法就是在我们给箭头icon设置点击事件,在点击中调用方法onBackPressed();
Android动画:转场动画(过度动画) ActivityOptionsCompat_第14张图片

ic_back.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        onBackPressed();
    }
});

源码

点击下载源码:ActivityOptionCompat01

overridePendingTransition (int enterAnim, int exitAnim)

overridePendingTransition(R.anim.bottom_to_current,R.anim.current_to_top);

当前页向上退出

Android动画:转场动画(过度动画) ActivityOptionsCompat_第15张图片
current_to_top.xml


<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="0"
    android:toYDelta="-100%">
translate>

bottom_to_current.xml


<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="100%"
    android:duration="500"
    android:toYDelta="0">
translate>

当前页向下退出

Android动画:转场动画(过度动画) ActivityOptionsCompat_第16张图片
current_to_bottom.xml


<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="0"
    android:toYDelta="100%">
translate>

top_to_current.xml


<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="-100%"
    android:toYDelta="0">
translate>

当前页向右退出

Android动画:转场动画(过度动画) ActivityOptionsCompat_第17张图片
current_to_right.xml


<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="100%"
    android:duration="500" >
translate>

left_to_current.xml


<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%"
    android:toXDelta="0"
    android:duration="500" >
translate>

当前页向左退出

Android动画:转场动画(过度动画) ActivityOptionsCompat_第18张图片
current_to_left.xml


<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="-100%"
    android:duration="500" >
translate>

right_to_current.xml


<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="100%"
    android:toXDelta="0"
    android:duration="500" >
translate>

当前页从右边进入,退出时回到右边

startActivity(new Intent(getActivity(), CommonQuestionActivity.class));
overridePendingTransition(R.anim.right_to_current,R.anim.current_to_left);
@Override
public void onBackPressed() {
    super.onBackPressed();
    overridePendingTransition(R.anim.alpha_1_1,R.anim.current_to_right);
}

Activity切换时黑屏

如果我们采用这种方式那么会导致当前页黑屏

startActivity(new Intent(Activity_A.this,Activity_C.class));
overridePendingTransition(R.anim.right_to_current,0);

见图:
Android动画:转场动画(过度动画) ActivityOptionsCompat_第19张图片
解决方法:不实用0,仍然使用动画,将退出动画设置透明度从1到1.
current_stay_alpha.xml

R.anim.current_stay_alpha

overridePendingTransition(R.anim.right_to_current,R.anim.current_stay_alpha);

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="500"
       android:fromAlpha="1"
       android:toAlpha="1">
alpha>

当然,不只是current_stay_alpha,只要使当前页保持不动都可以,下面还有

R.anim.current_stay_translate

overridePendingTransition(R.anim.right_to_current,R.anim.current_stay_translate);

<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:fromXDelta="0"
           android:toXDelta="0"
           android:duration="500">
translate>

current_stay_scale.xml

overridePendingTransition(R.anim.right_to_current,R.anim.current_stay_scale)

<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="500"
       android:fromXScale="1"
       android:fromYScale="1"
       android:toXScale="1"
       android:toYScale="1">
scale>

current_stay_rotate.xml

overridePendingTransition(R.anim.right_to_current,R.anim.current_stay_rotate)

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="500">
rotate>

源码

https://git.oschina.net/AnimationDemo/overridePendingTransition

你可能感兴趣的:(动画)