Android Splash实现
1、创建Activity
package com.wsy.knowledge.ui.splashimport android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint
import android.os.Build
import android.os.Looper
import android.util.Log
import androidx.annotation.RequiresApi
import com.alibaba.android.arouter.facade.annotation.Route
import com.wsy.knowledge.common.arouter.ArouterUrl
import com.wsy.knowledge.common.ui.component.BaseActivity
import com.wsy.knowledge.databinding.ActivityNativeSplashBinding
import com.wsy.knowledge.ui.homepage.HomePageActivity@SuppressLint("CustomSplashScreen")
@Route(path = ArouterUrl.native_splash)
class NativeSplashActivity : BaseActivity() {private lateinit var binding: ActivityNativeSplashBindingoverride fun getLayoutId() {binding = ActivityNativeSplashBinding.inflate(layoutInflater)setContentView(binding.root)}override fun initData() {}@RequiresApi(Build.VERSION_CODES.O)override fun init() {setFAFStatusBar()binding.animLogo.apply {addOffsetAnimListener(object : AnimatorListenerAdapter() {override fun onAnimationEnd(animation: Animator) {Log.d("AnimLogoView", "Offset anim end")}})addGradientAnimListener(object : AnimatorListenerAdapter() {override fun onAnimationEnd(animation: Animator) {Log.d("AnimLogoView", "Gradient anim end")startActivity(HomePageActivity::class.java, true)}})}Looper.myQueue().addIdleHandler {binding.animLogo.startAnimation()false}}}
2、XML文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ui.splash.NativeSplashActivity"android:background="@color/blue_2A6FAF"tools:ignore="MissingDefaultResource"><com.wsy.knowledge.common.ui.view.AnimationLogoViewandroid:id="@+id/anim_logo"android:layout_width="match_parent"android:layout_height="@dimen/sp_200"app:layout_constraintTop_toBottomOf="@+id/splashImg"app:autoPlay="false"app:gradientAnimDuration="2000"app:gradientColor="@color/blue_2A6FAF"app:logoName="@string/app_name"app:offsetAnimDuration="2000"app:showGradient="true"app:textColor="@color/white"app:textPadding="3dp"app:textSize="@dimen/sp_40"/><ImageViewandroid:id="@+id/splashImg"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginBottom="@dimen/sp_200"android:src="@drawable/launch_second"android:layout_marginTop="@dimen/sp_200"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewapp:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:layout_marginBottom="@dimen/sp_20"android:text="@string/search_service"android:textSize="@dimen/sp_14"android:textColor="@color/color_999"android:gravity="center"android:layout_width="match_parent"android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
3、AnimationLogoView
package com.wsy.knowledge.common.ui.viewimport android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.PointFEvaluator
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.util.SparseArray
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import com.wsy.knowledge.Rclass AnimationLogoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {private val mLogoTexts = SparseArray<String>()private val mQuietPoints = SparseArray<PointF>()private val mRandomPoints = SparseArray<PointF>()private var mOffsetAnimator: ValueAnimator? = nullprivate var mGradientAnimator: ValueAnimator? = nullprivate var mPaint: Paint? = nullprivate var mTextPadding: Intprivate var mTextColor: Intprivate var mTextSize: Floatprivate var mOffsetAnimProgress = 0fprivate var mOffsetDuration: Intprivate var isOffsetAnimEnd = falseprivate var mGradientDuration: Intprivate var mLinearGradient: LinearGradient? = nullprivate var mGradientColor: Intprivate var mGradientMatrix: Matrix? = nullprivate var mMatrixTranslate = 0private val isAutoPlay: Booleanprivate var mWidth = 0private var mHeight = 0private var isShowGradient: Booleanprivate val mLogoOffset: Intprivate var mGradientListener: Animator.AnimatorListener? = nullcompanion object {private const val DEFAULT_LOGO = "Animation"private const val DEFAULT_TEXT_PADDING = 10private const val ANIM_LOGO_DURATION = 1500private const val ANIM_LOGO_GRADIENT_DURATION = 1500private const val ANIM_LOGO_TEXT_SIZE = 30fprivate const val ANIM_LOGO_TEXT_COLOR = Color.BLACKprivate const val ANIM_LOGO_GRADIENT_COLOR = Color.YELLOW}init {val ta = context.obtainStyledAttributes(attrs, R.styleable.AnimationLogoView)var logoName = ta.getString(R.styleable.AnimationLogoView_logoName)isAutoPlay = ta.getBoolean(R.styleable.AnimationLogoView_autoPlay, true)isShowGradient = ta.getBoolean(R.styleable.AnimationLogoView_showGradient, false)mOffsetDuration = ta.getInt(R.styleable.AnimationLogoView_offsetAnimDuration, ANIM_LOGO_DURATION)mGradientDuration = ta.getInt(R.styleable.AnimationLogoView_gradientAnimDuration, ANIM_LOGO_GRADIENT_DURATION)mTextColor = ta.getColor(R.styleable.AnimationLogoView_textColor, ANIM_LOGO_TEXT_COLOR)mGradientColor = ta.getColor(R.styleable.AnimationLogoView_gradientColor, ANIM_LOGO_GRADIENT_COLOR)mTextPadding = ta.getDimensionPixelSize(R.styleable.AnimationLogoView_textPadding, DEFAULT_TEXT_PADDING)mTextSize = ta.getDimension(R.styleable.AnimationLogoView_textSize, ANIM_LOGO_TEXT_SIZE)mLogoOffset = ta.getDimensionPixelOffset(R.styleable.AnimationLogoView_verticalOffset, 0)ta.recycle()if (TextUtils.isEmpty(logoName)) {logoName = DEFAULT_LOGO}fillLogoTextArray(logoName)initPaint()initOffsetAnimation()}private fun fillLogoTextArray(logoName: String?) {if (TextUtils.isEmpty(logoName)) {return}if (mLogoTexts.size() > 0) {mLogoTexts.clear()}for (i in logoName!!.indices) {mLogoTexts.put(i, logoName[i].toString())}}private fun initPaint() {mPaint=Paint().apply {isAntiAlias = truestyle = Paint.Style.FILLtextSize = mTextSizecolor = mTextColor}}private fun initOffsetAnimation() {if (mOffsetAnimator == null) {mOffsetAnimator = ValueAnimator.ofFloat(0f, 1f).apply {interpolator = AccelerateDecelerateInterpolator()addUpdateListener(AnimatorUpdateListener { animation ->if (mQuietPoints.size() <= 0 || mRandomPoints.size() <= 0) {return@AnimatorUpdateListener}mOffsetAnimProgress = animation.animatedValue as Floatinvalidate()})addListener(object : AnimatorListenerAdapter() {override fun onAnimationEnd(animation: Animator) {if (mGradientAnimator != null && isShowGradient) {isOffsetAnimEnd = truemPaint?.shader = mLinearGradientmGradientAnimator!!.start()}}})duration = mOffsetDuration.toLong()}}}override fun onAttachedToWindow() {super.onAttachedToWindow()if (visibility == VISIBLE && isAutoPlay) {mOffsetAnimator?.start()}}override fun onDetachedFromWindow() {if (mOffsetAnimator != null && mOffsetAnimator!!.isRunning) {mOffsetAnimator!!.cancel()}if (mGradientAnimator != null && mGradientAnimator!!.isRunning) {mGradientAnimator!!.cancel()}super.onDetachedFromWindow()}fun addOffsetAnimListener(listener: Animator.AnimatorListener?) {mOffsetAnimator!!.addListener(listener)}fun addGradientAnimListener(listener: Animator.AnimatorListener?) {mGradientListener = listener}/*** 开启动画*/fun startAnimation() {if (visibility == VISIBLE) {if (mOffsetAnimator!!.isRunning) {mOffsetAnimator!!.cancel()}isOffsetAnimEnd = falsemOffsetAnimator!!.start()} else {Log.w("AnimLogoView", "The view is not visible, not to play the animation .")}}override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {super.onSizeChanged(w, h, oldw, oldh)mWidth = wmHeight = hinitLogoCoordinate()initGradientAnimation()}private fun initLogoCoordinate() {if (mWidth == 0 || mHeight == 0) {return}val fontMetrics = mPaint!!.fontMetricsval baseY = mHeight / 2 - fontMetrics.top / 2 - fontMetrics.bottom / 2val centerY = baseY + mLogoOffsetvar totalLength = 0ffor (i in 0 until mLogoTexts.size()) {val str = mLogoTexts[i]val currentLength = mPaint!!.measureText(str)totalLength += if (i != mLogoTexts.size() - 1) {currentLength + mTextPadding} else {currentLength}}check(totalLength <= mWidth) { "The text of logoName is too large that this view can not display all text" }var startX = (mWidth - totalLength) / 2if (mQuietPoints.size() > 0) {mQuietPoints.clear()}for (i in 0 until mLogoTexts.size()) {val str = mLogoTexts[i]val currentLength = mPaint!!.measureText(str)mQuietPoints.put(i, PointF(startX, centerY))startX += currentLength + mTextPadding}if (mRandomPoints.size() > 0) {mRandomPoints.clear()}for (i in 0 until mLogoTexts.size()) {mRandomPoints.put(i, PointF(Math.random().toFloat() * mWidth, Math.random().toFloat() * mHeight))}}private fun initGradientAnimation() {if (mWidth == 0 || mHeight == 0) {return}if (mGradientAnimator == null) {mGradientAnimator = ValueAnimator.ofInt(0, 2 * mWidth).apply {if (mGradientListener != null) {addListener(mGradientListener)}addUpdateListener { animation ->mMatrixTranslate = animation.animatedValue as Intinvalidate()}mLinearGradient = LinearGradient(-mWidth.toFloat(), 0f, 0f, 0f, intArrayOf(mTextColor, mGradientColor, mTextColor), floatArrayOf(0f, 0.5f, 1f), Shader.TileMode.CLAMP)mGradientMatrix = Matrix()duration = mGradientDuration.toLong()}}}@SuppressLint("DrawAllocation")override fun onDraw(canvas: Canvas) {if (!isOffsetAnimEnd) {mPaint!!.alpha = 255f.coerceAtMost(255 * mOffsetAnimProgress + 100).toInt()for (i in 0 until mQuietPoints.size()) {val point=PointFEvaluator().evaluate(mOffsetAnimProgress,mRandomPoints[i],mQuietPoints[i])canvas.drawText(mLogoTexts[i],point.x, point.y, mPaint!!)}} else {for (i in 0 until mQuietPoints.size()) {val quietP = mQuietPoints[i]canvas.drawText(mLogoTexts[i], quietP.x, quietP.y, mPaint!!)}mGradientMatrix!!.setTranslate(mMatrixTranslate.toFloat(), 0f)mLinearGradient!!.setLocalMatrix(mGradientMatrix)}}}
相关文章:
Android Splash实现
1、创建Activity package com.wsy.knowledge.ui.splashimport android.animation.Animator import android.animation.AnimatorListenerAdapter import android.annotation.SuppressLint import android.os.Build import android.os.Looper import android.util.Log import an…...

