当前位置: 首页 > article >正文

Android 转场动画合集

项目背景:mvvm+组件化,然后由于领导要求,使用MainActivity为主界面,各种业务使用Fragment处理。所以~ 由于单独Activity+N Fragment 的方式,经过十多天的试错,我确认一件事情。再确认过架构方式后一定要了解下业务场景和使用技术栈。不然会导致身心俱疲——下一篇记录 组件化方式中使用 MainActivity + N Fragment方式怎么适配 组件化。

目录

1、界面转跳 转场动画;

方案一:使用 ARouter 自带 withTransition 设置转场动画。

方案二:使用ViewAnimationUtils 实现动画,配合addOnLayoutListener 监听 控制rootView显隐,达到视觉效果的转场。

方案三:使用Android官方推荐的共享元素方式

使用 FragmentTransaction 

使用 TransitionSet

使用 MaterialContainerTransform

2、Fragment add Fragment 动画不生效问题记录。


1、界面转跳 转场动画;

方案一:使用 ARouter 自带 withTransition 设置转场动画。

// 普通跳转
ARouter.getInstance().build("/test/activity")
        .withTransition(R.anim.slide_in_right, R.anim.slide_out_left) // 设置转场动画
        .navigation(this);

slide_in_right.xml

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

slide_out_left.xml

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

优点:实现简单,不用二次封装

缺点:无法实现复杂的动画。

方案二:使用ViewAnimationUtils 实现动画,配合addOnLayoutListener 监听 控制rootView显隐,达到视觉效果的转场。

转跳前可以获取按钮位置xy值

        binding.tvRouter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                
                int centerX = (v.getLeft() + v.getRight()) / 2;
                int centerY = (v.getTop() + v.getBottom()) / 2;

                LogUtils.e("centerX: " + centerX  );
                LogUtils.e("centerY: " + centerX  );
                ARouter.getInstance().build(RouterActivityPath.Login.PAGER_LOGIN)
                        .withInt("centerX", centerX)
                        .withInt("centerY", centerY)
                        .navigation(getActivity());
            }
        });

转跳界面:获取前页面传递过来xy值,设置一些想要的动画效果。

       centerX =getIntent().getIntExtra("centerX",0);
        centerX =getIntent().getIntExtra("centerY",0);

        binding.parent.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                binding.parent.removeOnLayoutChangeListener(this);
                float finalRadius = (float) Math.hypot(v.getWidth(), v.getHeight());
                CircularRevealUtil.startCircularReveal(v, centerX, centerY, 0, finalRadius);
            }
        });

CircularRevealUtil : 作了一个示例,圆形揭示

  /**
     * 开始圆形揭示动画
     *
     * @param view         要显示的视图
     * @param centerX      动画的中心X坐标
     * @param centerY      动画的中心Y坐标
     * @param startRadius  动画起始半径
     * @param endRadius    动画结束半径
     */
    public static void startCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) {
        Animator anim = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
        view.setVisibility(View.VISIBLE);
        anim.start();
    }

优点:可以定制复杂的转场动画

缺点:不易封装,实现难度,性能消耗等

方案三:使用Android官方推荐的共享元素方式

// 在第一个Activity中启动第二个Activity
Intent intent = new Intent(this, SecondActivity.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
    this,
    Pair.create(sharedView, "shared_element_transition")
);
startActivity(intent, options.toBundle());

在布局文件中,为共享元素设置 android:transitionName

<!-- activity_first.xml -->
<ImageView
    android:id="@+id/sharedView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sample_image"
    android:transitionName="shared_element_transition" />
<!-- activity_second.xml -->
<ImageView
    android:id="@+id/sharedView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sample_image"
    android:transitionName="shared_element_transition" />
使用 FragmentTransaction 

对于 Fragment 之间的共享元素动画,可以使用 FragmentTransaction 类来设置共享元素。

在第一个 Fragment 中启动第二个 Fragment

