Android 入门示例之炫彩的发光字幕跑马灯文本特效








前言


  • 在新闻网站、广告展示、公告栏等多种场景中都广泛的应用【跑马灯】特效。页面滚动显示信息可以增加用户关注度。

在一次大型演唱会台上,看到很多粉迷使用手机展示字幕,很有吸引力的炫彩字幕跑马灯效果,于是突发连想,在近期业余期开发了此类 Apk,实现三种效果,可参考如下具体完整代码示例

  • 项目工程主要目录文件结构图:

故屿-2025-6-23 10:35:40







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

故屿-2025-6-19 10:20:28


  • 字符串资源 (默认创建):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 即可,参考如下图!

故屿-2025-6-23 16:21:59

原APK文件下载地址:https://download.youkuaiyun.com/download/weixin_49770443/90883478?spm=1001.2014.3001.5501



原Apk应用图标和名称:

故屿-2025-6-23 17:46:27



运行界面样式截图如下:

故屿-2025-6-23 16:33:12

故屿-2025-6-23 17:35:59

故屿-2025-6-23 17:33:55

故屿-2025-6-23 17:29:39


  • 视频效果:

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

    小白一枚,仅供参考,多多指教!




故屿-2025-7-2 16:31:26














Note:
欢迎点赞,留言,转载请在文章页面明显位置给出原文链接
知者,感谢您在茫茫人海中阅读了我的文章
没有个性 哪来的签名!
详情请关注点我
持续更新中

扫一扫 有惊喜!
© 2025 06 - Guyu.com | 【版权所有 侵权必究】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值