From 794e1a32fea96f632cc2bd5784ec59f629e03e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A8=E7=9A=84=E5=90=8D=E5=AD=97?= <您的邮箱> Date: Fri, 24 Oct 2025 16:53:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E6=9D=A1=E4=BA=A4=E4=BA=92=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复拖拽时圆球消失问题 - 添加动态轨道高度变化效果(按住时4dp,松开时2dp) - 优化圆球大小设置(固定14dp) - 添加ProGuard规则保护DefaultTimeBar反射字段 - 改进触摸事件处理逻辑 - 增强拖拽体验的流畅性 修复内容: - CustomSeekView: 重构触摸事件处理和动态高度调整 - 布局文件: 统一设置圆球大小为14dp - ProGuard: 保护Media3 DefaultTimeBar字段不被混淆 --- app/proguard-rules.pro | 7 +++ .../leanback/res/layout/view_control_seek.xml | 4 +- .../android/tv/ui/custom/CustomSeekView.java | 61 +++++++------------ .../mobile/res/layout/view_control_seek.xml | 4 +- 4 files changed, 32 insertions(+), 44 deletions(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 8fea74b4..3164b172 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -92,5 +92,12 @@ -keep class com.sun.jna.** { *; } -keep class com.east.android.zlive.** { *; } +# Media3 DefaultTimeBar - 保护反射访问的字段 +-keep class androidx.media3.ui.DefaultTimeBar { + int barHeight; + int scrubberEnabledSize; + int scrubberDisabledSize; +} + # Zxing -keep class com.google.zxing.** { *; } \ No newline at end of file diff --git a/app/src/leanback/res/layout/view_control_seek.xml b/app/src/leanback/res/layout/view_control_seek.xml index 6e5f2f51..f91d88f3 100644 --- a/app/src/leanback/res/layout/view_control_seek.xml +++ b/app/src/leanback/res/layout/view_control_seek.xml @@ -29,8 +29,8 @@ android:nextFocusUp="@id/next" android:nextFocusDown="@id/timeBar" app:bar_height="2dp" - app:scrubber_enabled_size="12dp" - app:scrubber_disabled_size="12dp" + app:scrubber_enabled_size="14dp" + app:scrubber_disabled_size="14dp" app:played_color="#FFEB3B" app:scrubber_color="#FFEB3B" app:buffered_color="#80FFEB3B" diff --git a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java index 98d40215..5d0d3cea 100644 --- a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java +++ b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java @@ -59,22 +59,22 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen timeBar.addListener(this); refresh = this::refresh; - // 设置触摸事件监听器,实现动态尺寸调整 + // 添加触摸事件处理,实现按住时圆球变大的效果 timeBar.setOnTouchListener((v, event) -> { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!isPressed) { isPressed = true; - // 按下时:滑杆4dp,圆球16dp - setTimeBarSize(4, 16); + // 按住时:轨道变高到4dp + setTimeBarHeight(4); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (isPressed) { isPressed = false; - // 松开时:滑杆2dp,圆球12dp - setTimeBarSize(2, 12); + // 松开时:轨道恢复到2dp + setTimeBarHeight(2); } break; } @@ -95,54 +95,32 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen } /** - * 动态设置进度条高度和拖拽手柄大小 - * @param barHeightDp 滑杆高度值(dp) - * @param scrubberSizeDp 拖拽手柄大小(dp) + * 动态调整进度条高度 + * @param barHeightDp 轨道高度(dp) */ - private void setTimeBarSize(int barHeightDp, int scrubberSizeDp) { - // 设置滑杆高度 + private void setTimeBarHeight(int barHeightDp) { int barHeightPx = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, barHeightDp, getContext().getResources().getDisplayMetrics() ); - // 设置拖拽手柄大小 - int scrubberSizePx = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - scrubberSizeDp, - getContext().getResources().getDisplayMetrics() - ); - - // 通过反射设置DefaultTimeBar的内部属性 + // 尝试通过反射设置DefaultTimeBar的内部barHeight字段 try { - // 设置滑杆高度 java.lang.reflect.Field barHeightField = timeBar.getClass().getDeclaredField("barHeight"); barHeightField.setAccessible(true); barHeightField.setInt(timeBar, barHeightPx); - // 设置拖拽手柄大小 - 尝试多个可能的字段名 - String[] scrubberFields = {"scrubberSize", "scrubberEnabledSize", "scrubberDisabledSize"}; - for (String fieldName : scrubberFields) { - try { - java.lang.reflect.Field scrubberField = timeBar.getClass().getDeclaredField(fieldName); - scrubberField.setAccessible(true); - scrubberField.setInt(timeBar, scrubberSizePx); - break; // 成功设置后退出循环 - } catch (NoSuchFieldException e) { - // 继续尝试下一个字段名 - } - } - - // 刷新视图 - timeBar.requestLayout(); + // 强制刷新 timeBar.invalidate(); - } catch (Exception e) { - // 如果反射失败,使用备用方案 - e.printStackTrace(); - // 备用方案:重新设置布局参数 - timeBar.getLayoutParams().height = barHeightPx; timeBar.requestLayout(); + } catch (Exception e) { + // 如果反射失败,尝试调整布局参数 + android.util.Log.w("CustomSeekView", "Failed to set bar height via reflection: " + e.getMessage()); + if (timeBar.getLayoutParams() != null) { + timeBar.getLayoutParams().height = barHeightPx; + timeBar.requestLayout(); + } } } @@ -224,7 +202,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen positionView.setText(player.stringToTime(actualPosition)); } } - }, 50); // 延迟50ms刷新 + }, 100); // 增加延迟时间,确保拖拽状态完全结束 } @Override @@ -247,6 +225,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen @Override public void onScrubStop(@NonNull TimeBar timeBar, long position, boolean canceled) { scrubbing = false; + if (!canceled) { // 立即设置进度条位置到目标位置,避免圆球跳回原始位置 timeBar.setPosition(position); @@ -259,5 +238,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen player.play(); } } + + // 不干预DefaultTimeBar的圆球绘制,让它自己处理 } } diff --git a/app/src/mobile/res/layout/view_control_seek.xml b/app/src/mobile/res/layout/view_control_seek.xml index 829fed7f..9461a2f2 100644 --- a/app/src/mobile/res/layout/view_control_seek.xml +++ b/app/src/mobile/res/layout/view_control_seek.xml @@ -23,8 +23,8 @@ android:layout_marginEnd="8dp" android:layout_weight="1" app:bar_height="2dp" - app:scrubber_enabled_size="12dp" - app:scrubber_disabled_size="12dp" + app:scrubber_enabled_size="14dp" + app:scrubber_disabled_size="14dp" app:played_color="#FFEB3B" app:scrubber_color="#FFEB3B" app:buffered_color="#80FFEB3B" />