欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android动画学习(七)之转场动画

程序员文章站 2024-03-25 23:47:22
...

Android动画学习(七)之转场动画

概述

Android 中的转场动画用于处理视图怎么进入和退出屏幕。

Android5.0之前的转场动画

概述:
在Android 5.0以前实现转场动画是通过补间动画来实现。通常的Activity跳转是从界面下方进入的,传统的转场动画可设置从左边或右边进入。Activity中调用overridePendingTransition(int enterAnim, int exitAnim)方法,来设置界面切换。enterAnim和exitAnim两个参数对应的是两个View动画。
使用
从右边进入左边退出:
主转场java代码:

public void oldSpecial(View v) {
        startActivity(new Intent(this, SpecialActivity.class));
        overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
    }

slide_right_in.xml(enterAnim)

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

slide_left_out.xml(exitAnim)

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

测试转场Java代码:

 public void backToActivity(View view) {
        this.finish();
        overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
    }

slide_left_in.xml(enterAnim)

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

slide_right_out.xml(exitAnim)

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

只要修改上述进入的overridePendingTransition中进入与退出方向,可以实现左边进入左边退出、右边进入右边退出、从左边进入右边退出等效果
测试效果:
Android动画学习(七)之转场动画

Android5.0之后的转场动画

Android 5.0之后,谷歌引入了 Activity Transition 来实现交互更加友好的转场动画效果。传统的转场动画只能作用于整个页面,不能对页面中的单个元素做控制,而5.0新转场动画可以控制页面中的每个元素。
Tansition的类型共有三种:
进入 —— 决定Activity中的所有视图怎么进入屏幕
退出 —— 决定Activity中的所有视图怎么退出屏幕
共享元素 —— 决定两个Activity之间的过渡时怎么共享它们的视图

进入和退出包含如下动画效果:
explode(分解) —— 从屏幕中间进或出
slide(滑动) —— 从屏幕边缘进或出地
fade(淡出) —— 改变屏幕上视图的不透明度实现添加或移除视图的效果

共享元素包含如下动画效果:
changeBounds —— 改变目标视图的布局边界
changeClipBounds —— 裁剪目标视图边界
changeTransform —— 改变目标视图的缩放比例和旋转角度
changeImageTransform —— 改变目标图片的大小和缩放比例

Explode

代码效果:
下一个页面的元素从四面八方进入,最终形成完整的页面。

 public void Explode(View v) {//Explode的效果是下一个页面的元素从四面八方进入,最终形成完整的页面
        Intent intent = new Intent(this, SpecialTestActivity.class);
        intent.putExtra("flag", 0);
        /*
        在跳转时就要注意一点,intent后面还要再传一个参数bundle,
        固定写法ActivityOptions.makeSceneTransitionAnimation(this).toBundle(),
        下一个Activity根据这个就能识别出使用5.0新转场动画
         */
        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

    }

Slide

代码效果:
下一个页面元素从底部依次向上运动,最终形成完整的页面

 public void Slide(View v) {//Slide就是下一个页面元素从底部依次向上运动,最终形成完整的页面
        Intent intent = new Intent(this, SpecialTestActivity.class);
        intent.putExtra("flag", 1);
        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    }

Fade

代码效果:
下一个页面元素渐变出现,最终形成完整的页面

 public void Fade(View v) {//Fade就是下一个页面元素渐变出现,最终形成完整的页面
        Intent intent = new Intent(this, SpecialTestActivity.class);
        intent.putExtra("flag", 2);
        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    }

Share

