使用MotionLayout 实现启动页动画 Splash

2023-11-04

效果图

capture.gif

项目地址

具体代码实现

activity_splash.xml

<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/_splashMotion"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical"
    app:layoutDescription="@xml/activity_motion_scene">

    <ImageView
        android:id="@+id/main_image2"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:src="@drawable/ic_sun"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="ContentDescription" />
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/aplashTv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:lineSpacingExtra="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="" />


    <TextView
        android:id="@+id/app_name_by"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="12dp"
        android:text="@string/app_name_by "
        android:textColor="#dd000000"
        app:layout_goneMarginBottom="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textSize="14sp"/>

</androidx.constraintlayout.motion.widget.MotionLayout>

xml/activity_motion_scene/xml

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="4000"
        motion:motionInterpolator="easeInOut">
        <OnClick
            motion:clickAction="toggle"
            motion:targetId="@id/main_image2"
            motion:dragDirection="dragRight" />
        <KeyFrameSet>
            <KeyTimeCycle
                motion:motionTarget="@id/main_image2"
                motion:motionProgress="60"
                motion:framePosition="50"
                motion:wavePeriod="43"
                motion:waveShape="sawtooth"
                motion:waveOffset="60"
                />
            <KeyPosition
                motion:framePosition="10"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/main_image2"
                motion:pathMotionArc="startHorizontal"
                motion:curveFit="spline"
                motion:percentX="2"
                motion:percentY="0" />
            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="pathRelative"
                motion:motionTarget="@id/main_image2"
                motion:pathMotionArc="flip"
                motion:curveFit="spline"
                motion:percentX="1.6"
                motion:percentY="0.55"/>
            <KeyPosition
                motion:framePosition="85"
                motion:keyPositionType="pathRelative"
                motion:motionTarget="@id/main_image2"
                motion:pathMotionArc="flip"
                motion:curveFit="spline"
                motion:percentX="1.3"
                motion:percentY="-0.65"/>
            <KeyAttribute
                motion:motionTarget="@id/main_image2"
                motion:framePosition="30"
                android:rotationX="50"
                android:rotationY="50"/>

        </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start">

        <Constraint
            android:id="@+id/main_image2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:alpha="0"
            motion:drawPath="path"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@+id/app_name_by"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:alpha="0"
            motion:drawPath="path"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toRightOf="parent"  />

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/main_image2"
            android:layout_width="50dp"
            android:layout_height="50dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent"  />
        <Constraint
            android:id="@+id/app_name_by"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="60dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toRightOf="parent"   />

    </ConstraintSet>

</MotionScene>

SplashActivity

package com.e9ab98e991ab.motionsplash

import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.motion.widget.MotionLayout
import kotlinx.android.synthetic.main.activity_splash.*

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        }
        main_image2.post {
            main_image2.performClick()
        }
        _splashMotion.setTransitionListener(object : MotionLayout.TransitionListener {
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
            }

            override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
                startActivity(Intent(this@SplashActivity, MainActivity::class.java))
                overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
                this@SplashActivity.finish()
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {
            }
        })
    }
}

实现原理

第一步:SplashActivity 中使用MotionLayout (id: _splashMotion)添加 ImageView (id: main_image2)

第二步:MotionScene->Transition添加 如下事件监听 并在MotionScene 布局中调整动画角度。

<OnClick
    motion:clickAction="toggle"
    motion:targetId="@id/main_image2"
    motion:dragDirection="dragRight" />

第三步 SplashActivity 中 执行 performClick()开始执行动画

main_image2.post {
    main_image2.performClick()
}

第四步 在SplashActivity(id: _splashMotion) 设置动画监听

_splashMotion.setTransitionListener(object : MotionLayout.TransitionListener {
	//开始时
    override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
    }

    override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
    }
	//结束
    override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
        startActivity(Intent(this@SplashActivity, MainActivity::class.java))
        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
        this@SplashActivity.finish()
    }

    override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {
    }
})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用MotionLayout 实现启动页动画 Splash 的相关文章