Fragment secondFragment = new SecondFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, secondFragment);
transaction.addToBackStack(null);
transaction.addSharedElement(sharedView, "shared_element_transition");
transaction.commit();

在布局文件中,为共享元素设置 android:transitionName

<!-- fragment_first.xml -->
<ImageView
    android:id="@+id/sharedView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sample_image"
    android:transitionName="shared_element_transition" />
<!-- fragment_second.xml -->
<ImageView
    android:id="@+id/sharedView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sample_image"
    android:transitionName="shared_element_transition" />
使用 TransitionSet

如果需要同时使用多种动画效果,可以使用 TransitionSet 来组合多个动画效果。

TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(new ChangeBounds());
transitionSet.addTransition(new ChangeTransform());
transitionSet.addTransition(new ChangeImageTransform());

getWindow().setSharedElementEnterTransition(transitionSet);
getWindow().setSharedElementReturnTransition(transitionSet);
使用 MaterialContainerTransform

MaterialContainerTransform 是 Android Material Design 提供的一个组件,可以用于容器转换动画,适用于 Activity 和 Fragment 之间的共享元素过渡。

FragmentTransaction transaction = getFragmentManager().beginTransaction();
MaterialContainerTransform transform = new MaterialContainerTransform();
transform.setDuration(300);
secondFragment.setSharedElementEnterTransition(transform);
transaction.addSharedElement(sharedView, "shared_element_transition");
transaction.replace(R.id.fragment_container, new SecondFragment());
transaction.addToBackStack(null);
transaction.commit();

在布局文件中,为共享元素设置 android:transitionName

<!-- fragment_first.xml -->
<View
    android:id="@+id/sharedView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:transitionName="shared_element_transition" />
<!-- fragment_second.xml -->
<View
    android:id="@+id/sharedView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:transitionName="shared_element_transition" />

2、Fragment add Fragment 动画不生效问题记录。

其实写这篇文章最重要的是想记录这个问题,我卡了一天。怀疑了FragmentTransaction封装,怀疑组件化结构。任何动画设置均不成功。最后看到自己布局里使用的Fragment容器。

       <androidx.fragment.app.FragmentContainerView
            android:id="@+id/main_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

FragmentContainerView 会导致 Fragment转场动画不生效。

FragmentContainerView 会导致 Fragment转场动画不生效。

FragmentContainerView 会导致 Fragment转场动画不生效。

重要的话说三遍


http://www.kler.cn/a/459638.html

相关文章:

  • 单片机串口控制
  • log4j2的Strategy、log4j2的DefaultRolloverStrategy、删除过期文件
  • Java-多种方法实现多线程计数
  • SQL—替换字符串—replace函数用法详解
  • 太通透了,Android 流程分析 蓝牙enable流程(stack/hidl)
  • torch.nn.GRU介绍
  • WebSocket 的封装使用
  • E卷-恢复数字序列(100分)
  • C语言程序设计:程序设计和C语言
  • 如何判断一个学术论文是否具有真正的科研价值?ChatGPT如何提供帮助?
  • 抽象工厂模式详解
  • 初识 Conda:一站式包管理和环境管理工具
  • Unity3D 基于GraphView实现的节点编辑器框架详解
  • es6 字符串每隔几个中间插入一个逗号
  • 【Cursor编辑器】自用经验和实操(迭代更新)
  • 【MySQL】搞懂mvcc、read view:MySQL事务原理深度剖析
  • Springboot配置文件加载顺序(含Nacos配置)
  • 自动驾驶第一股的转型迷途:图森未来赌上了AIGC
  • 论文阅读《Cross-scale multi-instance learning for pathological image diagnosis》
  • xtuoj 等式
  • python读写文件的三种做法
  • FPGA多路红外相机视频拼接输出,提供2套工程源码和技术支持
  • 【Leetcode 热题 100】17. 电话号码的字母组合
  • 【Golang 面试题】每日 3 题(九)
  • BLIP论文笔记
  • w124中药实验管理系统