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&#…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...