fix: obx不能返回nil,无障碍适配

This commit is contained in:
orz12
2024-02-29 20:59:33 +08:00
parent 1d6b3049d9
commit 646424d7c2

View File

@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
@@ -17,6 +17,8 @@ import 'package:PiliPalaX/utils/feed_back.dart';
import 'package:PiliPalaX/utils/storage.dart';
import 'package:screen_brightness/screen_brightness.dart';
import '../../common/widgets/audio_video_progress_bar.dart';
import '../../utils/utils.dart';
import 'models/bottom_progress_behavior.dart';
import 'widgets/app_bar_ani.dart';
import 'widgets/backward_seek.dart';
@@ -79,6 +81,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
DateTime? lastFullScreenToggleTime;
// 记录上一次音量调整值作平均,避免音量调整抖动
double lastVolume = -1.0;
// 是否在调整固定进度条
RxBool draggingFixedProgressBar = false.obs;
// 阅读器限制
Timer? _accessibilityDebounce;
double _lastAnnouncedValue = -1;
void onDoubleTapSeekBackward() {
_ctr.onDoubleTapSeekBackward();
@@ -127,8 +134,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
defaultValue: BtmProgresBehavior.values.first.code);
enableQuickDouble =
setting.get(SettingBoxKey.enableQuickDouble, defaultValue: true);
fullScreenGestureReverse = setting.get(SettingBoxKey.fullScreenGestureReverse,
defaultValue: false);
fullScreenGestureReverse = setting
.get(SettingBoxKey.fullScreenGestureReverse, defaultValue: false);
enableBackgroundPlay =
setting.get(SettingBoxKey.enableBackgroundPlay, defaultValue: false);
Future.microtask(() async {
@@ -281,10 +288,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
children: [
Obx(() {
return Text(
_.sliderTempPosition.value.inMinutes >= 60
? printDurationWithHours(
_.sliderTempPosition.value)
: printDuration(_.sliderTempPosition.value),
Utils.timeFormat(
_.sliderTempPosition.value.inSeconds),
style: textStyle,
);
}),
@@ -439,6 +444,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
top: 25,
right: 15,
bottom: 15,
child: Semantics(
label: '双击开关播放控件,左右滑动调整进度',
child: GestureDetector(
onTap: () {
_.controls = !_.showControls.value;
@@ -448,7 +455,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (_.videoType.value == 'live' || _.controlsLock.value) {
return;
}
RenderBox renderBox = _playerKey.currentContext!.findRenderObject() as RenderBox;
RenderBox renderBox =
_playerKey.currentContext!.findRenderObject() as RenderBox;
final double totalWidth = renderBox.size.width;
final double tapPosition = details.localPosition.dx;
final double sectionWidth = totalWidth / 3;
@@ -479,7 +487,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
// final double tapPosition = details.localPosition.dx;
final int curSliderPosition =
_.sliderPosition.value.inMilliseconds;
RenderBox renderBox = _playerKey.currentContext!.findRenderObject() as RenderBox;
RenderBox renderBox =
_playerKey.currentContext!.findRenderObject() as RenderBox;
final double scale = 90000 / renderBox.size.width;
final Duration pos = Duration(
milliseconds:
@@ -499,16 +508,17 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
},
// 垂直方向 音量/亮度调节
onVerticalDragUpdate: (DragUpdateDetails details) async {
RenderBox renderBox = _playerKey.currentContext!.findRenderObject() as RenderBox;
final double totalWidth = renderBox.size.width;
final double tapPosition = details.localPosition.dx;
final double sectionWidth = totalWidth / 3;
final double delta = details.delta.dy;
RenderBox renderBox =
_playerKey.currentContext!.findRenderObject() as RenderBox;
/// 锁定时禁用
if (_.controlsLock.value) {
return;
}
final double totalWidth = renderBox.size.width;
final double tapPosition = details.localPosition.dx;
final double sectionWidth = totalWidth / 3;
final double delta = details.delta.dy;
if (lastFullScreenToggleTime != null &&
DateTime.now().difference(lastFullScreenToggleTime!) <
const Duration(milliseconds: 500)) {
@@ -529,6 +539,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
lastFullScreenToggleTime = DateTime.now();
await widget.controller.triggerFullScreen(status: status);
}
if (dy > _distance && dy > threshold) {
// 下滑退出全屏/进入全屏
if (_.isFullScreen.value ^ fullScreenGestureReverse) {
@@ -549,7 +560,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (lastVolume < 0) {
lastVolume = _ctr.volumeValue.value;
}
final double volume = (lastVolume + _ctr.volumeValue.value - delta / level)/2;
final double volume =
(lastVolume + _ctr.volumeValue.value - delta / level) / 2;
final double result = volume.clamp(0.0, 1.0);
lastVolume = result;
setVolume(result);
@@ -558,6 +570,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
onVerticalDragEnd: (DragEndDetails details) {},
),
),
),
// 头部、底部控制条
SafeArea(
@@ -605,28 +618,32 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
}
if (defaultBtmProgressBehavior ==
BtmProgresBehavior.alwaysHide.code) {
return nil;
return Container();
}
if (defaultBtmProgressBehavior ==
BtmProgresBehavior.onlyShowFullScreen.code &&
!_.isFullScreen.value) {
return nil;
return Container();
} else if (defaultBtmProgressBehavior ==
BtmProgresBehavior.onlyHideFullScreen.code &&
_.isFullScreen.value) {
return nil;
return Container();
}
if (_.videoType.value == 'live') {
return const SizedBox();
return Container();
}
if (value > max || max <= 0) {
return nil;
return Container();
}
return Positioned(
bottom: -1.5,
bottom: -1,
left: 0,
right: 0,
child: Semantics(
// label: '${(value / max * 100).round()}%',
value: '${(value / max * 100).round()}%',
// enabled: false,
child: ProgressBar(
progress: Duration(seconds: value),
buffered: Duration(seconds: buffer),
@@ -637,22 +654,37 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Theme.of(context).colorScheme.primary.withOpacity(0.4),
timeLabelLocation: TimeLabelLocation.none,
thumbColor: colorTheme,
barHeight: 3,
thumbRadius: 0.0,
// onDragStart: (duration) {
// _.onChangedSliderStart();
// },
// onDragEnd: () {
// _.onChangedSliderEnd();
// },
// onDragUpdate: (details) {
// print(details);
// },
// onSeek: (duration) {
// feedBack();
// _.onChangedSlider(duration.inSeconds.toDouble());
// _.seekTo(duration);
// },
barHeight: 3.5,
thumbRadius: draggingFixedProgressBar.value ? 7 : 4,
onDragStart: (duration) {
draggingFixedProgressBar.value = true;
feedBack();
_.onChangedSliderStart();
},
onDragUpdate: (duration) {
double newProgress = duration.timeStamp.inSeconds / max;
if ((newProgress - _lastAnnouncedValue).abs() > 0.02) {
_accessibilityDebounce?.cancel();
_accessibilityDebounce =
Timer(const Duration(milliseconds: 200), () {
SemanticsService.announce(
"${(newProgress * 100).round()}%",
TextDirection.ltr);
_lastAnnouncedValue = newProgress;
});
}
_.onUpdatedSliderProgress(duration.timeStamp);
},
onSeek: (duration) {
draggingFixedProgressBar.value = false;
_.onChangedSliderEnd();
_.onChangedSlider(duration.inSeconds.toDouble());
_.seekTo(Duration(seconds: duration.inSeconds),
type: 'slider');
SemanticsService.announce(
"${(duration.inSeconds / max * 100).round()}%",
TextDirection.ltr);
},
),
// SlideTransition(
// position: Tween<Offset>(
@@ -663,7 +695,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
// curve: Curves.easeInOut,
// )),
// child: ),
);
));
},
),
@@ -678,6 +710,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
child: Visibility(
visible: _.showControls.value,
child: ComBtn(
tooltip: _.controlsLock.value ? '解锁' : '锁定',
icon: Icon(
_.controlsLock.value
? FontAwesomeIcons.lock