feat: 优化播放进度条交互体验

- 修复拖拽时圆球消失问题
- 添加动态轨道高度变化效果(按住时4dp,松开时2dp)
- 优化圆球大小设置(固定14dp)
- 添加ProGuard规则保护DefaultTimeBar反射字段
- 改进触摸事件处理逻辑
- 增强拖拽体验的流畅性

修复内容:
- CustomSeekView: 重构触摸事件处理和动态高度调整
- 布局文件: 统一设置圆球大小为14dp
- ProGuard: 保护Media3 DefaultTimeBar字段不被混淆
This commit is contained in:
您的名字
2025-10-24 16:53:19 +08:00
parent 8357ebefcf
commit 56251db9e7
4 changed files with 32 additions and 44 deletions
+7
View File
@@ -92,5 +92,12 @@
-keep class com.sun.jna.** { *; } -keep class com.sun.jna.** { *; }
-keep class com.east.android.zlive.** { *; } -keep class com.east.android.zlive.** { *; }
# Media3 DefaultTimeBar - 保护反射访问的字段
-keep class androidx.media3.ui.DefaultTimeBar {
int barHeight;
int scrubberEnabledSize;
int scrubberDisabledSize;
}
# Zxing # Zxing
-keep class com.google.zxing.** { *; } -keep class com.google.zxing.** { *; }
@@ -29,8 +29,8 @@
android:nextFocusUp="@id/next" android:nextFocusUp="@id/next"
android:nextFocusDown="@id/timeBar" android:nextFocusDown="@id/timeBar"
app:bar_height="2dp" app:bar_height="2dp"
app:scrubber_enabled_size="12dp" app:scrubber_enabled_size="14dp"
app:scrubber_disabled_size="12dp" app:scrubber_disabled_size="14dp"
app:played_color="#FFEB3B" app:played_color="#FFEB3B"
app:scrubber_color="#FFEB3B" app:scrubber_color="#FFEB3B"
app:buffered_color="#80FFEB3B" app:buffered_color="#80FFEB3B"
@@ -59,22 +59,22 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
timeBar.addListener(this); timeBar.addListener(this);
refresh = this::refresh; refresh = this::refresh;
// 设置触摸事件监听器,实现动态尺寸调整 // 添加触摸事件处理,实现按住时圆球变大的效果
timeBar.setOnTouchListener((v, event) -> { timeBar.setOnTouchListener((v, event) -> {
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
if (!isPressed) { if (!isPressed) {
isPressed = true; isPressed = true;
// 按时:滑杆4dp,圆球16dp // 按时:轨道变高到4dp
setTimeBarSize(4, 16); setTimeBarHeight(4);
} }
break; break;
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:
if (isPressed) { if (isPressed) {
isPressed = false; isPressed = false;
// 松开时:滑杆2dp,圆球12dp // 松开时:轨道恢复到2dp
setTimeBarSize(2, 12); setTimeBarHeight(2);
} }
break; break;
} }
@@ -95,56 +95,34 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
} }
/** /**
* 动态设置进度条高度和拖拽手柄大小 * 动态调整进度条高度
* @param barHeightDp 滑杆高度dp * @param barHeightDp 轨道高度(dp
* @param scrubberSizeDp 拖拽手柄大小(dp
*/ */
private void setTimeBarSize(int barHeightDp, int scrubberSizeDp) { private void setTimeBarHeight(int barHeightDp) {
// 设置滑杆高度
int barHeightPx = (int) TypedValue.applyDimension( int barHeightPx = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, TypedValue.COMPLEX_UNIT_DIP,
barHeightDp, barHeightDp,
getContext().getResources().getDisplayMetrics() getContext().getResources().getDisplayMetrics()
); );
// 设置拖拽手柄大小 // 尝试通过反射设置DefaultTimeBar的内部barHeight字段
int scrubberSizePx = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
scrubberSizeDp,
getContext().getResources().getDisplayMetrics()
);
// 通过反射设置DefaultTimeBar的内部属性
try { try {
// 设置滑杆高度
java.lang.reflect.Field barHeightField = timeBar.getClass().getDeclaredField("barHeight"); java.lang.reflect.Field barHeightField = timeBar.getClass().getDeclaredField("barHeight");
barHeightField.setAccessible(true); barHeightField.setAccessible(true);
barHeightField.setInt(timeBar, barHeightPx); 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(); timeBar.invalidate();
timeBar.requestLayout();
} catch (Exception e) { } catch (Exception e) {
// 如果反射失败,使用备用方案 // 如果反射失败,尝试调整布局参数
e.printStackTrace(); android.util.Log.w("CustomSeekView", "Failed to set bar height via reflection: " + e.getMessage());
// 备用方案:重新设置布局参数 if (timeBar.getLayoutParams() != null) {
timeBar.getLayoutParams().height = barHeightPx; timeBar.getLayoutParams().height = barHeightPx;
timeBar.requestLayout(); timeBar.requestLayout();
} }
} }
}
private void start() { private void start() {
removeCallbacks(refresh); removeCallbacks(refresh);
@@ -224,7 +202,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
positionView.setText(player.stringToTime(actualPosition)); positionView.setText(player.stringToTime(actualPosition));
} }
} }
}, 50); // 延迟50ms刷新 }, 100); // 增加延迟时间,确保拖拽状态完全结束
} }
@Override @Override
@@ -247,6 +225,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
@Override @Override
public void onScrubStop(@NonNull TimeBar timeBar, long position, boolean canceled) { public void onScrubStop(@NonNull TimeBar timeBar, long position, boolean canceled) {
scrubbing = false; scrubbing = false;
if (!canceled) { if (!canceled) {
// 立即设置进度条位置到目标位置,避免圆球跳回原始位置 // 立即设置进度条位置到目标位置,避免圆球跳回原始位置
timeBar.setPosition(position); timeBar.setPosition(position);
@@ -259,5 +238,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
player.play(); player.play();
} }
} }
// 不干预DefaultTimeBar的圆球绘制,让它自己处理
} }
} }
@@ -23,8 +23,8 @@
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_weight="1" android:layout_weight="1"
app:bar_height="2dp" app:bar_height="2dp"
app:scrubber_enabled_size="12dp" app:scrubber_enabled_size="14dp"
app:scrubber_disabled_size="12dp" app:scrubber_disabled_size="14dp"
app:played_color="#FFEB3B" app:played_color="#FFEB3B"
app:scrubber_color="#FFEB3B" app:scrubber_color="#FFEB3B"
app:buffered_color="#80FFEB3B" /> app:buffered_color="#80FFEB3B" />