Skip to content

Commit fee2515

Browse files
authored
opt: 重写侧边音量条长按展开 & 内联音量/亮度条优化 (#1310)
* fix: 控制中心亮度条数据内联显示在调节时字体变成白色 * fix: 控制中心数据内联显示切换分辨率后字体大小异常 * fix: 控制中心亮度条数据内联显示长按展开动画中,出现错位 * opt: 重写侧边音量条长按展开 * * fix: 控制中心亮度条数据内联显示在调节时字体变成白色
1 parent 38142ba commit fee2515

3 files changed

Lines changed: 170 additions & 137 deletions

File tree

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/module/hook/systemui/plugin/StartCollpasedColumnPress.kt

Lines changed: 104 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,30 @@ import android.os.Looper
2727
import android.view.HapticFeedbackConstants
2828
import android.view.MotionEvent
2929
import android.view.View
30+
import android.view.ViewGroup
31+
import com.sevtinge.hyperceiler.hook.utils.callMethod
32+
import com.sevtinge.hyperceiler.hook.utils.getBooleanField
33+
import com.sevtinge.hyperceiler.hook.utils.getFloatField
34+
import com.sevtinge.hyperceiler.hook.utils.getObjectField
35+
import com.sevtinge.hyperceiler.hook.utils.getObjectFieldAs
3036
import com.sevtinge.hyperceiler.hook.utils.log.XposedLogUtils.logD
37+
import com.sevtinge.hyperceiler.hook.utils.replaceMethod
38+
import com.sevtinge.hyperceiler.hook.utils.setLongField
39+
import com.sevtinge.hyperceiler.hook.utils.setObjectField
3140
import de.robv.android.xposed.XC_MethodHook
3241
import de.robv.android.xposed.XC_MethodReplacement
3342
import de.robv.android.xposed.XposedBridge
3443
import de.robv.android.xposed.XposedHelpers
44+
import io.github.kyuubiran.ezxhelper.core.finder.MethodFinder.`-Static`.methodFinder
3545
import io.github.kyuubiran.ezxhelper.core.util.ClassUtil.loadClass
46+
import io.github.kyuubiran.ezxhelper.xposed.dsl.HookFactory.`-Static`.createAfterHook
47+
import io.github.kyuubiran.ezxhelper.xposed.dsl.HookFactory.`-Static`.createBeforeHook
48+
import kotlinx.coroutines.CoroutineScope
49+
import kotlinx.coroutines.Dispatchers
50+
import kotlinx.coroutines.Job
51+
import kotlinx.coroutines.delay
52+
import kotlinx.coroutines.launch
53+
import kotlin.collections.get
3654

3755
object StartCollpasedColumnPress {
3856
fun initLoaderHook(classLoader: ClassLoader) {
@@ -46,122 +64,101 @@ object StartCollpasedColumnPress {
4664
loadClass("com.android.systemui.miui.volume.MiuiVolumeSeekBar", classLoader)
4765
}
4866

49-
XposedHelpers.findAndHookMethod(
50-
miuiVolumeDialogView, "onFinishInflate",
51-
object : XC_MethodHook() {
52-
override fun afterHookedMethod(param: MethodHookParam?) {
53-
val thisObj = param?.thisObject
54-
val mExpandButton =
55-
XposedHelpers.getObjectField(thisObj, "mExpandButton") as View
56-
mExpandButton.setOnClickListener(null)
57-
mExpandButton.alpha = 0f
58-
mExpandButton.isClickable = false
59-
mExpandButton.visibility = View.GONE
60-
}
61-
})
62-
63-
XposedHelpers.findAndHookMethod(
64-
miuiVolumeDialogView, "notifyAccessibilityChanged", Boolean::class.java,
65-
object : XC_MethodHook() {
66-
override fun afterHookedMethod(param: MethodHookParam?) {
67-
val thisObj = param?.thisObject
68-
val mExpandButton =
69-
XposedHelpers.getObjectField(thisObj, "mExpandButton") as View
70-
71-
mExpandButton.setOnClickListener(null)
72-
mExpandButton.isClickable = false
73-
mExpandButton.visibility = View.GONE
74-
}
75-
})
76-
77-
XposedBridge.hookAllConstructors(miuiVolumeDialogMotion, object : XC_MethodHook() {
78-
override fun afterHookedMethod(param: MethodHookParam?) {
79-
val thisObj = param?.thisObject
80-
val mExpandButton = XposedHelpers.getObjectField(thisObj, "mExpandButton") as View
81-
82-
mExpandButton.setOnTouchListener(null)
83-
}
84-
})
67+
var longClick = false
68+
var longPressJob: Job? = null
69+
70+
fun View.startScaleAnimation() {
71+
longClick = true
72+
animate()
73+
.scaleX(0.92f)
74+
.scaleY(0.92f)
75+
.setDuration(300)
76+
.start()
77+
}
8578

79+
fun View.stopScaleAnimation() {
80+
longClick = false
81+
animate()
82+
.scaleX(1.0f)
83+
.scaleY(1.0f)
84+
.setDuration(300)
85+
.start()
86+
}
8687

87-
var longClick = false
88-
XposedHelpers.findAndHookMethod(
89-
miuiVolumeDialogMotion, "lambda\$processExpandTouch\$1",
90-
object : XC_MethodReplacement() {
91-
override fun replaceHookedMethod(param: MethodHookParam?): Any? {
92-
val thisObj = param?.thisObject
93-
if (XposedHelpers.getBooleanField(thisObj, "mExpanded") || !longClick) return null
94-
val mVolumeView = XposedHelpers.getObjectField(thisObj, "mVolumeView") as View
95-
96-
logD("StartCollpasedColumnPress", "miui.systemui.plugin", "processExpandTouch")
97-
98-
with(AnimatorSet()) {
99-
playTogether(
100-
ObjectAnimator.ofFloat(mVolumeView, "scaleX", 0.95f),
101-
ObjectAnimator.ofFloat(mVolumeView, "scaleY", 0.95f)
102-
)
103-
duration = 100L
104-
addListener(object : AnimatorListenerAdapter() {
105-
override fun onAnimationEnd(animation: Animator) {
106-
super.onAnimationEnd(animation)
107-
mVolumeView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
108-
val mVolumeExpandCollapsedAnimator =
109-
XposedHelpers.getObjectField(thisObj, "mVolumeExpandCollapsedAnimator")
110-
val mCallback = XposedHelpers.getObjectField(thisObj, "mCallback")
111-
XposedHelpers.callMethod(mVolumeExpandCollapsedAnimator, "calculateFromViewValues", true)
112-
XposedHelpers.callMethod(mCallback, "onExpandClicked")
113-
114-
mVolumeView.scaleX = 1f
115-
mVolumeView.scaleY = 1f
116-
}
117-
})
118-
start()
88+
miuiVolumeDialogView.methodFinder().apply {
89+
filterByName("onFinishInflate")
90+
.first().createAfterHook {
91+
it.thisObject.getObjectFieldAs<View>("mExpandButton").apply {
92+
alpha = 0f
93+
isClickable = false
94+
visibility = View.GONE
95+
setOnClickListener(null)
11996
}
120-
return null
121-
}
12297

123-
})
124-
125-
XposedHelpers.findAndHookMethod(
126-
miuiVolumeSeekBar, "onTouchEvent", MotionEvent::class.java,
127-
object : XC_MethodHook() {
128-
override fun afterHookedMethod(param: MethodHookParam?) {
129-
super.afterHookedMethod(param)
130-
val thisObj = param?.thisObject
131-
val mSeekBarOnclickListener =
132-
XposedHelpers.getObjectField(thisObj, "mSeekBarOnclickListener")
133-
134-
val handler = Handler(Looper.getMainLooper())
135-
val mLongPressRunnable = Runnable {
136-
val mMoveY = XposedHelpers.getFloatField(thisObj, "mMoveY")
137-
if (longClick) {
138-
thisObj as View
139-
XposedHelpers.callMethod(mSeekBarOnclickListener, "onClick")
140-
}
98+
}
99+
filterByName("notifyAccessibilityChanged")
100+
.filterByParamTypes {
101+
it[0] == Boolean::class.java
102+
}.first().createAfterHook {
103+
it.thisObject.getObjectFieldAs<View>("mExpandButton").apply {
104+
isClickable = false
105+
visibility = View.GONE
106+
setOnClickListener(null)
141107
}
108+
}
109+
}
142110

143-
if (mSeekBarOnclickListener != null) {
144-
val motionEvent = param?.args?.get(0) as MotionEvent
145-
146-
val action = motionEvent.action
147-
when (action) {
148-
0 -> {
149-
longClick = true
150-
XposedHelpers.setLongField(thisObj, "mCurrentMS", 0L)
151-
handler.postDelayed(mLongPressRunnable, 300L)
152-
}
153-
154-
1 -> {
155-
longClick = false
156-
XposedHelpers.setLongField(thisObj, "mCurrentMS", 0L)
157-
}
158-
159-
2 -> {
160-
longClick = false
111+
miuiVolumeDialogMotion.methodFinder().apply {
112+
filterByName("lambda\$processExpandTouch\$1")
113+
.first().createBeforeHook {
114+
it.thisObject.setObjectField("mIsExpandButton",true)
115+
}
116+
}
117+
miuiVolumeSeekBar.methodFinder()
118+
.filterByName("onTouchEvent")
119+
.filterByParamTypes {
120+
it[0] == MotionEvent::class.java
121+
}.first().createAfterHook {
122+
val mSeekBarOnclickListener = it.thisObject.getObjectField("mSeekBarOnclickListener")
123+
val mSeekBarAnimListener = it.thisObject.getObjectField("mSeekBarAnimListener")!!
124+
val volumePanelViewController = mSeekBarAnimListener.getObjectField("this\$0")!!
125+
val mVolumeView = volumePanelViewController.getObjectFieldAs<View>("mVolumeView")
126+
127+
it.thisObject.setLongField("mCurrentMS",0L)
128+
if (mSeekBarOnclickListener != null) {
129+
val motionEvent = it.args?.get(0) as MotionEvent
130+
when (motionEvent.action) {
131+
MotionEvent.ACTION_DOWN -> {
132+
if ( !volumePanelViewController.getBooleanField("mExpanded") ){
133+
longPressJob = CoroutineScope(Dispatchers.Main).launch {
134+
mVolumeView.startScaleAnimation()
135+
delay(300)
136+
val mMoveY = it.thisObject.getFloatField("mMoveY")
137+
if (longClick && mMoveY < 10f){
138+
mVolumeView.apply {
139+
scaleY = 1f
140+
scaleX = 1f
141+
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
142+
}
143+
mSeekBarOnclickListener.callMethod( "onClick")
144+
145+
}
146+
147+
}
161148
}
162149
}
150+
MotionEvent.ACTION_UP->{
151+
mVolumeView.stopScaleAnimation()
152+
longPressJob?.cancel()
153+
}
154+
MotionEvent.ACTION_CANCEL -> {
155+
mVolumeView.stopScaleAnimation()
156+
longPressJob?.cancel()
157+
}
163158
}
159+
164160
}
165-
})
161+
}
162+
166163
}
167164
}

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/module/hook/systemui/plugin/VolumeOrQSBrightnessValue.kt

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ import android.widget.SeekBar
3131
import android.widget.TextView
3232
import androidx.core.util.TypedValueCompat.dpToPx
3333
import com.sevtinge.hyperceiler.hook.module.hook.systemui.base.api.mSupportSV
34+
import com.sevtinge.hyperceiler.hook.utils.blur.MiBlurUtilsKt.chooseBackgroundBlurContainer
3435
import com.sevtinge.hyperceiler.hook.utils.callMethod
3536
import com.sevtinge.hyperceiler.hook.utils.callStaticMethod
3637
import com.sevtinge.hyperceiler.hook.utils.getObjectField
38+
import com.sevtinge.hyperceiler.hook.utils.getObjectFieldAs
39+
import com.sevtinge.hyperceiler.hook.utils.getObjectFieldOrNullAs
3740
import com.sevtinge.hyperceiler.hook.utils.prefs.PrefsUtils.mPrefsMap
3841
import com.sevtinge.hyperceiler.hook.utils.replaceMethod
3942
import de.robv.android.xposed.XposedHelpers
@@ -250,12 +253,12 @@ object VolumeOrQSBrightnessValue {
250253
.filterByName("frameCallback")
251254
.first().createAfterHook {
252255
val sliderController = it.thisObject.getObjectField("sliderController")
253-
val item = callMethod(sliderController as String?, "getVToggleSliderInner") as ViewGroup
256+
val item = sliderController?.callMethod("getVToggleSliderInner") as ViewGroup
254257
val topValue = item.findViewByIdName("top_text") as TextView
255-
val icon = callMethod(sliderController, "getVIcon") as View
258+
val icon = sliderController.callMethod("getVIcon") as View
256259

257-
val sizeBgX = it.thisObject.getObjectField("sizeBgX") as Float
258-
val left = (dpToPx(40f, topValue.resources.displayMetrics).toInt() - icon.layoutParams.width) / 2
260+
val sizeBgX = it.thisObject.getObjectFieldAs<Float>("sizeBgX")
261+
val left = (dpToPx(50f, topValue.resources.displayMetrics) - icon.layoutParams.width).toInt() / 2
259262
topValue.left = icon.left - left
260263
topValue.right = icon.right + left
261264
topValue.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13f + 2f * sizeBgX)
@@ -269,8 +272,8 @@ object VolumeOrQSBrightnessValue {
269272
val topText = brightnessPanel.findViewByIdName("top_text") as TextView
270273
topText.textAlignment = TextView.TEXT_ALIGNMENT_CENTER
271274
val mLayoutParams =
272-
(topText.layoutParams as FrameLayout.LayoutParams).apply {
273-
width = dpToPx(40f, topText.resources.displayMetrics).toInt()
275+
(topText.layoutParams as ViewGroup.LayoutParams).apply {
276+
width = dpToPx(50f, topText.resources.displayMetrics).toInt()
274277
}
275278
topText.layoutParams = mLayoutParams
276279
}
@@ -284,12 +287,12 @@ object VolumeOrQSBrightnessValue {
284287
val viewHolder = it.result
285288

286289
if (viewHolder != null) {
287-
val root = XposedHelpers.getObjectField(viewHolder, "itemView") as ViewGroup
290+
val root = viewHolder.getObjectFieldAs<ViewGroup>("itemView")
288291
val topText = root.findViewByIdName("top_text") as TextView
289292
topText.textAlignment = TextView.TEXT_ALIGNMENT_CENTER
290293
val mLayoutParams =
291-
(topText.layoutParams as FrameLayout.LayoutParams).apply {
292-
width = dpToPx(40f, root.resources.displayMetrics).toInt()
294+
(topText.layoutParams as ViewGroup.LayoutParams).apply {
295+
width = dpToPx(50f, root.resources.displayMetrics).toInt()
293296
}
294297
topText.layoutParams = mLayoutParams
295298
}
@@ -302,33 +305,56 @@ object VolumeOrQSBrightnessValue {
302305
val toggleSliderViewHolder =
303306
loadClass("miui.systemui.controlcenter.panel.main.recyclerview.ToggleSliderViewHolder", classLoader)
304307

305-
toggleSliderViewHolder.methodFinder()
306-
.filterByName("updateBlendBlur")
307-
.first().createAfterHook {
308-
val context = it.thisObject.callMethod("getContext") as Context
308+
toggleSliderViewHolder.methodFinder().apply {
309+
filterByName("updateSize")
310+
.first().createAfterHook {
311+
val item = it.thisObject.getObjectField("itemView") as View
312+
val topValue = item.findViewByIdName("top_text") as TextView
313+
topValue.textAlignment = TextView.TEXT_ALIGNMENT_CENTER
314+
topValue.setTextSize(TypedValue.COMPLEX_UNIT_DIP,13f)
309315

310-
val item = it.thisObject.getObjectField("itemView") as View
311-
val topValue = item.findViewByIdName("top_text") as TextView
316+
}
317+
filterByName("updateBlendBlur")
318+
.first().createAfterHook {
319+
val context = it.thisObject.callMethod("getContext") as Context
312320

313-
if (!controlCenterUtils.getBackgroundBlurOpenedInDefaultTheme(context)) {
314-
val colorId = context.resources.getIdentifier("toggle_slider_top_text_color", "color", "miui.systemui.plugin")
315-
val color = item.resources.getColor(colorId, null)
321+
val item = it.thisObject.getObjectField("itemView") as View
322+
val topValue = item.findViewByIdName("top_text") as TextView
316323

317-
topValue.setTextColor(color)
318-
miBlurCompat.setMiViewBlurModeCompat(topValue, 0)
319-
miBlurCompat.clearMiBackgroundBlendColorCompat(topValue)
320-
return@createAfterHook
321-
}
322-
// Color.WHITE Color.parseColor("#959595")
323-
topValue.setTextColor(Color.WHITE)
324-
miBlurCompat.setMiViewBlurModeCompat(topValue, 3)
324+
if (!controlCenterUtils.getBackgroundBlurOpenedInDefaultTheme(context)) {
325+
val colorId = context.resources.getIdentifier(
326+
"toggle_slider_top_text_color",
327+
"color",
328+
"miui.systemui.plugin"
329+
)
330+
val color = item.resources.getColor(colorId, null)
325331

326-
val colorArray: IntArray =
327-
context.resources.getIntArrayBy("toggle_slider_icon_blend_colors", plugin)
328-
miBlurCompat.setMiBackgroundBlendColors(topValue, colorArray, 1f)
332+
topValue.setTextColor(color)
333+
miBlurCompat.setMiViewBlurModeCompat(topValue, 0)
334+
miBlurCompat.clearMiBackgroundBlendColorCompat(topValue)
335+
return@createAfterHook
336+
}
337+
topValue.setTextColor(Color.WHITE)
338+
val inMirror = it.thisObject.getObjectField("inMirror") as Boolean
339+
topValue.chooseBackgroundBlurContainer(
340+
if (inMirror) {
341+
with(it.thisObject) {
342+
getObjectFieldOrNullAs<View>("mirrorBlendBackground")
343+
?: getObjectFieldOrNullAs<View>("mirrorBlurProvider")
344+
}
345+
} else {
346+
null
347+
}
348+
)
329349

330-
}
350+
miBlurCompat.setMiViewBlurModeCompat(topValue, 3)
351+
352+
val colorArray: IntArray =
353+
context.resources.getIntArrayBy("toggle_slider_icon_blend_colors", plugin)
354+
miBlurCompat.setMiBackgroundBlendColors(topValue, colorArray, 1f)
331355

356+
}
357+
}
332358
}
333359

334360
private fun convertToPercentageProgress(

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/utils/blur/MiBlurUtilsKt.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ import android.view.*
2323

2424
object MiBlurUtilsKt {
2525

26+
27+
private val chooseBackgroundBlurContainer by lazy {
28+
View::class.java.getDeclaredMethod("chooseBackgroundBlurContainer", View::class.java)
29+
}
30+
2631
private val setMiViewBlurMode by lazy {
2732
View::class.java.getDeclaredMethod("setMiViewBlurMode", Integer.TYPE)
2833
}
@@ -55,6 +60,11 @@ object MiBlurUtilsKt {
5560
View::class.java.getDeclaredMethod("disableMiBackgroundContainBelow", java.lang.Boolean.TYPE)
5661
}
5762

63+
64+
fun View.chooseBackgroundBlurContainer(container: View?) {
65+
chooseBackgroundBlurContainer.invoke(this, container)
66+
}
67+
5868
fun View.setMiBackgroundBlurMode(mode: Int) {
5969
setMiBackgroundBlurMode.invoke(this, mode)
6070
}

0 commit comments

Comments
 (0)