随机推荐

  • 关于ARM_math数学库的使用

    关于ARM math数学库的使用 ARM math好强大的好吧 话不多说 请看截图 各种数学库看到没有 好强大的说 其实使用这些写函数 最快上手的方法就是看官方手册 话不多说 上官方链接arm math库的官网 举个栗子 一般步骤 1 首先
  • STM32 GPIO 8种输入输出

    STM32 GPIO 8种输入输出 输入 浮空输入 上拉输入 下拉输入 模拟输入 输出 开漏输出 复用开漏输出 推挽输出 复用推挽输出 总结 参考 输入 1 浮空输入 GPIO Mode IN FLOATING 2 上拉输入 GPIO Mo
  • Ubuntu:C++远程连接Mysql

    1 安装mysql sudo apt get install update sudo apt get install mysql server libmysqlclient dev 2 登录mysql并进行配置 sudo mysql u r
  • 启动其他APK的Activity方法

    启动其他APK的Activity方法 有两个app 分别叫做App1和App2 App1包含两个Activity 分别叫做App1 A和App1 B 其中App1 A是入口Activity 也就是App1 A设置intent filter
  • .NET 5.0发布,你的代码保护工具还够用吗?

    NET是程序员比较钟爱的一款编程工具 但它有一个致命的缺点 编译好的程序集很容易反编译成源代码 一旦被反编译 软件开发者的辛苦劳动将付诸东流 选择一款合格的 NET保护工具是非常重要的 如今 NET 5 0已经发布 你是如何评价的呢 无论怎
  • 【教程汇总】如何选择合适的坐标系及投影

    总结 considerations for choosing the coordinate system map purpose map extent map orientation latitude range national coor
  • QC11 premier Edition 安装注意事项

    安装环境 Windows Server 2003 SQLServer 2005 系统环境需求可查看 https h10078 www1 hp com cda hpms display main hpms content jsp zn bto
  • 深圳拟重点扶持12大数字经济产业:区块链、金融科技在列

    伴随着数字经济的高速增长 深圳市数字经济产业发展迎来政策春风 近日 深圳市工业和信息化局发布了关于公开征求 深圳市数字经济产业创新发展实施方案 征求意见稿 下称 实施方案 意见的通告 表示将努力建成全国领先 全球一流的数字经济产业创新发展引
  • OpenCV—基本数据结构与示例

    https blog csdn net iracer article details 51292349 OpenCV中强大的Mat类型大家已经比较熟悉了 这里梳理一些在工程中其他经常用到的几种基本数据类型 包括 Vec Scalar Poi
  • MSP430F5529输出PWM

    msp430f5529产生4路PWM波 改变占空比从而改变电机 直流减速电机 的速度 驱动电机必然会用到驱动模块 接下来就介绍一下驱动模块 L298N L298N驱动 若要对直流电机进行PWM调速 需设置IN1和IN2 即确定电机的转动方向
  • Java集合-List

    一 List集合概述 java util List接口继承自Collection接口 是单列集合的一个重要分支 习惯性地会将实现了List接口的对象称为List集合 在List集合中允许出现重复的元素 所有的元素是以一种线性方式进行存储的
  • ic卡校验码计算软件_CRC校验码简介及CRC16的计算方法

    点击上方 嵌入式从0到1 选择 置顶 星标公众号 干货福利 第一时间送达 什么是CRC校验 CRC即循环冗余校验码 Cyclic Redundancy Check 是数据通信领域中最常用的一种查错校验码 其特征是信息字段和校验字段的长度可以
  • 法师康的工人--计蒜客

    三个法师康的工人每天早上6点到工厂开始到三条产品生产线上组装桔子手机 第一个工人在200时刻开始 从6点开始计时 以秒作为单位 在生产线上开始生产 一直到1000时刻 第二个工人 在700时刻开始 在1100时刻结束 第三个工人从1500时
  • 在Docker上用3个Nacos1.3容器+一个MySQL5和8容器+一个Nginx容器进行集群的具体操作(Nacos集群版)

    在Docker上用Nacos1 3容器连接MySQL5 6和8 0 18容器进入持久化的具体操作 Nacos单机版 这里直接在linux中启动三个Nacos容器 文章目录 3个Nacos1 3容器 一个MySQL5 6容器 一个Nginx容
  • pytest---usefixtures简单使用

    前面介绍的fixture都是通过函数的方式进行传参的 如果遇到一个class中都需要传入一个fixture 那一个个写进函数中 太麻烦 今天安静介绍一种方法 通过class直接传入fixture usefixtures usefixture
  • 报错解决:pandas的依赖项openpyxl

    问题 使用pandas包 没有使用openpyxl包 但是报错 ImportError Missing optional dependency openpyxl Use pip or conda to install openpyxl 翻译
  • 使用@ConfigurationProperties映射配置项到实体类

    1 创建配置文件 七牛云相关 qiniu accessKey accessKey secretKey secretKey CDN加速域名前缀 cdnDomainPrefix cdnDomainPrefix 2 添加映射配置 项目添加相关依赖
  • Nginx安全控制

    安全隔离 通过代理分开了客户端到应用程序服务器端的连接 实现了安全措施 在反向代理之前设置防火墙 仅留一个入口供代理服务器访问 使用SSL对流量进行加密 常用的http请求转变成https请求 因为http协议是明文传输数据 存在安全问题
  • Java堆、栈和常量池以及相关String的详细讲解(经典中的经典)

    一 在JAVA中 有六个不同的地方可以存储数据 寄存器 register 这是最快的存储区 因为它位于不同于其他存储区的地方 处理器内部 但是寄存器的数量极其有限 所以寄存器由编译器根据需求进行分配 你不能直接控制 也不能在程序中感觉到寄存
  • 使用MotionLayout 实现启动页动画 Splash

    效果图 项目地址 具体代码实现 activity splash xml