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