Share是共享元素,是比较最复杂的一种转场方式,在跳转的两个Activity之间,如果有相同的View元素,那么,两个元素就可以设置成共享状态,在跳转时,这个View就会从第一个Activity的显示状态过渡到第二个Activity的显示状态,给用户的感觉仿佛是两个Activity共享一个View。

 public void Share(View v) {
        // 跳转时,要为每一个共享的view设置对应的transitionName
        View fab = findViewById(R.id.fab_button);
        View txName = findViewById(R.id.tx_user_name);
        Intent intent = new Intent(this, SpecialTestActivity.class);
        intent.putExtra("flag", 3);
        //创建单个共享元素
//        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle());
        //创建多个共享单元
        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,
                Pair.create(v, "share"),
                Pair.create(fab, "fab"),
                Pair.create(txName, "user_name"))
                .toBundle());


    }

可以发现,以上四种转场在切换时几乎一模一样,都是在 startActivity时加入ActivityOptions.makeSceneTransitionAnimation(this).toBundle(),主要的区别在测试的Activity。测试Activity中onCreate下通过

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

设置视图进入退出方向。不过share与其他集中不同。只需要设置

 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

测试的Activity:

public class SpecialTestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int flag = getIntent().getExtras().getInt("flag");
        switch (flag) {
            case 0:
                getWindow().setEnterTransition(new Explode());
                getWindow().setExitTransition(new Explode());
                break;
            case 1:
                getWindow().setEnterTransition(new Slide());
                getWindow().setExitTransition(new Slide());
                break;
            case 2:
                getWindow().setEnterTransition(new Fade());
                getWindow().setExitTransition(new Fade());
                break;
            case 3:
                getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
                break;
            default:
                break;
        }
        setContentView(R.layout.activity_ca);

    }
    public void backToActivity(View view) {
        this.finish();
        overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
    }

Explode的效果:
Android动画学习(七)之转场动画
Slide的效果:
Android动画学习(七)之转场动画
Fade的效果:
Android动画学习(七)之转场动画
Share的效果:
Android动画学习(七)之转场动画

Share的经典应用-新闻列表页跳详情页

在share类中有一个经典应用,就是新闻列表页跳详情页,通常列表页和详情页都会包含相同View元素,使用Share转场给人一种连续过渡效果,非常酷炫。
代码:

/**
*  5.0新的转场动画  Share的典型应用
*@author ZD
*created at 2017/7/14 16:19
*description:
*/
public class ShareListActivity extends AppCompatActivity implements RVAdapter.RVClickListener {
    RecyclerView rv;

    List<RVBean> beans;

    RVAdapter rvAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_share_list);
        init();
    }
    private void init() {
        rv = (RecyclerView)findViewById(R.id.rv);
        rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

        beans = new ArrayList<>();
        beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
        beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
        beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
        beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
        beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));

        beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
        beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
        beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
        beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
        beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));

        beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
        beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
        beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
        beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
        beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));

        beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
        beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
        beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
        beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
        beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));

        rvAdapter = new RVAdapter(this, beans);
        rv.setAdapter(rvAdapter);

        rvAdapter.setListener(this);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onItemClick(int position) {
        RVBean bean = beans.get(position);

        Intent intent = new Intent(ShareListActivity.this, ShareListDetailActivity.class);
        intent.putExtra("resId", bean.getResId());
        intent.putExtra("name", bean.getName());
        intent.putExtra("desc", bean.getDesc());

        int firstVisiblePosition = ((LinearLayoutManager)rv.getLayoutManager()).findFirstVisibleItemPosition();

        View itemView = rv.getChildAt(position - firstVisiblePosition);
        View headImage = itemView.findViewById(R.id.head_image);
        View name = itemView.findViewById(R.id.name);
        View desc = itemView.findViewById(R.id.desc);

        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,
                Pair.create(headImage, "headImage"),
                Pair.create(name, "name"),
                Pair.create(desc, "desc"))
                .toBundle());
    }

代码效果:
Android动画学习(七)之转场动画

总结

Activity转场动画非常简单,通过加入代码和动画实现设定界面切换时进入退出的方向。
写博客是为了帮助开发者学习使用技术,同时巩固自己所学技术。如果此篇博客有助于您的学习,那是我的荣幸!如果此篇博客有任何瑕疵,请多多指教!在此感谢您的学习和指教!