文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android转场动画深入分析探究

2022-11-13 19:07

关注

早期的转场

最初,两个Activity之间的切换的过度动画,都是用overridePendingTransition。它只支持平移、缩放、透明度、旋转四种动画效果。

比如我们写个平移跳转动画,实现是这样的。首先,我们在资源文件anim下新建两个动画资源文件 enter_anim.xml 和 quit_anim.xml,分别表示进入和退出的动画。

enter_anim.xml

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

quit_anim.xml

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

然后在界面跳转的时候,调用overridePendingTransition就行啦

            startActivity(Intent(this, TestActivity::class.java))
            overridePendingTransition(R.anim.enter_anim, R.anim.quit_anim)

Material Design 转场动画

Android 5.0之后使用,具有三种转场动画效果:

Materia转场有两种启用方式,一种是在theme中设置 windowActivityTransitions

    <style name="Theme.AndroidApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="android:windowActivityTransitions">true</item>
    </style>

一种是通过代码开启

window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)

下面,通过一个简单的示例,来瞧瞧具体是怎么去使用的

在MainActivity中设置退出动画,然后通过点击事件去进行跳转到TestActivity

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        window.apply {
            requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
            exitTransition = Fade() //退出动画
        }
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.go.setOnClickListener {
            materialGo()
        }
    }
    private fun materialGo() {
        val intent = Intent(this, TestActivity::class.java)
        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
    }
}

在TestActivity中设置进入动画,这样淡入淡出式就完成了

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        window.run {
            requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
            enterTransition = Fade() //进入动画
        }
        super.onCreate(savedInstanceState)
        val binding = ActivityTestBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }
}

共享元素

如下所示,共享元素的效果很有趣,看着就像是图片从一个页面放大到另一个页面

共享元素过渡方式有四种

首先需要设置transitionName,告诉系统,哪个View需要做动画,然后进行Activity的跳转

        binding.image.setOnClickListener {
            binding.image.transitionName = "shared_elements"
            val options =
                ActivityOptions.makeSceneTransitionAnimation(this, binding.image, "shared_elements")
            val intent = Intent(this, TestActivity::class.java)
            startActivity(intent, options.toBundle())
        }

在目标Activity中给View设置transitionName,也可添加一系列的过渡效果

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val transitionSet = TransitionSet().apply {
            addTransition(ChangeBounds())
            addTransition(ChangeClipBounds())
            addTransition(ChangeTransform())
            addTransition(ChangeImageTransform())
        }
        with(window) {
            requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
            sharedElementEnterTransition = transitionSet
            sharedElementExitTransition = transitionSet
        }
        super.onCreate(savedInstanceState)
        val binding = ActivityTestBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.picture.transitionName = "shared_elements"
    }
}

如果要使用多个共享元素,可使用Pair,例如

            val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
                this, Pair(binding.imageView, "imageView"),
                Pair(binding.signature, "signature")
            )

Material Motion 动画

它提供了四种模式,可以根据需求灵活选用,分别是:

MaterialContainerTransform

用于包含容器的界面元素之间的过渡,通过将一个UI元素无缝转换为另一个UI元素,在两个不同的界面元素之间创造可视化的连接,跟之前共享元素动画最大的不同点在于它可以是一个 ViewGroup,也可以是一个 View。

下面,我们通过一个简单的例子来感受一下效果,item是个LinearLayout,用于点击跳转。

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        //1.启用转场动画
        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
        setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        initView()
    }
    private fun initView() {
        //2.设置transitionName
        binding.item.transitionName = "share"
        binding.item.setOnClickListener {
            //3.进行页面跳转
            startActivity(
                Intent(this, TestActivity::class.java),
                ActivityOptions.makeSceneTransitionAnimation(this, it, "share").toBundle()
            )
        }
    }
}

在目标Activity中,只显示了几行文本,整体用LinearLayout做容器,id为display。

这里为了更加清楚的看到动画的转换过程,我将动画的执行时间duration设置为2秒,实际开发中,不能搞这么久哦。

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        //1.启用转场动画
        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
        setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
        super.onCreate(savedInstanceState)
        val binding = ActivityTestBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //2.设置transitionName
        binding.display.transitionName = "share"
        //3.设置具体的动画
        window.sharedElementEnterTransition = MaterialContainerTransform().apply {
            addTarget(binding.display)
            scrimColor = Color.TRANSPARENT
            setAllContainerColors(Color.WHITE)
            duration = 2000L
        }
        window.sharedElementExitTransition = MaterialContainerTransform().apply {
            addTarget(binding.display)
            scrimColor = Color.TRANSPARENT
            setAllContainerColors(Color.WHITE)
            duration = 2000L
        }
    }
}

MaterialContainerTransform有两个属性需要注意下:

Shared axis

用于具有空间或导航关系的界面元素之间的过渡,让元素在转换时共用 x 轴、y 轴或 z 轴,用以强调元素间的关系。

在MainActivity中设置退出动画

        //启用转场动画
        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
        window.exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
            //指定转换视图
            addTarget(R.id.list)
            //转换不包含导航和状态栏
            excludeTarget(android.R.id.statusBarBackground, true)
            excludeTarget(android.R.id.navigationBarBackground, true)
        }

进行跳转

            startActivity(
                Intent(this, TestActivity::class.java),
                ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
            )

在TestActivity中设置进入动画

        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
        window.enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
            addTarget(R.id.display)
            excludeTarget(android.R.id.statusBarBackground, true)
            excludeTarget(android.R.id.navigationBarBackground, true)
        }

然后,我们来看一下转场效果

Fade Through

用于彼此之间没有密切关系的界面元素之间的过渡,使用依序淡出和淡入的效果,并会对转入的元素进行缩放,用法跟MaterialSharedAxis差不多。

        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
        window.enterTransition = MaterialFadeThrough().apply {
            addTarget(R.id.display)
            excludeTarget(android.R.id.statusBarBackground, true)
            excludeTarget(android.R.id.navigationBarBackground, true)
        }

Fade

用于进入或退出屏幕画面范围的界面元素。似乎效果上Fade 和上面的 Fade Through 差不多,其实确实都是透明度+缩放动画,但是官方建议,如果发生在同一个界面,例如在屏幕中心淡出的对话框。

这里为了更清楚的看清转场过程,将动画的执行时间duration设置为1000,实际开发中应设置小点,或者不用去设置

            val materialFade = MaterialFade().apply {
                duration = 1000L
            }
            TransitionManager.beginDelayedTransition(binding.list, materialFade)
            binding.detail.visibility = View.VISIBLE

总结

在Android 转场动画的发展中,早期的转场支持平移、缩放、透明度、旋转四种基础动画效果,随后,出现了Material Design 转场动画,给我们带来了共享元素动画效果,最后Material Motion 动画封装了四种动画,使得转场效果的实现更加容易。我觉得,页面之间的转场效果,可以赋予应用活力,丰富用户的使用体验,升华应用交互的灵魂,常言道,好看的皮囊千篇一律,有趣的灵魂万里挑一。

到此这篇关于Android转场动画深入分析探究的文章就介绍到这了,更多相关Android转场动画内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