feat: 优化播放进度条交互体验
- 修复拖拽时圆球消失问题 - 添加动态轨道高度变化效果(按住时4dp,松开时2dp) - 优化圆球大小设置(固定14dp) - 添加ProGuard规则保护DefaultTimeBar反射字段 - 改进触摸事件处理逻辑 - 增强拖拽体验的流畅性 修复内容: - CustomSeekView: 重构触摸事件处理和动态高度调整 - 布局文件: 统一设置圆球大小为14dp - ProGuard: 保护Media3 DefaultTimeBar字段不被混淆
This commit is contained in:
Vendored
+7
@@ -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,54 +95,32 @@ 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();
|
||||||
} catch (Exception e) {
|
|
||||||
// 如果反射失败,使用备用方案
|
|
||||||
e.printStackTrace();
|
|
||||||
// 备用方案:重新设置布局参数
|
|
||||||
timeBar.getLayoutParams().height = barHeightPx;
|
|
||||||
timeBar.requestLayout();
|
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));
|
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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user