FPGA projet : VGA
在vga屏幕上显示 : 野火科技 相比于上个工程,只需要修改 vga_pix 模块即可。 注意存储器类型变量的定义:reg 【宽度】<名称>【深度】 赋值 always (poseedge vga_clk)begin 为每一行赋值,不可位赋…...

JDK8 升级至JDK19
优质博文IT-BLOG-CN 目前部分项目使用JDK8,部分项目使用JDK19因此,环境变量中还是保持JDK8,只需要下载JDK19免安装版本,通过配置IDEA就可以完成本地开发。 一、IDEA 环境设置 【1】通过快捷键CTRL SHIFT ALT S或者File->P…...

Python3.10 IDLE更换主题
前言 自定义主题网上有很多,3.10IDLE的UI有一些新的东西,直接扣过来会有些地方覆盖不到,需要自己测试着添几行配置,以下做个记录。 配置文件路径 Python安装目录下的Lib\idlelib\config-highlight.def。如果是默认安装…...

C# OpenVino Yolov8 Pose 姿态识别
效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp;namespace OpenVino_Yolov8_Demo {public…...

北邮22级信通院数电:Verilog-FPGA(1)实验一“跑通第一个例程” 过程中遇到的常见问题与解决方案汇总(持续更新中)
北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 问题一:Verilog代码没有跑通 报…...

CSS - 鼠标移入整行高亮显示,适用于会员套餐各参数对比页面(display: table,div 转表格形式)
效果图 可根据基础示例和进阶示例,复制进行改造样式。 如下图所示,本文提供 2 个示例。 基础示例 找个 HTML 页面,一键复制运行。 <body><h1 style"text-align: center;">基础示例</h1><section class"…...

无涯教程-JavaScript - ATAN2函数
描述 The ATAN2 function returns the arctangent, or inverse tangent, of the specified x- and ycoordinates, in radians, between -π/2 and π/2. 语法 ATAN2 (x_num, y_num)争论 Argument描述Required/OptionalX_numThe x-coordinate of the point.RequiredY_numThe…...

Tomcat 下部署 jFinal
1、检查web.xml 配置,在 tomcat 下部署需要检查 web.xml 是否存在,并且要确保配置正确,配置格式如下。 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…...

【Spatial-Temporal Action Localization(二)】论文阅读2017年
文章目录 1. ActionVLAD: Learning spatio-temporal aggregation for action classification [code](https://github.com/rohitgirdhar/ActionVLAD/)[](https://github.com/rohitgirdhar/ActionVLAD/)摘要和结论引言:针对痛点和贡献相关工作模型框架思考不足之处 2.…...

二维码智慧门牌管理系统:数据现势性,满足应用需求的根本保证
文章目录 前言一、项目背景二、数据的现势性三、系统的优势四、应用前景 前言 在当今信息化社会,数据的重要性日益凸显,尤其是数据的现势性,它决定着服务的质量和满足应用需求的能力。近日,一个创新的二维码智慧门牌管理系统项目…...

BF算法(C++)简单讲解
BF算法匹配过程易理解,若匹配,子串和主串都往下移一位。不匹配时,主串回溯至本次匹配开始下标的下一位。例:图中第三趟匹配时,主串到第七位时与子串不匹配,这次匹配主串是从第三位开始的,所以下…...

JVM 虚拟机 ----> Java 类加载机制
文章目录 JVM 虚拟机 ----> Java 类加载机制一、概述二、类的生命周期1、类加载过程(Loading)(1)加载(2)验证(3)准备(4)解析(5)初始…...

《protobuf》基础语法2
文章目录 枚举类型ANY 类型oneof 类型map 类型改进通讯录实例 枚举类型 protobuf里有枚举类型,定义如下 enum PhoneType {string home_addr 0;string work_addr 1; }同message一样,可分为 嵌套定义,文件内定义,文件外定义。不…...

利用 SOAR 加快事件响应并加强网络安全
随着攻击面的扩大和攻击变得越来越复杂,与网络攻击者的斗争重担落在了安全运营中心 (SOC) 身上。SOC 可以通过利用安全编排、自动化和响应 (SOAR) 平台来加强组织的安全态势。这一系列兼容的以安全为中心的软件可加快事…...

uni-app:通过ECharts实现数据可视化-如何引入项目
效果 引入文件位置 代码 <template><view id"myChart"></view> </template> <script> import echarts from /static/js/echarts.js // 引入文件 export default {mounted() {// 初始化EChartsconst myChart echarts.init(document…...
string 模拟与用法
string 用法 string string 模拟 #pragma once #include <assert.h> #include <string.h> #include <iostream>namespace sjy {class string{public://迭代器相关typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _st…...

[NLP] LLM---<训练中文LLama2(一)>训练一个中文LLama2的步骤
一 数据集 【Awesome-Chinese-LLM中文数据集】 【awesome-instruction-dataset】【awesome-instruction-datasets】【LLaMA-Efficient-Tuning-数据集】Wiki中文百科(25w词条)wikipedia-cn-20230720-filteredBaiduBaiKe(563w词条) …...

华为云云耀云服务器L实例使用教学 | 利用华为云服务器搭建--> 基于Spring Boot+WebSocket+WebRtc实现的多人自习室
文章目录 1. 购买华为云服务器L2. 在华为云服务器上搭建项目前期准备工作1. 更换登录密码2. 安全组配置 3. 在服务器上运行自己的项目 1. 购买华为云服务器L 在有优惠券的情况下,来到华为云这个网址下面,链接为:https://www.huaweicloud.com…...

Postman应用——接口请求(Get和Post请求)
文章目录 新增请求接口请求Get接口请求Post 这里只讲用的比较多的Get和Post请求方式,也可以遵循restful api接口规范,使用其他请求方式。 GET(SELECT):从服务器取出资源(一项或多项)POST&#…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...