前言
- 在新闻网站、广告展示、公告栏等多种场景中都广泛的应用【跑马灯】特效。页面滚动显示信息可以增加用户关注度。
在一次大型演唱会台上,看到很多粉迷使用手机展示字幕,很有吸引力的炫彩字幕跑马灯效果,于是突发连想,在近期业余期开发了此类 Apk,实现三种效果,可参考如下具体完整代码示例
- 项目工程主要目录文件结构图:
1. 创建一个项目
项目名称示例:HelloWorld-01
默认项目包名:com.example.myapplication
- 主程序 (默认创建):src/main/java/MainActivity.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private Button btnWeb, btnWeb1, btnWeb2;
private TextView tvCornerText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 使用沉浸式模式,全屏显示界面,不知道啥原因,设置了部分机型上还是无效
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
btnWeb = findViewById(R.id.btn_web);
btnWeb1 = findViewById(R.id.btn_web1);
btnWeb2 = findViewById(R.id.btn_web2);
webView = findViewById(R.id.webView);
tvCornerText = findViewById(R.id.tv_corner_text);
// 设置 WebViewClient 以确保内容在 WebView 中加载
webView.setWebViewClient(new WebViewClient());
btnWeb.setOnClickListener(v -> showWebView("file:///android_asset/webpage.html")); // 固定
btnWeb1.setOnClickListener(v -> showWebView("file:///android_asset/marquee.html"));
btnWeb2.setOnClickListener(v -> showWebView("file:///android_asset/marquee1.html"));
}
private void showWebView(String url) {
// 隐藏按钮,显示 WebView
btnWeb.setVisibility(View.GONE);
btnWeb1.setVisibility(View.GONE);
btnWeb2.setVisibility(View.GONE);
tvCornerText.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
// 加载 URL
webView.loadUrl(url);
}
@Override
protected void onResume() {
super.onResume();
// 每次返回 Activity 时重置回到默认主界面
resetToDefaultState();
}
private void resetToDefaultState() {
// 确保 WebView 是隐藏的,按钮是显示的
webView.setVisibility(View.GONE);
btnWeb.setVisibility(View.VISIBLE);
btnWeb1.setVisibility(View.VISIBLE);
btnWeb2.setVisibility(View.VISIBLE);
tvCornerText.setVisibility(View.VISIBLE);
// 如果需要,可以在这里停止 WebView 的加载或清除历史记录
webView.stopLoading();
webView.clearHistory();
webView.clearCache(true);
}
}
- 跳转 HTML 界面 (需手动创建):src/main/assets
在 main 目录下创建一个文件夹命名为:assets,再此文件夹内创建三个 HTML 文件如下,确保需要使用的原始文件夹路径为:app/src/main/assets
①webpage.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Hello</title>
<!-- 炫彩的发光字特效,并且可直接在界面上自定义编辑文本 参考:https://blog.youkuaiyun.com/weixin_62897746/article/details/128735318 -->
<style>
*{
/* 初始化 */
margin: 0;
padding: 0;
}
body{
/* 100% 窗口高度 */
min-height: 100vh;
width: 100%;
/* 弹性布局 水平+垂直居中 */
display: flex;
justify-content: center;
align-items: center;
background-color: #06252e;
}
.box{
width: 100%;
/* 投影效果 */
-webkit-box-reflect:below 1px linear-gradient(transparent, rgba(0,0,0,0.2));
}
h1{
color: #fff;
font-size: 56px;
/* 字间距 */
letter-spacing: 15px;
/* 转大写 */
text-transform: uppercase;
text-align: center;
line-height: 76px;
outline: none;
/* 自定义属性 --c,可通过 var 函数对其调用 */
--c:lightseagreen;
/* 调用自定义属性--c,设置文字阴影(发光效果) */
text-shadow: 0 0 10px var(--c),
0 0 20px var(--c),
0 0 40px var(--c),
0 0 80px var(--c),
0 0 160px var(--c);
/* 执行动画:动画名 时长 线性的 无限次播放 */
animation: animate 5s linear infinite;
}
/* 定义动画 */
@keyframes animate{
to{
/* 色相旋转过滤镜(设置度数可改变颜色) */
filter: hue-rotate(360deg);
}
}
</style>
</head>
<body>
<div class="box">
<!-- <h1 contenteditable="true">我爱你❤中国!</h1>-->
<h1 contenteditable="true">❤中国!</h1>
</div>
</body>
</html>
②marquee.html
<!DOCTYPE html>
<html>
<head>
<!-- 炫彩的发光字跑马灯特效,文本从右往左侧边界一直滚动,并且可直接在界面上自定义编辑文本 -->
<style>
/* 核心定位样式,将文字固定显示在屏幕右下角 */
.corner-text {
position: fixed; /* 关键属性:相对于浏览器窗口定位 */
right: 5px; /* 距离右边距 20px */
bottom: 3px; /* 距离底部 30px */
/* 可选自定义边距、背景色、字体大小等样式 */
padding: 2px 5px;
background: rgba(0,0,0,0.2); /* 0.2为透明度20% */
color: purple;
border-radius: 5px;
font-size: 0.5px;
transform: scale(0.5); /* 缩小至 50% */
display: inline-block; /* 避免缩放影响布局(关键) */
transform-origin: 100% 100%; /* 右下角对齐 */
z-index: 9999; /* 确保在最顶层 */
}
*{
/* 初始化 */
margin: 0;
padding: 0;
}
body{
/* 100% 窗口高度 */
min-height: 100vh;
width: 100%;
/* 弹性布局 水平+垂直居中 */
display: flex;
justify-content: center;
align-items: center;
/* 设置界面主背景色 */
background-color: #FFFFFF;
}
.box{
width: 100%;
/* 投影效果 */
-webkit-box-reflect:below 1px linear-gradient(transparent, rgba(0,0,0,0.2));
}
h1{
color: #fff;
/* 字体大小 */
font-size: 310px;
/* 字间距 */
letter-spacing: 15px;
/* 转大写 */
text-transform: uppercase;
text-align: center;
/* 阴影部分高度 */
line-height: 365px;
outline: none;
/* 自定义属性 --c,可通过 var 函数对其调用 */
--c:lightseagreen;
/* 调用自定义属性--c,设置文字阴影(发光效果) */
text-shadow: 0 0 10px var(--c),
0 0 20px var(--c),
0 0 40px var(--c),
0 0 80px var(--c),
0 0 160px var(--c);
/* 执行动画:动画名 时长 线性的 无限次播放; 心跳频率参数:animate 1s cubic-bezier(0.1, 0.8, 0.2, 1) infinite; */
animation: animate 1s linear infinite;
}
/* 定义动画 */
@keyframes animate{
to{
/* 色相旋转过滤镜(设置度数可改变颜色) */
filter: hue-rotate(360deg);
}
}
</style>
</head>
<body>
<!-- 提示:将文字固定显示在屏幕右下角,加边框显示 -->
<div class="corner-text">请将设备旋转至横屏以获得最佳体验</div>
<!-- behavior="alternate":文本在边界来回弹动; behavior="scroll": 文本向左侧边界滚动;direction:滚动方向(left/right/up/down); scrollamount:控制滚动速度(数值越大越快) -->
<marquee id="customMarquee" behavior="scroll" direction="left" scrollamount="15" >
<!-- contenteditable="false" 默认为false表示界面不予许被编辑 -->
<h1 contenteditable="true">❤中国!❤</h1>
</marquee>
</body>
</html>
③marquee1.html
<!DOCTYPE html>
<html>
<head>
<!-- 炫彩的发光字跑马灯特效,文本在边界来回弹动,并且可直接在界面上自定义编辑文本 -->
<style>
/* 核心定位样式,将文字固定显示在屏幕右下角 */
.corner-text {
position: fixed; /* 关键属性:相对于浏览器窗口定位 */
right: 5px; /* 距离右边距 20px */
bottom: 3px; /* 距离底部 30px */
/* 可选自定义边距、背景色、字体大小等样式 */
padding: 2px 5px;
background: rgba(0,0,0,0.2); /* 0.2为透明度20% */
color: purple;
border-radius: 5px;
font-size: 0.5px;
transform: scale(0.5); /* 缩小至 50% */
display: inline-block; /* 避免缩放影响布局(关键) */
transform-origin: 100% 100%; /* 右下角对齐 */
z-index: 9999; /* 确保在最顶层 */
}
*{
/* 初始化 */
margin: 0;
padding: 0;
}
body{
/* 100% 窗口高度 */
min-height: 100vh;
width: 100%;
/* 弹性布局 水平+垂直居中 */
display: flex;
justify-content: center;
align-items: center;
/* 设置界面主背景色 */
background-color: #FFFFFF;
}
.box{
width: 100%;
/* 投影效果 */
-webkit-box-reflect:below 1px linear-gradient(transparent, rgba(0,0,0,0.2));
}
h1{
color: #fff;
/* 字体大小 */
font-size: 310px;
/* 字间距 */
letter-spacing: 15px;
/* 转大写 */
text-transform: uppercase;
text-align: center;
/* 阴影部分高度 */
line-height: 365px;
outline: none;
/* 自定义属性 --c,可通过 var 函数对其调用 */
--c:lightseagreen;
/* 调用自定义属性--c,设置文字阴影(发光效果) */
text-shadow: 0 0 10px var(--c),
0 0 20px var(--c),
0 0 40px var(--c),
0 0 80px var(--c),
0 0 160px var(--c);
/* 执行动画:动画名 时长 线性的 无限次播放; 心跳频率参数:animate 1s cubic-bezier(0.1, 0.8, 0.2, 1) infinite; */
animation: animate 1s linear infinite;
}
/* 定义动画 */
@keyframes animate{
to{
/* 色相旋转过滤镜(设置度数可改变颜色) */
filter: hue-rotate(360deg);
}
}
</style>
</head>
<body>
<!-- 提示:将文字固定显示在屏幕右下角,加边框显示 -->
<div class="corner-text">请将设备旋转至横屏以获得最佳体验</div>
<!-- behavior="alternate":文本在边界来回弹动; behavior="scroll": 文本向边界滚动;direction:滚动方向(left/right/up/down); scrollamount:控制滚动速度(数值越大越快) -->
<marquee id="customMarquee" behavior="alternate" direction="left" scrollamount="15" >
<!-- contenteditable="false" 默认为false表示界面不予许被编辑 -->
<h1 contenteditable="true">❤中国!❤</h1>
</marquee>
</body>
</html>
2. 编写页面布局样式
- 布局界面 (默认创建):res/layout/activity_main.xm
<?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=".MainActivity">
<Button
android:id="@+id/btn_web"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="请触摸屏幕,点我!固定"
android:textSize="30sp"
android:textStyle="bold"
android:background="#9C27B0"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_web1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_weight="1" />
<Button
android:id="@+id/btn_web1"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="滚动"
android:textSize="30sp"
android:textStyle="bold"
android:background="#673AB7"
app:layout_constraintTop_toBottomOf="@id/btn_web"
app:layout_constraintBottom_toTopOf="@id/btn_web2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_weight="1" />
<Button
android:id="@+id/btn_web2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="来回"
android:textSize="30sp"
android:textStyle="bold"
android:background="#3F51B5"
app:layout_constraintTop_toBottomOf="@id/btn_web1"
app:layout_constraintBottom_toTopOf="@id/tv_corner_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_weight="1" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="@+id/tv_corner_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请将设备旋转至横屏以获得最佳体验"
android:textColor="#FFEB3B"
android:textSize="16sp"
android:background="#E91E63"
android:gravity="center"
android:layout_gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="15dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 高分辨率的图像资源 (默认创建):res/mipmap-hdpi
放入自定义Apk 图标名称为:ic_hzy.png
- 字符串资源 (默认创建):res/value/strings.xml
修改自定义Apk的应用名称为:故屿屿
<resources>
<string name="app_name">故屿屿</string>
</resources>
- 配置应用主题和样式 (默认创建):res/value/themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MyApplication" parent="Theme.AppCompat.Light.NoActionBar">:ml-citation{ref="1,8" data="citationList"}
<item name="android:windowFullscreen">true</item> <!-- 强制全屏显示 -->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
3. 其它关键性代码
修改自定义Apk的应用名称和图标
修改自定义输出Apk的应用名版本日期等字段
设置打开布局界面达到全屏显示 (部分 Android 10 机型上无法全屏)
- 主配置文件 (默认创建):AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_hzy"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- app 模块构建脚本文件 (默认创建):build.gradle
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 29
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
applicationVariants.all { variant ->
def project = "CustomSubtitles"
// def flavor = variant.productFlavors[0].name // 如果没有 productFlavors,可忽略
// def buildType = variant.buildType.name // buildType 类型默认为 Debug,可忽略
def version = variant.versionName
def date = new Date().format("yyyyMMddHHmm")
variant.outputs.all {
// outputFileName = "${project}_${flavor}_${buildType}_v${version}_${date}.apk"
outputFileName = "${project}_v${version}_${date}.apk" // 自定义输出 apk 命名:名称+包名+时间
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
- project 全局构建脚本文件 (默认创建):build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter() { url "https://maven.aliyun.com/repository/jcenter" }
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
4. 编译运行代码
在 Android Studio 中,顶部菜单栏选择:Build > Clean Project;会清除 (xxx.apk) 项目
①然后选择 Build > Rebuild Project (若插入移动设备可直接点击执行 Run),等待编译完之后在左侧目录文件:app - build - outputs - apk - debug,找到生成目标 xxx.Apk 即可,参考如下图!
原APK文件下载地址:https://download.youkuaiyun.com/download/weixin_49770443/90883478?spm=1001.2014.3001.5501
原Apk应用图标和名称:
运行界面样式截图如下:
- 视频效果:
TB330FU 2025-07-07 09-54-24
注意事项
①、炫彩的发光字幕跑马灯在边界来回弹动(或者侧边滚动)特效,设置一属性后可直接在界面上自定义编辑光发文本;
②、字幕【跑马灯】特效主要通过编程语言如 JavaScript、CSS 及 HTML 结合布局控件页面来实现;
③、部分机型上 (Android 10 版本) 安装此Apk,系统版本不兼容会触发安装失败,提示:解析包时出现问题,需检查更新 APK 的 minSdkVersion 和 targetSdkVersion 为 29 ;
④、此 Apk 无签名,adb 安装可使用 adb install -t xxx.apk 安装应用。
-
下一期总结三篇示例:
①定制3D悬浮相册 Custom3DPhoto
②定制表白对话框 CustomDialog
③炫彩的时分秒掉落颗粒特效 CustomTime小白一枚,仅供参考,多多指教!
Note:
欢迎点赞,留言,转载请在文章页面明显位置给出原文链接
知者,感谢您在茫茫人海中阅读了我的文章
没有个性 哪来的签名!
详情请关注点我
持续更新中

© 2025 06 - Guyu.com | 【版权所有 侵权必究】 |