Android动画 转场动画 过度动画 ActivityOptionsCompat

首先给大家推荐一下我老师大神的人工智能教学网站。教学不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵黄段子!点这里可以跳转到网站

ActivityOptionsCompat

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

简介

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

总效果图

这里写图片描述

4个静态方法

这里写图片描述
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...<View, String> sharedElements)

1 makeCustomAnimation(…)

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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退出是有退出动画的,不需要在设置。

<item name="android:windowEnterTransition">@android:transition/slide_left</item>
<item name="android:windowExitTransition">@android:transition/slide_right</item>

注意:是windowEnterTransition,不是windowEnterAnimation

<item name="android:windowEnterAnimation">@android:anim/slide_in_left</item>
<item name="android:windowExitAnimation">@android:anim/slide_out_right</item>

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

ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
        this,
        new Pair<View, String>(view.findViewById(R.id.imageview_item),
                DetailActivity.VIEW_NAME_HEADER_IMAGE),
        new Pair<View, String>(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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

效果图

这里写图片描述

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

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

当前页向上退出

这里写图片描述


current_to_top.xml

<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="0"
    android:toYDelta="-100%">
</translate>

bottom_to_current.xml

<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="100%"
    android:duration="500"
    android:toYDelta="0">
</translate>

当前页向下退出

这里写图片描述


current_to_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="0"
    android:toYDelta="100%">
</translate>

top_to_current.xml

<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="-100%"
    android:toYDelta="0">
</translate>

当前页向右退出

这里写图片描述


current_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="100%"
    android:duration="500" >
</translate>
<!-- 要使用%,这样才有效果,反则没有效果,500ms不起作用 -->

left_to_current.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%"
    android:toXDelta="0"
    android:duration="500" >
</translate>
<!-- 要使用%,这样才有效果,反则没有效果,500ms不起作用 -->

当前页向左退出

这里写图片描述


current_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="-100%"
    android:duration="500" >
</translate>

right_to_current.xml

<?xml version="1.0" encoding="utf-8"?>
<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);
这里写图片描述

见图:

解决方法:不实用0,仍然使用动画,将退出动画设置透明度从1到1.
current_stay_alpha.xml

R.anim.current_stay_alpha

overridePendingTransition(R.anim.right_to_current,R.anim.current_stay_alpha);
<?xml version="1.0" encoding="utf-8"?>
<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);
<?xml version="1.0" encoding="utf-8"?>
<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)
<?xml version="1.0" encoding="utf-8"?>
<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)
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="500">
</rotate>

源码

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

点这里可以跳转到人工智能网站

0 0 投票数
文章评分
订阅评论
提醒
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请发表评论。x
()
x