一款极简的 Android 催眠视觉应用。打开应用后,屏幕正中央显示一颗紫粉色爱心,同时有多圈紫粉色同心波纹以爱心为中心不断向外扩散,配合纯黑背景,营造沉浸式催眠/冥想氛围。
- 中心爱心:位于手机屏幕几何正中心,紫粉色填充 + 白色描边,作为视觉焦点
- 扩散波纹:10 圈紫粉色同心圆从中心持续向外扩散,半径越大透明度越低、线宽越细,模拟真实波纹消散
- 色彩层次:8 种紫粉色(
#FF00FF→#A000A0)交替循环,增强视觉层次 - 节奏舒缓:单次扩散周期 4 秒,匀速线性插值,适合催眠引导
- 纯黑背景:全屏沉浸,无干扰元素
| 项目 | 版本/说明 |
|---|---|
| 语言 | Kotlin |
| 最低系统 | Android 7.0 (API 24) |
| 目标系统 | Android 15 (API 35) |
| 构建工具 | Gradle 8.14.5 |
| Android Gradle Plugin | 8.7.3 |
| Kotlin | 2.0.21 |
| JDK | OpenJDK 24.0.2 |
| 依赖库 | AndroidX AppCompat 1.7.0、Core KTX 1.15.0、Activity KTX 1.9.3 |
本项目使用以下已配置好的本地环境(无需额外下载):
| 组件 | 路径 |
|---|---|
| JDK 24 | C:\Users\Administrator\.jdks\openjdk-24.0.2+12-54 |
| Android SDK | D:\envs\android-dev(含 build-tools 34/35、platforms 34/35) |
| Gradle 8.14.5 | D:\envs\gradle-8.14.5 |
| Kotlin | D:\envs\kotlin\kotlinc |
克隆后需在项目根目录创建
local.properties,写入sdk.dir=<你的 Android SDK 路径>。
# Debug 版本(可直接安装,已签名)
gradle assembleDebug
# Release 版本(未签名,需自行配置签名)
gradle assembleRelease
# 强制重新构建(忽略增量缓存)
gradle assembleDebug --rerun-tasks构建产物路径:
app/build/outputs/apk/debug/app-debug.apk
app/build/outputs/apk/release/app-release-unsigned.apk
方式一:ADB 安装(推荐)
用数据线连接手机并开启 USB 调试:
adb install app/build/outputs/apk/debug/app-debug.apk方式二:直接传输 APK
将 app-debug.apk 传到手机,点击安装(需允许"未知来源")。
hypnosis_application/
├── app/
│ ├── build.gradle.kts # 模块级构建配置(依赖、SDK 版本)
│ ├── proguard-rules.pro # ProGuard 混淆规则
│ └── src/main/
│ ├── AndroidManifest.xml # 应用清单(全屏、横竖屏自适应)
│ ├── java/com/hypnosis/app/
│ │ ├── MainActivity.kt # 入口 Activity,全屏沉浸 + 生命周期管理
│ │ └── HypnosisView.kt # 核心:自定义 View,绘制爱心与扩散波纹
│ └── res/drawable/
│ └── ic_launcher.xml # 矢量应用图标(黑底+紫粉波纹+爱心)
├── build.gradle.kts # 根级构建配置
├── settings.gradle.kts # 多模块设置与仓库声明
├── gradle.properties # Gradle 与 AndroidX 属性
├── local.properties # SDK 路径(不入库,需自行创建)
├── .gitignore
└── README.md
继承自 View,全部绘制逻辑在 onDraw 中完成,通过 ValueAnimator 驱动每帧重绘。
1. 扩散波纹算法
val rippleCount = 10
for (i in 0 until rippleCount) {
val offset = i.toFloat() / rippleCount // 相位偏移
val rawRadius = (phase + offset) % 1f // 归一化半径 [0,1)
val radius = rawRadius * maxRadius // 实际像素半径
val alpha = (1f - rawRadius) * 255f // 半径越大越透明
ripplePaint.alpha = alpha.toInt().coerceIn(0, 255)
ripplePaint.strokeWidth = 18f - rawRadius * 12f // 半径越大线越细
canvas.drawCircle(cx, cy, radius, ripplePaint)
}phase由ValueAnimator在 4 秒内从 0 线性增长到 1,无限循环- 10 个波纹每个相位错开
1/10,形成持续不断的扩散流 maxRadius取屏幕对角线一半,保证波纹能扩散到屏幕四角
2. 爱心绘制
使用两条三阶贝塞尔曲线(cubicTo)拼合标准爱心形状,以屏幕中心为基准点,尺寸随屏幕较小边自适应(min(w,h) × 0.18):
heartPath.moveTo(cx, bottomPoint) // 心尖
heartPath.cubicTo( // 左半边
cx - size*1.2f, cy - size*0.2f,
cx - size*0.6f, topOffset - size*0.5f,
cx, topOffset
)
heartPath.cubicTo( // 右半边
cx + size*0.6f, topOffset - size*0.5f,
cx + size*1.2f, cy - size*0.2f,
cx, bottomPoint
)3. 生命周期管理
onResume:启动动画onPause:停止动画(节省电量)onDetachedFromWindow:释放动画资源
- 设置全屏黑色背景
- 直接将
HypnosisView作为根视图(无需 XML 布局,更轻量) - 在生命周期回调中控制动画启停
采用纯矢量 drawable(<vector>)实现,无需多套位图:
- 深紫黑背景
#0A0010 - 4 圈紫粉同心波纹,透明度由外向内递减
- 中心爱心,紫粉填充 + 白色描边
- 任意分辨率清晰锐利,体积仅 1KB
如需调整效果,修改 HypnosisView.kt 中以下参数:
| 参数 | 默认值 | 作用 |
|---|---|---|
rippleCount |
10 | 同时存在的波纹数量 |
duration |
4000ms | 单次扩散周期,越大越慢 |
rippleColors |
8 种紫粉 | 波纹颜色循环 |
heart scale |
0.18f |
爱心大小占屏幕比例 |
strokeWidth |
18f | 波纹初始线宽 |
- 应用不申请任何权限
- 横屏/竖屏自适应(
screenOrientation="sensor") - 纯 Canvas 绘制,无第三方 UI 框架,运行流畅低耗电
- 矢量图标方案兼容 API 24+,无需生成多套 PNG
MIT License - 可自由使用、修改、分发。