From b87e6a934304332056e5ae021b8b4d67c6c0fb66 Mon Sep 17 00:00:00 2001 From: xiao_wine <68009112+xiaowine@users.noreply.github.com> Date: Sat, 4 Nov 2023 22:49:28 +0800 Subject: [PATCH] Merge Dev into main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 6.0.1 动态歌词速度(Beta) 添加部分提示 修改默认配置 优化代码 * Prevent channel push failures due to long commit messages (#332) * Update source file strings.xml (#333) [ci skip] New translations from Crowdin * 优化初始化 * 优化 限制可见性更改 * 添加 点击状态栏隐藏歌词(完美) * 优化布局 * Update source file strings.xml (#340) [ci skip] New translations from Crowdin * 优化布局 * Update source file strings.xml (#342) [ci skip] New translations from Crowdin * 优化代码 * 优化提示 优化动态速度 * 添加判断 * 优化描述 * 优化点击状态栏隐藏歌词 * Update README.md * README.md * 优化提示 * 优化代码 * 添加 MIUI隐藏网速 * 优化布局 * 修复随机动画缺少新动画 * 优化代码 * 优化代码 * 优化代码 * 更新 SystemUILyric.kt * 添加 歌词模糊边缘类型 * 优化代码 * 添加 根据下一句歌词到来时间,动态调节速度速度(目前只支持apple music,算法也不知道有没有问题) * 添加 根据下一句歌词到来时间,动态调节速度速度(目前只支持apple music,算法也不知道有没有问题) * New Crowdin updates (#346) * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin --------- Co-authored-by: xiao_wine <68009112+xiaowine@users.noreply.github.com> * 优化代码 * 添加 部分系统息屏切换深色模式时自动重启系统界面 * 优化部分逻辑 * 同步api改动 * 使用kotlin委托属性 * api从git子模块迁移到JitPack * Update build.gradle.kts * 优化代码 * 删除无用的name * lyricGetterApi to 5.0.2 * lyricGetterApi to 5.0.2 * 添加 状态栏滑动切歌 * 调整 添加 状态栏滑动切歌 优先级 * 调整 添加 状态栏滑动切歌 优先级 * 更改string格式 * 删除无用资源 * 优化代码 * 6.0.2 添加 状态栏滑动切歌 添加 点击状态栏隐藏歌词(完美方案) 添加 根据下一句歌词到来时间,动态调节速度速度(目前只支持apple music,算法也不知道有没有问题) 添加 歌词模糊边缘类型 修复 随机动画缺少新动画 添加 MIUI隐藏网速 优化 代码 * 优化 点击状态栏隐藏歌词 * lyricGetterApi to "5.0.3" * lyricGetterApi to "5.0.3" 优化代码 * 修复暂停音乐后依旧可以点击状态栏显示歌词 * 回撤反色改动 * 删除 正则表达式屏蔽歌词 * 新增歌词动画插值器、歌词动画持续时间和动画淡出淡入效果 (#358) * 新增歌词动画插值器选项和歌词动画持续时间可配置项 * 新增歌词动画淡出淡入效果 * 代人水个pr 顺便升级下api * 更新 README.md * Bump com.github.kyuubiran:EzXHelper from 2.0.6 to 2.0.7 (#364) Bumps [com.github.kyuubiran:EzXHelper](https://github.com/KyuubiRan/EzXHelper) from 2.0.6 to 2.0.7. - [Commits](https://github.com/KyuubiRan/EzXHelper/commits) --- updated-dependencies: - dependency-name: com.github.kyuubiran:EzXHelper dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump org.jetbrains.kotlin:kotlin-gradle-plugin from 1.9.0 to 1.9.10 (#363) Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.9.0 to 1.9.10. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.9.10/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.0...v1.9.10) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * New Crowdin updates (#352) * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin * Update source file strings.xml [ci skip] New translations from Crowdin * 优化代码 * 修复部分情况歌词颜色异常 * gradle to 8.1.1 * gradle to 8.1.2 * Update README.md * 优化颜色处理 * 添加 miui pad优化 放宽条件继续扩大范围 * 添加 miui pad优化 放宽条件继续扩大范围 * 改错了,同时我不理解为什么找不到库 * 没什么用的优化 * 优化代码 * 修复滑动状态栏无法切歌 修复开启限制可见性变化后 点击隐藏歌词 时间不显示 * 添加 长按状态栏停止音乐 优化相关代码 * 修复miui切换深色后无法使用(现在切换后重新点亮屏幕就行了) * 优化代码 * Bump org.jetbrains.kotlin:kotlin-gradle-plugin from 1.9.10 to 1.9.20 (#377) Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.9.10 to 1.9.20. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/commits) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump com.github.kyuubiran:EzXHelper from 2.0.7 to 2.0.8 (#376) Bumps [com.github.kyuubiran:EzXHelper](https://github.com/KyuubiRan/EzXHelper) from 2.0.7 to 2.0.8. - [Commits](https://github.com/KyuubiRan/EzXHelper/commits) --- updated-dependencies: - dependency-name: com.github.kyuubiran:EzXHelper dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * 同步UI库 * 删除无用资源 * 6.1.0 * Revert "Merge branch 'main' into Dev" This reverts commit e4cbaa26d8d188eef1d91b6db36ac32428eb5fe5, reversing changes made to a51617ade426faefbb9d96ece183871832d022bb. --------- Signed-off-by: dependabot[bot] Co-authored-by: Howard Wu Co-authored-by: 方块君 <86393520+577fkj@users.noreply.github.com> Co-authored-by: KokomiQAQ <87627969+H-u-T-ao@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com> Co-authored-by: QQ little ice <60041789+qqlittleice233@users.noreply.github.com> Co-authored-by: QQ littleice <1767523953@qq.com> --- README.md | 3 +- app/build.gradle.kts | 27 +-- .../lyric/activity/page/ChoosePage.kt | 11 +- .../lyric/activity/page/ExtendPage.kt | 16 +- .../lyric/activity/page/LyricPage.kt | 42 ++++ .../statusbar/lyric/activity/page/MenuPage.kt | 5 +- .../lyric/activity/page/SystemSpecialPage.kt | 1 + .../java/statusbar/lyric/config/Config.kt | 63 +++-- .../main/java/statusbar/lyric/data/Data.kt | 66 +++++- .../statusbar/lyric/hook/app/SystemUILyric.kt | 216 +++++++++++------- .../statusbar/lyric/hook/app/SystemUITest.kt | 40 ++-- .../main/java/statusbar/lyric/tools/Tools.kt | 56 +++-- .../java/statusbar/lyric/tools/ViewTools.kt | 47 +++- app/src/main/res/values-zh-rCN/strings.xml | 17 +- app/src/main/res/values-zh-rTW/strings.xml | 17 +- app/src/main/res/values/strings.xml | 17 +- blockmiui | 2 +- build.gradle.kts | 4 +- gradle.properties | 7 + settings.gradle.kts | 8 +- 20 files changed, 456 insertions(+), 209 deletions(-) diff --git a/README.md b/README.md index c2228e5e..702c7c94 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Icon](/icon.png)]() ![Release Download](https://img.shields.io/github/downloads/577fkj/StatusBarLyric/total?style=flat-square) +![Release Download](https://img.shields.io/github/downloads/Xposed-Modules-Repo/statusbar.lyric/total?style=flat-square) [![Release Version](https://img.shields.io/github/v/release/577fkj/StatusBarLyric?style=flat-square)](https://github.com/577fkj/StatusBarLyric/releases/latest) [![GitHub license](https://img.shields.io/github/license/577fkj/StatusBarLyric?style=flat-square)](LICENSE) [![GitHub Star](https://img.shields.io/github/stars/577fkj/StatusBarLyric?style=flat-square)](https://github.com/577fkj/StatusBarLyric/stargazers) @@ -14,8 +15,6 @@ [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2F577fkj%2FStatusBarLyric%2Fbadge%3Fref%3Dmain&style=flat)](https://actions-badge.atrox.dev/577fkj/StatusBarLyric/goto?ref=main) [![GitHub Star](https://img.shields.io/github/stars/577fkj/StatusBarLyric.svg?style=social)](https://github.com/577fkj/StatusBarLyric) [![电报群](https://img.shields.io/badge/电报群-StatusBatLyric-blue.svg?style=flat-square&color=12b7f5)](https://t.me/StatusBatLyric) -[![爱发电](https://img.shields.io/badge/爱发电-@xiao_wine-blue.svg?style=flat-square&color=12b7f5)](https://afdian.net/@xiao_wine) - ### 理论支持 __所有__ 官方以及部分修改系统 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 29423f41..e3284ddb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -7,8 +7,7 @@ plugins { } val localProperties = Properties() -if (rootProject.file("local.properties").canRead()) - localProperties.load(rootProject.file("local.properties").inputStream()) +if (rootProject.file("local.properties").canRead()) localProperties.load(rootProject.file("local.properties").inputStream()) android { namespace = "statusbar.lyric" @@ -18,8 +17,8 @@ android { applicationId = "statusbar.lyric" minSdk = 26 targetSdk = 34 - versionCode = 202 - versionName = "6.0.2" + versionCode = 203 + versionName = "6.1.0" aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false buildConfigField("long", "BUILD_TIME", "$buildTime") @@ -53,20 +52,13 @@ android { kotlinOptions { jvmTarget = JavaVersion.VERSION_17.majorVersion } - packagingOptions { + packaging { resources { - excludes += "/META-INF/**" - excludes += "/kotlin/**" - excludes += "/*.txt" - excludes += "/*.bin" - } - dex { - useLegacyPackaging = true + excludes += "**" } } buildFeatures { viewBinding = true - buildConfig = true } applicationVariants.all { outputs.all { @@ -75,11 +67,16 @@ android { } } +kotlin { + sourceSets.all { + languageSettings { languageVersion = "2.0" } + } +} dependencies { compileOnly("de.robv.android.xposed:api:82") implementation(project(":blockmiui")) implementation(project(":xtoast")) - implementation("com.github.kyuubiran:EzXHelper:2.0.6") - implementation("com.github.xiaowine:Lyric-Getter-Api:5.0.2") + implementation("com.github.kyuubiran:EzXHelper:2.0.8") + implementation("com.github.xiaowine:Lyric-Getter-Api:5.0.5") } diff --git a/app/src/main/java/statusbar/lyric/activity/page/ChoosePage.kt b/app/src/main/java/statusbar/lyric/activity/page/ChoosePage.kt index 5d5afb58..24fafc92 100644 --- a/app/src/main/java/statusbar/lyric/activity/page/ChoosePage.kt +++ b/app/src/main/java/statusbar/lyric/activity/page/ChoosePage.kt @@ -14,23 +14,24 @@ class ChoosePage : BasePage() { TitleText(textId = R.string.choose_page_tips) Line() dataList.forEach { data -> - TextSA(text = "${data.textViewClassName} ${data.textViewID}", tips = "${data.parentClassName} ${data.parentID}", onClickListener = { + TextSA(text = "${data.textViewClassName} ${data.textViewId}", tips = "${data.parentViewClassName} ${data.parentViewId} textSize:${data.textSize}", onClickListener = { activity.showView(data) MIUIDialog(activity) { setTitle(activity.getString(R.string.select_hook)) setRButton(activity.getString(R.string.ok)) { config.textViewClassName = data.textViewClassName - config.textViewID = data.textViewID - config.parentClassName = data.parentClassName - config.parentID = data.parentID + config.textViewId = data.textViewId + config.parentViewClassName = data.parentViewClassName + config.parentViewId = data.parentViewId config.index = data.index + config.textSize = data.textSize } setLButton(activity.getString(R.string.cancel)) finally { dismiss() } }.show() }) - TitleText(activity.getString(R.string.a_a_a_tips).format(data.isRepeat, data.index)) + TitleText(activity.getString(R.string.a_a_a_tips).format(data.isRepeat, data.index, data.textSize)) Line() } } diff --git a/app/src/main/java/statusbar/lyric/activity/page/ExtendPage.kt b/app/src/main/java/statusbar/lyric/activity/page/ExtendPage.kt index d5e664e3..3d2a6c82 100644 --- a/app/src/main/java/statusbar/lyric/activity/page/ExtendPage.kt +++ b/app/src/main/java/statusbar/lyric/activity/page/ExtendPage.kt @@ -38,21 +38,7 @@ class ExtendPage : BasePage() { }) TextSw(textId = R.string.dynamic_lyric_speed, key = "dynamicLyricSpeed", onClickListener = { changeConfig() }) TextSw(textId = R.string.click_status_bar_to_hide_lyric, key = "clickStatusBarToHideLyric") - TextSA(textId = R.string.regex_replace, onClickListener = { - MIUIDialog(activity) { - setTitle(getString(R.string.regex_replace)) - setMessage(getString(R.string.regex_replace_tips)) - setEditText(ActivityOwnSP.config.regexReplace, "", config = { - it.inputType = InputType.TYPE_CLASS_TEXT - it.filters = arrayOf(InputFilter.LengthFilter(200)) - }) - setRButton(getString(R.string.ok)) { - ActivityOwnSP.config.regexReplace = getEditText() - } - setLButton(getString(R.string.cancel)) - finally { dismiss() } - }.show() - }) + TextSw(textId = R.string.long_click_status_bar_stop, key = "longClickStatusBarStop") Line() val lyricBlurredEdgesRadiusBinding = GetDataBinding({ ActivityOwnSP.config.lyricBlurredEdges }) { view, _, data -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE diff --git a/app/src/main/java/statusbar/lyric/activity/page/LyricPage.kt b/app/src/main/java/statusbar/lyric/activity/page/LyricPage.kt index adabc7a4..d37d88cf 100644 --- a/app/src/main/java/statusbar/lyric/activity/page/LyricPage.kt +++ b/app/src/main/java/statusbar/lyric/activity/page/LyricPage.kt @@ -341,6 +341,7 @@ class LyricPage : BasePage() { this["Bottom"] = getString(R.string.lyrics_animation_bottom) this["Start"] = getString(R.string.lyrics_animation_start) this["End"] = getString(R.string.lyrics_animation_end) + this["Fade"] = getString(R.string.lyrics_animation_fade) this["ScaleX"] = getString(R.string.lyrics_animation_scale_x) this["ScaleY"] = getString(R.string.lyrics_animation_scale_y) this["ScaleXY"] = getString(R.string.lyrics_animation_scale_x_y) @@ -354,5 +355,46 @@ class LyricPage : BasePage() { } } }) + val interpolatorMaps: LinkedHashMap = LinkedHashMap().apply { + this["Linear"] = getString(R.string.lyrics_interpolator_linear) + this["Accelerate"] = getString(R.string.lyrics_interpolator_accelerate) + this["Decelerate"] = getString(R.string.lyrics_interpolator_decelerate) + this["Accelerate&Decelerate"] = getString(R.string.lyrics_interpolator_accelerate_decelerate) + this["Overshoot"] = getString(R.string.lyrics_interpolator_overshoot) + this["Bounce"] = getString(R.string.lyrics_interpolator_bounce) + } + TextSSp(textId = R.string.lyrics_animation_interpolator, currentValue = interpolatorMaps[config.interpolator].toString(), data = { + interpolatorMaps.forEach { + add(it.value) { + config.interpolator = (it.key) + changeConfig() + } + } + }) + TextSA(textId = R.string.lyrics_animation_duration, onClickListener = { + MIUIDialog(activity) { + setTitle(getString(R.string.lyrics_animation_duration)) + setMessage(getString(R.string.lyric_animation_duration_tips)) + setEditText(config.animationDuration.toString(), "500", config = { + it.inputType = InputType.TYPE_NUMBER_FLAG_SIGNED + it.filters = arrayOf(InputFilter.LengthFilter(4)) + }) + setRButton(getString(R.string.ok)) { + try { + val value = getEditText().toInt() + if (value in 300..1000) { + config.animationDuration = value + changeConfig() + } else { + throw Exception() + } + } catch (_: Exception) { + ActivityTools.showToastOnLooper(getString(R.string.input_error)) + } + } + setLButton(getString(R.string.cancel)) + finally { dismiss() } + }.show() + }) } } \ No newline at end of file diff --git a/app/src/main/java/statusbar/lyric/activity/page/MenuPage.kt b/app/src/main/java/statusbar/lyric/activity/page/MenuPage.kt index edbdc9a0..57760a8c 100644 --- a/app/src/main/java/statusbar/lyric/activity/page/MenuPage.kt +++ b/app/src/main/java/statusbar/lyric/activity/page/MenuPage.kt @@ -5,6 +5,7 @@ import android.content.pm.PackageManager import cn.fkj233.ui.activity.annotation.BMMenuPage import cn.fkj233.ui.activity.data.BasePage import cn.fkj233.ui.activity.view.SwitchV +import cn.fkj233.ui.activity.view.TextSummaryV import cn.fkj233.ui.activity.view.TextV import cn.fkj233.ui.dialog.MIUIDialog import statusbar.lyric.BuildConfig @@ -62,9 +63,9 @@ class MenuPage : BasePage() { Line() TitleText(textId = R.string.module_version) - TextSA(textId = R.string.module_version, tips = "${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})-${BuildConfig.BUILD_TYPE}") + TextSummaryV(textId = R.string.module_version, tips = "${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})-${BuildConfig.BUILD_TYPE}") val buildTime = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()).format(BuildConfig.BUILD_TIME) - TextSA(textId = R.string.module_build_time, tips = buildTime) + TextSummaryV(textId = R.string.module_build_time, tips = buildTime) Text() } } \ No newline at end of file diff --git a/app/src/main/java/statusbar/lyric/activity/page/SystemSpecialPage.kt b/app/src/main/java/statusbar/lyric/activity/page/SystemSpecialPage.kt index 5521edc4..84ffbf90 100644 --- a/app/src/main/java/statusbar/lyric/activity/page/SystemSpecialPage.kt +++ b/app/src/main/java/statusbar/lyric/activity/page/SystemSpecialPage.kt @@ -10,6 +10,7 @@ class SystemSpecialPage : BasePage() { override fun onCreate() { if (isMIUI) { TextSw(textId = R.string.miui_hide_network_speed, key = "mMIUIHideNetworkSpeed") + TextSw(textId = R.string.miui_pad_optimize, key = "mMiuiPadOptimize") } Line() TitleText("Wait for More...") diff --git a/app/src/main/java/statusbar/lyric/config/Config.kt b/app/src/main/java/statusbar/lyric/config/Config.kt index 8c5ec94d..05a44117 100644 --- a/app/src/main/java/statusbar/lyric/config/Config.kt +++ b/app/src/main/java/statusbar/lyric/config/Config.kt @@ -87,26 +87,26 @@ class Config { set(value) { config.put("textViewClassName", value) } - var textViewID: Int + var textViewId: Int get() { - return config.opt("textViewID", 0) + return config.opt("textViewId", 0) } set(value) { - config.put("textViewID", value) + config.put("textViewId", value) } - var parentClassName: String + var parentViewClassName: String get() { - return config.opt("parentClassName", "") + return config.opt("parentViewClassName", "") } set(value) { - config.put("parentClassName", value) + config.put("parentViewClassName", value) } - var parentID: Int + var parentViewId: Int get() { - return config.opt("parentID", 0) + return config.opt("parentViewId", 0) } set(value) { - config.put("parentID", value) + config.put("parentViewId", value) } var index: Int get() { @@ -115,7 +115,13 @@ class Config { set(value) { config.put("index", value) } - + var textSize: Float + get() { + return config.opt("textSize", 0f) + } + set(value) { + config.put("textSize", value) + } var lyricSize: Int get() { @@ -222,6 +228,13 @@ class Config { set(value) { config.put("limitVisibilityChange", value) } + var longClickStatusBarStop: Boolean + get() { + return config.opt("longClickStatusBarStop", false) + } + set(value) { + config.put("longClickStatusBarStop", value) + } var lyricLetterSpacing: Int get() { return config.opt("lyricLetterSpacing", 0) @@ -279,13 +292,6 @@ class Config { set(value) { config.put("iconSize", value) } - var regexReplace: String - get() { - return config.opt("regexReplace", "") - } - set(value) { - config.put("regexReplace", value) - } private var forceTheIconToBeDisplayed: Boolean get() { @@ -301,6 +307,20 @@ class Config { set(value) { config.put("animation", value) } + var interpolator: String + get() { + return config.opt("interpolator", "Linear") + } + set(value) { + config.put("interpolator", value) + } + var animationDuration: Int + get() { + return config.opt("animationDuration", 500) + } + set(value) { + config.put("animationDuration", value) + } var viewIndex: Int get() { return config.opt("viewIndex", 0) @@ -374,6 +394,15 @@ class Config { set(value) { config.put("slideStatusBarCutSongsYRadius", value) } + + var mMiuiPadOptimize: Boolean + get() { + return config.opt("mMiuiPadOptimize", false) + } + set(value) { + config.put("mMiuiPadOptimize", value) + } + private val defIconHashMap by lazy { HashMap().apply { this["com.tencent.qqmusic"] = qQMusicIcon diff --git a/app/src/main/java/statusbar/lyric/data/Data.kt b/app/src/main/java/statusbar/lyric/data/Data.kt index 712ff12e..fc400904 100644 --- a/app/src/main/java/statusbar/lyric/data/Data.kt +++ b/app/src/main/java/statusbar/lyric/data/Data.kt @@ -1,9 +1,65 @@ package statusbar.lyric.data -import java.io.Serializable +import android.os.Parcel +import android.os.Parcelable -data class Data(var textViewClassName: String, var textViewID: Int, var parentClassName: String, var parentID: Int, var isRepeat: Boolean, var index: Int) : Serializable { - companion object { - private const val serialVersionUID = 2562L + +class Data private constructor(parcel: Parcel) : Parcelable { + var textViewClassName: String = "" + var textViewId: Int = 0 + var parentViewClassName: String = "" + var parentViewId: Int = 0 + var isRepeat: Boolean = false + var index: Int = 0 + var textSize: Float = 0f + override fun describeContents(): Int { + return 0 + } + + constructor() : this(Parcel.obtain()) + constructor(textViewClassName: String, textViewId: Int, parentViewClassName: String, parentViewId: Int, isRepeat: Boolean, index: Int, size: Float) : this() { + this.textViewClassName = textViewClassName + this.textViewId = textViewId + this.parentViewClassName = parentViewClassName + this.parentViewId = parentViewId + this.isRepeat = isRepeat + this.index = index + this.textSize = size + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.apply { + writeString(textViewClassName) + writeInt(textViewId) + writeString(parentViewClassName) + writeInt(parentViewId) + writeInt(if (isRepeat) 1 else 0) + writeInt(index) + writeFloat(textSize) + } + } + + init { + textViewClassName = parcel.readString().toString() + textViewId = parcel.readInt() + parentViewClassName = parcel.readString().toString() + parentViewId = parcel.readInt() + isRepeat = parcel.readInt() == 1 + index = parcel.readInt() + textSize = parcel.readFloat() + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): Data { + return Data(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + + override fun toString(): String { + return "Data(textViewClassName='$textViewClassName', textViewId=$textViewId, parentViewClassName='$parentViewClassName', parentViewId=$parentViewId, isRepeat=$isRepeat, index=$index, textSize=$textSize)" } -} +} \ No newline at end of file diff --git a/app/src/main/java/statusbar/lyric/hook/app/SystemUILyric.kt b/app/src/main/java/statusbar/lyric/hook/app/SystemUILyric.kt index 56370a75..a47adf36 100644 --- a/app/src/main/java/statusbar/lyric/hook/app/SystemUILyric.kt +++ b/app/src/main/java/statusbar/lyric/hook/app/SystemUILyric.kt @@ -36,7 +36,6 @@ import android.graphics.Point import android.graphics.Typeface import android.graphics.drawable.GradientDrawable import android.os.Build -import android.os.PowerManager import android.util.DisplayMetrics import android.util.TypedValue import android.view.Gravity @@ -46,9 +45,7 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView -import android.widget.Toast import cn.lyric.getter.api.LyricListener -import cn.lyric.getter.api.data.DataType import cn.lyric.getter.api.data.LyricData import cn.lyric.getter.api.tools.Tools.base64ToDrawable import cn.lyric.getter.api.tools.Tools.registerLyricListener @@ -64,14 +61,15 @@ import statusbar.lyric.R import statusbar.lyric.config.XposedOwnSP.config import statusbar.lyric.hook.BaseHook import statusbar.lyric.tools.LogTools.log +import statusbar.lyric.tools.Tools import statusbar.lyric.tools.Tools.goMainThread import statusbar.lyric.tools.Tools.isLandscape import statusbar.lyric.tools.Tools.isMIUI import statusbar.lyric.tools.Tools.isNot import statusbar.lyric.tools.Tools.isNotNull +import statusbar.lyric.tools.Tools.isNull import statusbar.lyric.tools.Tools.isTargetView import statusbar.lyric.tools.Tools.observableChange -import statusbar.lyric.tools.Tools.regexReplace import statusbar.lyric.tools.Tools.shell import statusbar.lyric.tools.Tools.togglePrompts import statusbar.lyric.tools.ViewTools @@ -90,7 +88,6 @@ import kotlin.math.roundToInt class SystemUILyric : BaseHook() { - private var isScreenLock: Boolean = false private lateinit var hook: XC_MethodHook.Unhook private var lastColor: Int by observableChange(Color.WHITE) { _, newValue -> goMainThread { @@ -111,21 +108,15 @@ class SystemUILyric : BaseHook() { "Change Icon".log() } } + private var canLoad: Boolean = true + private var isScreenLock: Boolean = false private var iconSwitch: Boolean = true private var isPlaying: Boolean = false private var isHiding: Boolean = false - private var isMove = false private var themeMode: Int by observableChange(0) { oldValue, _ -> if (oldValue == 0) return@observableChange - "onConfigurationChanged".log() - runCatching { - val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager - if (!pm.isInteractive) { - shell("pkill -f com.android.systemui", false) - } else { - Toast.makeText(context, moduleRes.getString(R.string.configuration_changed_tips), Toast.LENGTH_LONG).show() - } - } + canLoad = true + hideLyric() } private var theoreticalWidth: Int = 0 private lateinit var point: Point @@ -142,6 +133,7 @@ class SystemUILyric : BaseHook() { private lateinit var targetView: ViewGroup private lateinit var mNotificationIconArea: View private lateinit var mCarrierLabel: View + private lateinit var mPadClockView: View private val lyricView: LyricSwitchView by lazy { LyricSwitchView(context).apply { setTypeface(clockView.typeface) @@ -175,22 +167,26 @@ class SystemUILyric : BaseHook() { private lateinit var mMIUINetworkSpeedView: TextView + val isReally by lazy { this@SystemUILyric::targetView.isInitialized } + //////////////////////////////Hook////////////////////////////////////// @SuppressLint("DiscouragedApi") override fun init() { "Init Hook".log() loadClassOrNull(config.textViewClassName).isNotNull { - hook = TextView::class.java.methodFinder().filterByName("setText").first().createHook { + hook = TextView::class.java.methodFinder().filterByName("onDraw").first().createHook { after { hookParam -> val view = (hookParam.thisObject as View) if (view.isTargetView()) { + if (!canLoad) return@after "Lyric Init".log() clockView = view as TextView targetView = (clockView.parent as LinearLayout).apply { gravity = Gravity.CENTER } + canLoad = false lyricInit() - hook.unhook() + if (!togglePrompts) hook.unhook() } } } @@ -202,10 +198,10 @@ class SystemUILyric : BaseHook() { moduleRes.getString(R.string.limit_visibility_change).log() View::class.java.methodFinder().filterByName("setVisibility").first().createHook { before { hookParam -> - if (isPlaying) { + if (isPlaying && !isHiding) { if (hookParam.args[0] == View.VISIBLE) { val view = hookParam.thisObject as View - if (view.isTargetView() || (this@SystemUILyric::mNotificationIconArea.isInitialized && mNotificationIconArea == view) || (this@SystemUILyric::mCarrierLabel.isInitialized && mCarrierLabel == view) || (this@SystemUILyric::mMIUINetworkSpeedView.isInitialized && mMIUINetworkSpeedView == view)) { + if (view.isTargetView() || (this@SystemUILyric::mNotificationIconArea.isInitialized && mNotificationIconArea == view) || (this@SystemUILyric::mCarrierLabel.isInitialized && mCarrierLabel == view) || (this@SystemUILyric::mMIUINetworkSpeedView.isInitialized && mMIUINetworkSpeedView == view) || (this@SystemUILyric::mPadClockView.isInitialized && mPadClockView == view)) { hookParam.args[0] = View.GONE } } @@ -219,9 +215,12 @@ class SystemUILyric : BaseHook() { 0 -> { loadClassOrNull("com.android.systemui.statusbar.phone.DarkIconDispatcherImpl").isNotNull { it.methodFinder().filterByName("applyDarkIntensity").first().createHook { - after { + after { hookParam -> if (!isPlaying) return@after - lastColor = clockView.currentTextColor + hookParam.thisObject.objectHelper { + val mIconTint = getObjectOrNullAs("mIconTint") ?: Color.BLACK + lastColor = mIconTint + } } } } @@ -230,15 +229,15 @@ class SystemUILyric : BaseHook() { 1 -> { loadClassOrNull("com.android.systemui.statusbar.phone.NotificationIconAreaController").isNotNull { it.methodFinder().filterByName("onDarkChanged").filterByParamCount(3).first().createHook { - after { + after { hookParam -> if (!isPlaying) return@after - lastColor = clockView.currentTextColor + val isDark = (hookParam.args[1] as Float) == 1f + lastColor = if (isDark) Color.BLACK else Color.WHITE } } } } } - if (config.hideNotificationIcon) { moduleRes.getString(R.string.hide_notification_icon).log() loadClassOrNull("com.android.systemui.statusbar.phone.NotificationIconAreaController").isNotNull { @@ -284,49 +283,67 @@ class SystemUILyric : BaseHook() { } MotionEvent.ACTION_MOVE -> { - isMove = true } MotionEvent.ACTION_UP -> { - if (!isMove) { - if (config.clickStatusBarToHideLyric) { - if (motionEvent.eventTime - motionEvent.downTime < 200) { - moduleRes.getString(R.string.click_status_bar_to_hide_lyric).log() - if (isHiding) { - isHiding = false - changeLyric(lastLyric, 0) - hookParam.result = true - } else { - val x = motionEvent.x.toInt() - val y = motionEvent.y.toInt() - val left = lyricLayout.left - val top = lyricLayout.top - val right = lyricLayout.right - val bottom = lyricLayout.bottom - if (x in left..right && y in top..bottom) { - hideLyric() - isHiding = true + val isMove = abs(point.y - motionEvent.rawY.toInt()) > 50 || abs(point.x - motionEvent.rawX.toInt()) > 50 + val isLongChick = motionEvent.eventTime - motionEvent.downTime > 500 + when (isMove) { + true -> { + if (config.slideStatusBarCutSongs && isPlaying) { + if (abs(point.y - motionEvent.rawY.toInt()) <= config.slideStatusBarCutSongsYRadius) { + val i = point.x - motionEvent.rawX.toInt() + if (abs(i) > config.slideStatusBarCutSongsXRadius) { + moduleRes.getString(R.string.slide_status_bar_cut_songs).log() + if (i > 0) { + shell("input keyevent 87", false) + } else { + shell("input keyevent 88", false) + } hookParam.result = true } } } } - } else { - if (config.slideStatusBarCutSongs && isPlaying) { - if (abs(point.y - motionEvent.rawY.toInt()) <= config.slideStatusBarCutSongsYRadius) { - val i = point.x - motionEvent.rawX.toInt() - if (abs(i) > config.slideStatusBarCutSongsXRadius) { - moduleRes.getString(R.string.slide_status_bar_cut_songs).log() - if (i > 0) { - shell("input keyevent 87", false) - } else { - shell("input keyevent 88", false) + + false -> { + when (isLongChick) { + true -> { + if (config.longClickStatusBarStop) { + moduleRes.getString(R.string.long_click_status_bar_stop).log() + shell("input keyevent 85", false) + hookParam.result = true + } + } + + false -> { + if (config.clickStatusBarToHideLyric) { + val isClick = motionEvent.eventTime - motionEvent.downTime < 200 + if (isClick && isPlaying) { + moduleRes.getString(R.string.click_status_bar_to_hide_lyric).log() + isHiding.log() + if (isHiding) { + isHiding = false + hookParam.result = true + changeLyric(lastLyric, 0) + } else { + val x = motionEvent.x.toInt() + val y = motionEvent.y.toInt() + val left = lyricLayout.left + val top = lyricLayout.top + val right = lyricLayout.right + val bottom = lyricLayout.bottom + if (x in left..right && y in top..bottom) { + isHiding = true + hookParam.result = true + hideLyric() + } + } + } } - hookParam.result = true } } } - isMove = false } } } @@ -339,35 +356,35 @@ class SystemUILyric : BaseHook() { @SuppressLint("UnspecifiedRegisterReceiverFlag", "MissingPermission") private fun lyricInit() { - themeMode = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) + val firstLoad = lyricLayout.parent.isNull() goMainThread(1) { + runCatching { (lyricLayout.parent as ViewGroup).removeView(lyricLayout) } if (config.viewIndex == 0) { targetView.addView(lyricLayout, 0) } else { targetView.addView(lyricLayout) } + themeMode = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) } - registerLyricListener(context, BuildConfig.API_VERSION, object : LyricListener { - override fun onReceived(lyricData: LyricData) { - if (!(this@SystemUILyric::clockView.isInitialized && this@SystemUILyric::targetView.isInitialized)) return - if (lyricData.type == DataType.UPDATE) { - val lyric = lyricData.lyric.regexReplace(config.regexReplace, "") - if (lyric.isNotEmpty()) { - lastLyric = lyric - if (isHiding) return - changeIcon(lyricData) - changeLyric(lyric, lyricData.delay) - } - } else if (lyricData.type == DataType.STOP) { - if (isHiding) isHiding = false - hideLyric() + if (!firstLoad) return + registerLyricListener(context, BuildConfig.API_VERSION, object : LyricListener() { + override fun onStop(lyricData: LyricData) { + if (!(isReally)) return + if (isHiding) isHiding = false + hideLyric() + } + + override fun onUpdate(lyricData: LyricData) { + if (!(isReally)) return + val lyric = lyricData.lyric + if (lyric.isNotEmpty()) { + lastLyric = lyric + if (isHiding) return + changeIcon(lyricData) + changeLyric(lyric, lyricData.delay) } - lyricData.log() } }) - - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { context.registerReceiver(UpdateConfig(), IntentFilter("updateConfig"), Context.RECEIVER_EXPORTED) } else { @@ -390,19 +407,25 @@ class SystemUILyric : BaseHook() { private fun changeLyric(lyric: String, delay: Int) { if (isHiding || isScreenLock) return - isPlaying = true "lyric:$lyric".log() goMainThread { + if (!isPlaying) { + if (config.lyricColor.isEmpty()) lastColor = clockView.currentTextColor + isPlaying = true + } lyricLayout.showView() if (config.hideTime) clockView.hideView() if (this::mNotificationIconArea.isInitialized) mNotificationIconArea.hideView() if (this::mCarrierLabel.isInitialized) mCarrierLabel.hideView() if (this::mMIUINetworkSpeedView.isInitialized) mMIUINetworkSpeedView.hideView() + if (this::mPadClockView.isInitialized) mPadClockView.hideView() lyricView.apply { + val interpolator = config.interpolator + val duration = config.animationDuration if (config.animation == "Random") { - val effect = arrayListOf("Top", "Bottom", "Start", "End", "ScaleXY", "ScaleX", "ScaleY").random() - inAnimation = ViewTools.switchViewInAnima(effect) - outAnimation = ViewTools.switchViewOutAnima(effect) + val effect = arrayListOf("Top", "Bottom", "Start", "End", "Fade", "ScaleXY", "ScaleX", "ScaleY").random() + inAnimation = ViewTools.switchViewInAnima(effect, interpolator, duration) + outAnimation = ViewTools.switchViewOutAnima(effect, duration) } width = getLyricWidth(paint, lyric) if (config.dynamicLyricSpeed && delay == 0) { @@ -438,7 +461,9 @@ class SystemUILyric : BaseHook() { } private fun hideLyric() { - isPlaying = false + if (!isHiding && isPlaying) { + isPlaying = false + } "Hide Lyric".log() goMainThread { lyricLayout.hideView() @@ -446,6 +471,7 @@ class SystemUILyric : BaseHook() { if (this::mNotificationIconArea.isInitialized) mNotificationIconArea.showView() if (this::mCarrierLabel.isInitialized) mCarrierLabel.showView() if (this::mMIUINetworkSpeedView.isInitialized) mMIUINetworkSpeedView.showView() + if (this::mPadClockView.isInitialized) mPadClockView.showView() } } @@ -474,9 +500,11 @@ class SystemUILyric : BaseHook() { setBackgroundColor(Color.parseColor(config.lyricBackgroundColor)) } val animation = config.animation + val interpolator = config.interpolator + val duration = config.animationDuration if (animation != "Random") { - inAnimation = ViewTools.switchViewInAnima(animation) - outAnimation = ViewTools.switchViewOutAnima(animation) + inAnimation = ViewTools.switchViewInAnima(animation, interpolator, duration) + outAnimation = ViewTools.switchViewOutAnima(animation, duration) } runCatching { val file = File("${context.filesDir.path}/font") @@ -539,15 +567,33 @@ class SystemUILyric : BaseHook() { inner class SystemUISpecial { init { if (togglePrompts) { - loadClassOrNull("com.android.systemui.SystemUIApplication").isNotNull { - it.methodFinder().filterByName("onConfigurationChanged").first().createHook { + loadClassOrNull("com.android.systemui.SystemUIApplication").isNotNull { clazz -> + clazz.methodFinder().filterByName("onConfigurationChanged").first().createHook { after { hookParam -> val newConfig = hookParam.args[0] as Configuration themeMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK } } + if (isMIUI && config.mMiuiPadOptimize) { + clazz.methodFinder().filterByName("onCreate").first().createHook { + after { + if (isPad) { + loadClassOrNull("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment").isNotNull { + it.methodFinder().filterByName("initMiuiViewsOnViewCreated").first().createHook { + after { hookParam -> + hookParam.thisObject.objectHelper { + mPadClockView = this.getObjectOrNullAs("mPadClockView")!! + } + } + } + } + } + } + } + } } } + if (isMIUI && config.mMIUIHideNetworkSpeed) { moduleRes.getString(R.string.miui_hide_network_speed).log() loadClassOrNull("com.android.systemui.statusbar.views.NetworkSpeedView").isNotNull { @@ -572,7 +618,7 @@ class SystemUILyric : BaseHook() { override fun onReceive(context: Context, intent: Intent) { when (intent.getStringExtra("type")) { "normal" -> { - if (!(this@SystemUILyric::clockView.isInitialized && this@SystemUILyric::targetView.isInitialized)) return + if (!(isReally)) return changeConfig() } @@ -592,4 +638,6 @@ class SystemUILyric : BaseHook() { } } + + val isPad get() = Tools.getSystemProperties(context, "ro.build.characteristics") == "tablet" } diff --git a/app/src/main/java/statusbar/lyric/hook/app/SystemUITest.kt b/app/src/main/java/statusbar/lyric/hook/app/SystemUITest.kt index 684cc154..e7421774 100644 --- a/app/src/main/java/statusbar/lyric/hook/app/SystemUITest.kt +++ b/app/src/main/java/statusbar/lyric/hook/app/SystemUITest.kt @@ -58,7 +58,7 @@ class SystemUITest : BaseHook() { private var lastTime: Int = 0 lateinit var context: Context lateinit var lastView: TextView - val testView by lazy { + val testTextView by lazy { TextView(context).apply { text = moduleRes.getString(R.string.app_name) isSingleLine = true @@ -91,26 +91,26 @@ class SystemUITest : BaseHook() { } private fun hook() { - hook = TextView::class.java.methodFinder().filterByName("setText").first().createHook { + hook = TextView::class.java.methodFinder().filterByName("onDraw").first().createHook { after { hookParam -> canHook { + val view = (hookParam.thisObject as TextView) val className = hookParam.thisObject::class.java.name - val text = "${hookParam.args[0]}".dispose() + val text = view.text.toString().dispose() text.isTimeSame { if (className.filterClassName()) { - val view = (hookParam.thisObject as TextView) view.filterView { val parentView = (view.parent as LinearLayout) val data = if (dataHashMap.size == 0) { - Data(className, view.id, parentView::class.java.name, parentView.id, false, 0) + Data(className, view.id, parentView::class.java.name, parentView.id, false, 0, view.textSize) } else { var index = 0 dataHashMap.values.forEach { data -> - if (data.textViewClassName == className && data.textViewID == view.id && data.parentClassName == parentView::class.java.name && data.parentID == parentView.id) { + if (data.textViewClassName == className && data.textViewId == view.id && data.parentViewClassName == parentView::class.java.name && data.parentViewId == parentView.id && data.textSize == view.textSize) { index += 1 } } - Data(className, view.id, parentView::class.java.name, parentView.id, index != 0, index) + Data(className, view.id, parentView::class.java.name, parentView.id, index != 0, index, view.textSize) } dataHashMap[view] = data moduleRes.getString(R.string.first_filter).format(data, dataHashMap.size).log() @@ -131,6 +131,20 @@ class SystemUITest : BaseHook() { return } } + if (config.relaxConditions) { + if (this.contains("周")) { + callback() + return + } + if (this.contains("月")) { + callback() + return + } + if (this.contains("日")) { + callback() + return + } + } } private fun String.filterClassName(): Boolean { @@ -181,23 +195,23 @@ class SystemUITest : BaseHook() { "ShowView" -> { val data = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - intent.getSerializableExtra("Data", Data::class.java) + intent.getParcelableExtra("Data", Data::class.java) } else { - @Suppress("DEPRECATION") intent.getSerializableExtra("Data") as Data + @Suppress("DEPRECATION") intent.getParcelableExtra("Data") }!! goMainThread { dataHashMap.forEach { (textview, da) -> - if (da.textViewClassName == data.textViewClassName && da.textViewID == data.textViewID && da.parentClassName == data.parentClassName && da.parentID == data.parentID && da.index == data.index) { + if (da.textViewClassName == data.textViewClassName && da.textViewId == data.textViewId && da.parentViewClassName == data.parentViewClassName && da.parentViewId == data.parentViewId && da.textSize == data.textSize && da.index == data.index) { if (this@SystemUITest::lastView.isInitialized) { - (lastView.parent as LinearLayout).removeView(testView) + (lastView.parent as LinearLayout).removeView(testTextView) lastView.showView() } textview.hideView() val parentLinearLayout = textview.parent as LinearLayout if (config.viewIndex == 0) { - parentLinearLayout.addView(testView, 0) + parentLinearLayout.addView(testTextView, 0) } else { - parentLinearLayout.addView(testView) + parentLinearLayout.addView(testTextView) } lastView = textview return@forEach diff --git a/app/src/main/java/statusbar/lyric/tools/Tools.kt b/app/src/main/java/statusbar/lyric/tools/Tools.kt index b3fb9431..9afe62d0 100644 --- a/app/src/main/java/statusbar/lyric/tools/Tools.kt +++ b/app/src/main/java/statusbar/lyric/tools/Tools.kt @@ -45,9 +45,6 @@ import kotlin.properties.ReadWriteProperty @SuppressLint("StaticFieldLeak") object Tools { - - private lateinit var target: TextView - private var index: Int = 0 val isMIUI by lazy { isPresent("android.provider.MiuiSettings") } @@ -68,6 +65,29 @@ object Tools { false } } + + @SuppressLint("PrivateApi") + fun getSystemProperties(context: Context, key: String): String { + var ret: String + try { + val cl = context.classLoader + val systemProperties = cl.loadClass("android.os.SystemProperties") + //参数类型 + val paramTypes: Array?> = arrayOfNulls(1) + paramTypes[0] = String::class.java + val get = systemProperties.getMethod("get", *paramTypes) + //参数 + val params = arrayOfNulls(1) + params[0] = key + ret = get.invoke(systemProperties, *params) as String + } catch (iAE: IllegalArgumentException) { + throw iAE + } catch (e: Exception) { + ret = "" + } + return ret + } + fun observableChange(initialValue: T, onChange: (oldValue: T, newValue: T) -> Unit): ReadWriteProperty { return Delegates.observable(initialValue) { _, oldVal, newVal -> if (oldVal != newVal) { @@ -77,28 +97,24 @@ object Tools { } fun View.isTargetView(): Boolean { - if (this@Tools::target.isInitialized) { - if (this == target) { - return true - } - } else { - val className = XposedOwnSP.config.textViewClassName - val textViewID = XposedOwnSP.config.textViewID - val parentClass = XposedOwnSP.config.parentClassName - val parentID = XposedOwnSP.config.parentID - if (className.isEmpty() || parentClass.isEmpty() || parentID == 0) { + val textViewClassName = XposedOwnSP.config.textViewClassName + val textViewId = XposedOwnSP.config.textViewId + val parentViewClassName = XposedOwnSP.config.parentViewClassName + val parentViewId = XposedOwnSP.config.parentViewId + val textSize = XposedOwnSP.config.textSize + if (textViewClassName.isEmpty() || parentViewClassName.isEmpty() || textViewId == 0 || parentViewId == 0|| textSize == 0f) { EzXHelper.moduleRes.getString(R.string.load_class_empty).log() return false } if (this is TextView) { - if (this::class.java.name == className) { - if (this.id == textViewID) { + if (this::class.java.name == textViewClassName) { + if (this.id == textViewId) { + if (this.textSize == textSize) { if (this.parent is LinearLayout) { val parentView = (this.parent as LinearLayout) - if (parentView::class.java.name == parentClass) { - if (parentID == parentView.id) { + if (parentView::class.java.name == parentViewClassName) { + if (parentViewId == parentView.id) { if (index == XposedOwnSP.config.index) { - target = this return true } else { index += 1 @@ -106,15 +122,15 @@ object Tools { } } } + } } } } - } return false } - fun String.regexReplace(pattern: String, newString: String): String { + private fun String.regexReplace(pattern: String, newString: String): String { val p = Pattern.compile("(?i)$pattern") val m = p.matcher(this) return m.replaceAll(newString) diff --git a/app/src/main/java/statusbar/lyric/tools/ViewTools.kt b/app/src/main/java/statusbar/lyric/tools/ViewTools.kt index 6ac6aa21..4d31b7b4 100644 --- a/app/src/main/java/statusbar/lyric/tools/ViewTools.kt +++ b/app/src/main/java/statusbar/lyric/tools/ViewTools.kt @@ -4,9 +4,15 @@ import android.animation.ArgbEvaluator import android.animation.ObjectAnimator import android.annotation.SuppressLint import android.view.View +import android.view.animation.AccelerateDecelerateInterpolator +import android.view.animation.AccelerateInterpolator import android.view.animation.AlphaAnimation import android.view.animation.Animation import android.view.animation.AnimationSet +import android.view.animation.BounceInterpolator +import android.view.animation.DecelerateInterpolator +import android.view.animation.LinearInterpolator +import android.view.animation.OvershootInterpolator import android.view.animation.ScaleAnimation import android.view.animation.TranslateAnimation import android.widget.ImageView @@ -22,40 +28,57 @@ object ViewTools { } } - fun switchViewInAnima(str: String?): Animation? { - val translateAnimation: Animation = when (str) { + fun switchViewInAnima(str: String?, interpolator: String?, time: Int?): Animation? { + val t = time?.toLong() ?: 500L + val translateAnimation: Animation? = when (str) { "Top" -> TranslateAnimation(0F, 0F, 100F, 0F) "Bottom" -> TranslateAnimation(0F, 0F, -100F, 0F) "Start" -> TranslateAnimation(100F, 0F, 0F, 0F) "End" -> TranslateAnimation(-100F, 0F, 0F, 0F) + "Fade" -> null "ScaleXY" -> ScaleAnimation(0f, 1f, 0f, 1f) "ScaleX" -> ScaleAnimation(0f, 1f, 1f, 1f) "ScaleY" -> ScaleAnimation(1f, 1f, 0f, 1f) else -> return null - }.apply { - duration = 300 + }?.apply { + duration = t } - return getAlphaAnimation(true).apply { - addAnimation(translateAnimation) + return getAlphaAnimation(true, t).apply { + translateAnimation?.let { addAnimation(it) } + switchInterpolator(interpolator) } } - fun switchViewOutAnima(str: String?): Animation? { - val translateAnimation: Animation = when (str) { + fun switchViewOutAnima(str: String?, time: Int?): Animation? { + val t = time?.toLong() ?: 500L + val translateAnimation: Animation? = when (str) { "Top" -> TranslateAnimation(0F, 0F, 0F, -100F) "Bottom" -> TranslateAnimation(0F, 0F, 0F, 100F) "Start" -> TranslateAnimation(0F, -100F, 0F, 0F) "End" -> TranslateAnimation(0F, 100F, 0F, 0F) + "Fade" -> null "ScaleXY" -> ScaleAnimation(1f, 0f, 1f, 0f) "ScaleX" -> ScaleAnimation(1f, 0f, 1f, 1f) "ScaleY" -> ScaleAnimation(1f, 1f, 1f, 0f) else -> return null - }.apply { - duration = 300 + }?.apply { + duration = t } - return getAlphaAnimation(false).apply { - addAnimation(translateAnimation) + return getAlphaAnimation(false, t).apply { + translateAnimation?.let { addAnimation(it) } + } + } + + private fun Animation.switchInterpolator(str: String?) { + interpolator = when (str) { + "Linear" -> LinearInterpolator() + "Accelerate" -> AccelerateInterpolator() + "Decelerate" -> DecelerateInterpolator() + "Accelerate&Decelerate" -> AccelerateDecelerateInterpolator() + "Overshoot" -> OvershootInterpolator() + "Bounce" -> BounceInterpolator() + else -> LinearInterpolator() } } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9a2700a6..11b054e2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -68,8 +68,6 @@ 范围:–500–500 歌词底边距 范围:–100–100 - * 正则表达式屏蔽 - 使用正则表达式匹配来屏蔽歌词 图标开关 图标大小 范围:状态栏高度的0%–100%,0代表以下时钟 @@ -104,7 +102,7 @@ 是否选择此Hook点 重启应用程序生效 强制显示图标 - 是否重复:%s;Index:%s + 是否重复:%s;Index:%s;textSize:%s 广播接收超时 请先重启系统界面,如依然超时请联系开发者 隐藏时间 @@ -114,10 +112,20 @@ 下划效果 左划效果 右划效果 + 淡出淡入 吸收效果 X轴翻页 Y轴翻页 随机效果 + 歌词动画插值器 + 线性效果 + 加速效果 + 减速效果 + 加速+减速 + 越界效果 + 弹跳效果 + 歌词动画时间 + 范围: 300~1000 * 歌词添加位置 靠左 靠右 @@ -137,9 +145,10 @@ * 的选项,重启系统界面生效 动态歌词速度(Beta) * 点击状态栏隐藏歌词 - 系统特性:切换外观后,墨-状态栏歌词 重启系统界面生效 + * 长按状态栏停止音乐 系统特供页 * MIUI隐藏网速 + * MIUI平板优化 仅右边 仅左边 两边 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 118b49b6..eceef043 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -68,8 +68,6 @@ 範圍:–500–500 歌詞底邊距 範圍:–100–100 - * 正則表達式屏蔽 - 使用正則表達式匹配來屏蔽歌詞 圖示開關 圖示大小 範圍:狀態列高度的0%–100%,0代表以下時鐘 @@ -104,7 +102,7 @@ 是否選擇此Hook點 重啟應用程式生效 強制顯示圖示 - 是否重複:%s;Index:%s + 是否重複:%s;Index:%s;textSize:%s 廣播接收超時 請先重啟系統UI,如依然超時請聯繫開發者 隱藏時間 @@ -114,10 +112,20 @@ 下滑效果 左劃效果 右劃效果 + 淡出淡入 吸收效果 X軸翻頁 Y軸翻頁 隨機效果 + 歌詞動畫插值器 + 线性效果 + 加速效果 + 減速效果 + 加速+減速 + 越界效果 + 彈跳效果 + 歌詞動畫時間 + 範圍: 300~1000 * 歌詞添加位置 靠左 靠右 @@ -137,9 +145,10 @@ * 的選項,重啟系統UI生效 動態歌詞速度(Beta) * 點擊狀態列隱藏歌詞 - 系統特性:切換外觀后,墨-狀態列歌詞 重啟系統UI生效 + * 長按狀態列停止音樂 系統特供頁 * MIUI隱藏網速 + * MIUI平板優化 僅右邊 僅左邊 兩邊 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de34b83b..e575c552 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -68,8 +68,6 @@ Range –500–500 Lyric Bottom Margins Range –100–100 - * Regex Replace - Block lyrics with regular expression matching Icon Switch Icon Size Range: 0%–100% of the height of the status bar, 0 is the following clock @@ -105,7 +103,7 @@ Restart App Effect Force The Icon To Be Displayed - IsRepeat: %s;Index: %s + IsRepeat: %s;Index: %s;textSize: %s Broadcast Receive Timeout Please restart the SystemUI first, if it still times out, please contact the developer Hide Time @@ -115,10 +113,20 @@ Bottom Start End + Fade ScaleXY ScaleX ScaleY Random + Lyric Animation Interpolator + Linear + Accelerate + Decelerate + Accelerate+Decelerate + Overshoot + Bounce + Lyric Animation Duration + Range 300~1000 * Lyric Add Location Start End @@ -138,9 +146,10 @@ Option with * , Restart SystemUI to take effect Dynamic Lyric Speed(Beta) * Click Status Bar To Hide Lyric - System features: After switching appearance, the ink - status bar lyrics restart the system interface to take effect + * Long Click Status Bar Stop Music System Special Page * MIUI Hide Network Speed + * MIUI tablet optimization Lyric Blurred Edges Type End Lyric Blurred Edges Type Start Lyric Blurred Edges Type All diff --git a/blockmiui b/blockmiui index 8274b901..6b6bf3fd 160000 --- a/blockmiui +++ b/blockmiui @@ -1 +1 @@ -Subproject commit 8274b90158ec42ef9942ba9bbd2a13b0eadc7966 +Subproject commit 6b6bf3fdeaa8310cde3ab22eabf79324d92b358d diff --git a/build.gradle.kts b/build.gradle.kts index 820e8acd..50a2101e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,8 +4,8 @@ buildscript { mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:8.1.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0") + classpath("com.android.tools.build:gradle:8.1.2") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") } } diff --git a/gradle.properties b/gradle.properties index 28e8eb42..9d162ce7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,4 +19,11 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official +# Enable BuildConfig +android.defaults.buildfeatures.buildconfig=true +# Enable parallel build org.gradle.parallel=true +# Enable configure on demand +org.gradle.configureondemand=true +# Enable build cache +org.gradle.caching=true \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 241de243..31dc3ea7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,13 @@ +@file:Suppress("UnstableApiUsage") + dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() - maven("https://api.xposed.info") maven("https://jitpack.io") + maven("https://api.xposed.info") } } rootProject.name = "Statusbar Lyric" -include(":app") -include(":blockmiui") -include(":xtoast") +include(":app", ":blockmiui", ":xtoast")