|
|
@@ -1,846 +0,0 @@
|
|
|
-import 'dart:async';
|
|
|
-
|
|
|
-import 'package:chewie/chewie.dart';
|
|
|
-import 'package:chewie/src/chewie_player.dart';
|
|
|
-import 'package:chewie/src/chewie_progress_colors.dart';
|
|
|
-import 'package:chewie/src/i2_control_event.dart';
|
|
|
-import 'package:chewie/src/material_progress_bar.dart';
|
|
|
-import 'package:chewie/src/utils.dart';
|
|
|
-import 'package:flutter/material.dart';
|
|
|
-import 'package:screen/screen.dart';
|
|
|
-import 'package:sys_volume/flutter_volume.dart';
|
|
|
-import 'package:video_player/video_player.dart';
|
|
|
-
|
|
|
-class CartoonMaterialControls extends StatefulWidget {
|
|
|
- final bool enableQuickControl;
|
|
|
- final List<MoreVideo> moreVideo;
|
|
|
- final OnTapMoreVideo onTapMoreVideo;
|
|
|
- final VoidCallback onTapNext;
|
|
|
- final VoidCallback onTapPrevious;
|
|
|
- final VoidCallback onTapLove;
|
|
|
- final ValueNotifier<int> isCollect;
|
|
|
- final ValueNotifier<int> isLoadingVideo;
|
|
|
-
|
|
|
- const CartoonMaterialControls(
|
|
|
- {Key key, this.enableQuickControl = false, this.moreVideo, this.onTapMoreVideo, this.onTapNext, this.onTapPrevious, this.onTapLove, this.isCollect, this.isLoadingVideo})
|
|
|
- : super(key: key);
|
|
|
-
|
|
|
- @override
|
|
|
- State<StatefulWidget> createState() {
|
|
|
- return CartoonMaterialControlsState();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-enum CartoonVerticalMode {
|
|
|
- Volume,
|
|
|
- Bright
|
|
|
-}
|
|
|
-
|
|
|
-typedef void OnTapMoreVideo(int index);
|
|
|
-
|
|
|
-class CartoonMaterialControlsState extends State<CartoonMaterialControls> {
|
|
|
- VideoPlayerValue _latestValue;
|
|
|
- bool _hideStuff = true;
|
|
|
- Timer _hideTimer;
|
|
|
- Timer _initTimer;
|
|
|
- Timer _showAfterExpandCollapseTimer;
|
|
|
- bool _dragging = false;
|
|
|
- bool _displayTapped = false;
|
|
|
-
|
|
|
- final barHeight = 36.0;
|
|
|
- final marginSize = 5.0;
|
|
|
-
|
|
|
- VideoPlayerController controller;
|
|
|
- ChewieController chewieController;
|
|
|
-
|
|
|
- /// 横向视频进度拖动 BiLiBiLi的逻辑 duration > 90 ? 90s : duration * 0.8
|
|
|
- double startDx;
|
|
|
- double lastDx;
|
|
|
- Duration dragDuration;
|
|
|
- Duration updateDragDuration;
|
|
|
-
|
|
|
- /// 竖向音量亮度拖动 100%调整的逻辑
|
|
|
- double startDy;
|
|
|
- double endDy;
|
|
|
- CartoonVerticalMode _CartoonVerticalMode;
|
|
|
- double currentBright;
|
|
|
- double currentVolume;
|
|
|
- String valueText;
|
|
|
- StreamSubscription _eventBusStreamSubscription;
|
|
|
-
|
|
|
- @override
|
|
|
- Widget build(BuildContext context) {
|
|
|
- if (_latestValue.hasError) {
|
|
|
- return chewieController.errorBuilder != null
|
|
|
- ? chewieController.errorBuilder(
|
|
|
- context,
|
|
|
- chewieController.videoPlayerController.value.errorDescription,
|
|
|
- )
|
|
|
- : Center(
|
|
|
- child: Icon(
|
|
|
- Icons.error,
|
|
|
- color: Colors.white,
|
|
|
- size: 42,
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- return MouseRegion(
|
|
|
- onHover: (_) {
|
|
|
- _cancelAndRestartTimer();
|
|
|
- },
|
|
|
- child: GestureDetector(
|
|
|
- onTap: () => _cancelAndRestartTimer(),
|
|
|
- onVerticalDragStart: (DragStartDetails details) async {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // 判断距离 只响应2/5的左边和2/5的右边
|
|
|
- if (details.globalPosition.dx < MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width / 5 * 2) {
|
|
|
- // 响应亮度
|
|
|
- startDy = details.globalPosition.dy;
|
|
|
- _CartoonVerticalMode = CartoonVerticalMode.Bright;
|
|
|
- currentBright = await Screen.brightness;
|
|
|
- } else if (details.globalPosition.dx > MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width / 5 * 3) {
|
|
|
- // 响应音量
|
|
|
- startDy = details.globalPosition.dy;
|
|
|
- _CartoonVerticalMode = CartoonVerticalMode.Volume;
|
|
|
- currentVolume = await FlutterVolume.get();
|
|
|
- } else {
|
|
|
- // 中间位置不响应 reset
|
|
|
- setState(() {
|
|
|
- _CartoonVerticalMode = null;
|
|
|
- currentBright = null;
|
|
|
- currentVolume = null;
|
|
|
- startDy = null;
|
|
|
- endDy = null;
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- onVerticalDragUpdate: (DragUpdateDetails details) async {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (_CartoonVerticalMode != null) {
|
|
|
- // 显示数值(百分比)
|
|
|
- setState(() {
|
|
|
- endDy = details.globalPosition.dy;
|
|
|
- });
|
|
|
- if (_CartoonVerticalMode != null && endDy != null &&
|
|
|
- startDy != null) {
|
|
|
- double value;
|
|
|
- if (_CartoonVerticalMode == CartoonVerticalMode.Bright) {
|
|
|
- if (currentBright == null) return;
|
|
|
- if (endDy > startDy) {
|
|
|
- // 降低操作 竖屏环境?????
|
|
|
- value = (currentBright - (endDy - startDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height) < 0
|
|
|
- ? 0
|
|
|
- : (currentBright - (endDy - startDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height);
|
|
|
- } else {
|
|
|
- // 拉高操作 竖屏环境?????
|
|
|
- value = (currentBright + (startDy - endDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height) >= 1
|
|
|
- ? 1
|
|
|
- : (currentBright + (startDy - endDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height);
|
|
|
- }
|
|
|
- Screen.setBrightness(value);
|
|
|
- } else {
|
|
|
- if (currentVolume == null) return;
|
|
|
- if (endDy > startDy) {
|
|
|
- // 降低操作 竖屏环境?????
|
|
|
- value = (currentVolume - (endDy - startDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height) < 0
|
|
|
- ? 0
|
|
|
- : (currentVolume - (endDy - startDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height);
|
|
|
- } else {
|
|
|
- // 拉高操作 竖屏环境?????
|
|
|
- value = (currentVolume + (startDy - endDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height) >= 1
|
|
|
- ? 1
|
|
|
- : (currentVolume + (startDy - endDy) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .height);
|
|
|
- }
|
|
|
- FlutterVolume.set(value);
|
|
|
- }
|
|
|
- if (value == 1 || value == 0) {
|
|
|
- // reset dy
|
|
|
- startDy = endDy;
|
|
|
- currentBright = await Screen.brightness;
|
|
|
- currentVolume = await FlutterVolume.get();
|
|
|
- }
|
|
|
- setState(() {
|
|
|
- valueText = (value * 100).toStringAsFixed(0);
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- onVerticalDragEnd: (DragEndDetails details) {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- setState(() {
|
|
|
- _CartoonVerticalMode = null;
|
|
|
- currentBright = null;
|
|
|
- startDy = null;
|
|
|
- endDy = null;
|
|
|
- });
|
|
|
- },
|
|
|
- onHorizontalDragStart: (DragStartDetails detail) {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (_latestValue.duration == null) return;
|
|
|
- _cancelAndRestartTimer();
|
|
|
- startDx = detail.localPosition.dx;
|
|
|
- dragDuration = _latestValue.position;
|
|
|
- },
|
|
|
- onHorizontalDragUpdate: (DragUpdateDetails detail) {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (_latestValue.duration == null) return;
|
|
|
- _cancelAndRestartTimer();
|
|
|
- lastDx = detail.localPosition.dx;
|
|
|
- // update progress bar
|
|
|
- Duration finalDuration = getDragDuration();
|
|
|
-
|
|
|
- setState(() {
|
|
|
- updateDragDuration = finalDuration;
|
|
|
- });
|
|
|
- },
|
|
|
- onHorizontalDragCancel: () {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- startDx = null;
|
|
|
- lastDx = null;
|
|
|
- dragDuration = null;
|
|
|
- setState(() {
|
|
|
- updateDragDuration = null;
|
|
|
- });
|
|
|
- },
|
|
|
- onHorizontalDragEnd: (DragEndDetails detail) {
|
|
|
- if (!widget.enableQuickControl) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (startDx != null && lastDx != null &&
|
|
|
- _latestValue.duration != null && dragDuration != null) {
|
|
|
- Duration finalDuration = getDragDuration();
|
|
|
- chewieController.seekTo(finalDuration);
|
|
|
- }
|
|
|
- startDx = null;
|
|
|
- lastDx = null;
|
|
|
- dragDuration = null;
|
|
|
- setState(() {
|
|
|
- updateDragDuration = null;
|
|
|
- });
|
|
|
- },
|
|
|
- child: AbsorbPointer(
|
|
|
- absorbing: _hideStuff,
|
|
|
- child: Stack(
|
|
|
- children: <Widget>[
|
|
|
- Column(
|
|
|
- children: <Widget>[
|
|
|
- _latestValue != null &&
|
|
|
- !_latestValue.isPlaying &&
|
|
|
- _latestValue.duration == null ||
|
|
|
- _latestValue.isBuffering
|
|
|
- ? const Expanded(
|
|
|
- child: const Center(
|
|
|
- child: const CircularProgressIndicator(),
|
|
|
- ),
|
|
|
- )
|
|
|
- : _buildHitArea(),
|
|
|
- _buildBottomBar(context),
|
|
|
- ],
|
|
|
- ),
|
|
|
- _buildTopBar(context),
|
|
|
- _buildDragProgress(),
|
|
|
- _buildVerticalWidget(),
|
|
|
- ],
|
|
|
- )
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- @override
|
|
|
- void initState() {
|
|
|
- super.initState();
|
|
|
- _initState();
|
|
|
- }
|
|
|
-
|
|
|
- void _initState() async {
|
|
|
- FlutterVolume.disableUI();
|
|
|
- _eventBusStreamSubscription =
|
|
|
- i2ControlEventBus.on<I2ControllerEvent>().listen((event) {
|
|
|
- if (event == I2ControllerEvent.ShowControl) {
|
|
|
- _showControlWithoutTimer();
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- @override
|
|
|
- void dispose() {
|
|
|
- _eventBusStreamSubscription.cancel();
|
|
|
- Screen.resetAndroidBrightness();
|
|
|
- _dispose();
|
|
|
- super.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- void _dispose() async {
|
|
|
- controller.removeListener(_updateState);
|
|
|
- _hideTimer?.cancel();
|
|
|
- _initTimer?.cancel();
|
|
|
- _showAfterExpandCollapseTimer?.cancel();
|
|
|
- }
|
|
|
-
|
|
|
- @override
|
|
|
- void didChangeDependencies() {
|
|
|
- final _oldController = chewieController;
|
|
|
- chewieController = ChewieController.of(context);
|
|
|
- controller = chewieController.videoPlayerController;
|
|
|
-
|
|
|
- if (_oldController != chewieController) {
|
|
|
- _dispose();
|
|
|
- _initialize();
|
|
|
- }
|
|
|
-
|
|
|
- super.didChangeDependencies();
|
|
|
- }
|
|
|
-
|
|
|
- Duration getDragDuration() {
|
|
|
- if (lastDx - startDx > 0) {
|
|
|
- // 前进
|
|
|
- int forwardSec;
|
|
|
- if (_latestValue.duration.inSeconds > 90) {
|
|
|
- forwardSec = ((lastDx - startDx) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width * 90).toInt();
|
|
|
- } else {
|
|
|
- forwardSec = ((lastDx - startDx) / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width * _latestValue.duration.inSeconds * 0.8).toInt();
|
|
|
- }
|
|
|
- Duration duration = dragDuration + Duration(seconds: forwardSec);
|
|
|
- return duration >= _latestValue.duration
|
|
|
- ? _latestValue.duration
|
|
|
- : duration;
|
|
|
- } else {
|
|
|
- // 后退
|
|
|
- int backwardSec;
|
|
|
- if (_latestValue.duration.inSeconds > 90) {
|
|
|
- backwardSec = ((lastDx - startDx) * -1 / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width * 90).toInt();
|
|
|
- } else {
|
|
|
- backwardSec = ((lastDx - startDx) * -1 / MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width * _latestValue.duration.inSeconds * 0.8).toInt();
|
|
|
- }
|
|
|
- Duration duration = (Duration(seconds: backwardSec) > dragDuration)
|
|
|
- ? Duration.zero
|
|
|
- : dragDuration - Duration(seconds: backwardSec);
|
|
|
- return duration;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildDragProgress() {
|
|
|
- final position = updateDragDuration ??
|
|
|
- (_latestValue != null && _latestValue.position != null
|
|
|
- ? _latestValue.position
|
|
|
- : Duration.zero);
|
|
|
- return Offstage(
|
|
|
- offstage: updateDragDuration == null,
|
|
|
- child: Align(
|
|
|
- alignment: Alignment.center,
|
|
|
- child: Container(
|
|
|
- width: 96,
|
|
|
- height: 34,
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: Color(0xB0000000),
|
|
|
- borderRadius: BorderRadius.circular(4),
|
|
|
- ),
|
|
|
- alignment: Alignment.center,
|
|
|
- child: Text("${formatDuration(position)}/${formatDuration(
|
|
|
- _latestValue.duration)}",
|
|
|
- style: TextStyle(color: Colors.white, fontSize: 12),),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildVerticalWidget() {
|
|
|
-// ((endDy - startDy) / widgetHeight * 100).toStringAsFixed(2)
|
|
|
- // 正方圆角
|
|
|
- return Offstage(
|
|
|
- offstage: _CartoonVerticalMode == null,
|
|
|
- child: Align(
|
|
|
- alignment: Alignment.center,
|
|
|
- child: Container(
|
|
|
- width: 80,
|
|
|
- height: 80,
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: Color(0xB0000000),
|
|
|
- borderRadius: BorderRadius.circular(4),
|
|
|
- ),
|
|
|
- alignment: Alignment.center,
|
|
|
- child: Column(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- mainAxisSize: MainAxisSize.max,
|
|
|
- children: <Widget>[
|
|
|
- Icon(_CartoonVerticalMode == CartoonVerticalMode.Volume ? Icons
|
|
|
- .volume_up : Icons.brightness_6, color: Colors.white,
|
|
|
- size: 24,),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.only(top: 10),
|
|
|
- child: Text("${valueText}%",
|
|
|
- style: TextStyle(color: Colors.white, fontSize: 15,),),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- AnimatedOpacity _buildTopBar(BuildContext context,) {
|
|
|
- return AnimatedOpacity(
|
|
|
- opacity: _hideStuff ? 0.0 : 1.0,
|
|
|
- duration: Duration(milliseconds: 300),
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: Colors.white,
|
|
|
- borderRadius: BorderRadius.only(bottomRight: Radius.circular(10),
|
|
|
- bottomLeft: Radius.circular(10)),
|
|
|
- ),
|
|
|
-// color: chewieController.isFullScreen ? Colors.black26 : Colors.transparent,
|
|
|
- alignment: Alignment.center,
|
|
|
- margin: EdgeInsets.only(left: (MediaQuery
|
|
|
- .of(context)
|
|
|
- .size
|
|
|
- .width - 280) / 2),
|
|
|
- width: 300,
|
|
|
- height: 46,
|
|
|
-// margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top != 0 ? MediaQuery.of(context).padding.top : 0),
|
|
|
- padding: EdgeInsets.only(left: 13,),
|
|
|
- child: Row(
|
|
|
- children: <Widget>[
|
|
|
- Expanded(
|
|
|
- child: GestureDetector(
|
|
|
- child: Image(image: AssetImage(
|
|
|
- "assets/dub_user_play/back2.png", package: 'chewie'),
|
|
|
- width: 20,
|
|
|
- height: 20,),
|
|
|
- onTap: onTapBack,
|
|
|
- ),
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: GestureDetector(
|
|
|
- child: Image(image: AssetImage(
|
|
|
- "assets/dub_user_play/rightyou.png", package: 'chewie'),
|
|
|
- width: 20,
|
|
|
- height: 20,),
|
|
|
- onTap: widget.onTapPrevious,
|
|
|
- ),
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: GestureDetector(
|
|
|
- child: Image(image: AssetImage(controller.value.isPlaying
|
|
|
- ? "assets/dub_user_play/top_stop.png"
|
|
|
- : "assets/dub_user_play/top_bof.png", package: 'chewie'),
|
|
|
- width: 20,
|
|
|
- height: 20,),
|
|
|
- onTap: _playPause,
|
|
|
- ),
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: GestureDetector(
|
|
|
- child: Image(image: AssetImage(
|
|
|
- "assets/dub_user_play/rightji.png", package: 'chewie'),
|
|
|
- width: 20,
|
|
|
- height: 20,),
|
|
|
- onTap: widget.onTapNext,
|
|
|
- ),
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: GestureDetector(
|
|
|
- child: ValueListenableBuilder(
|
|
|
- valueListenable: widget.isCollect,
|
|
|
- builder: (BuildContext context, int value, Widget child) {
|
|
|
- return Image(
|
|
|
- image: AssetImage("assets/dub_user_play/${widget
|
|
|
- .isCollect.value == 1 ? "xin.png" : "hxin.png"}",
|
|
|
- package: 'chewie'), width: 20, height: 20,);
|
|
|
- }
|
|
|
- ),
|
|
|
- onTap: () {
|
|
|
- _cancelAndRestartTimer();
|
|
|
- widget.onTapLove();
|
|
|
- },
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- AnimatedOpacity _buildBottomBar(BuildContext context,) {
|
|
|
- final iconColor = Theme
|
|
|
- .of(context)
|
|
|
- .textTheme
|
|
|
- .button
|
|
|
- .color;
|
|
|
-
|
|
|
- return AnimatedOpacity(
|
|
|
- opacity: _hideStuff ? 0.0 : 1.0,
|
|
|
- duration: Duration(milliseconds: 300),
|
|
|
- child: Column(
|
|
|
- children: <Widget>[
|
|
|
- Container(
|
|
|
- height: barHeight + (widget.moreVideo.length == 0 ? 0 : 80),
|
|
|
- decoration: BoxDecoration(
|
|
|
- gradient: const LinearGradient(
|
|
|
- colors: [Colors.black38, Colors.transparent],
|
|
|
- begin: Alignment.bottomCenter,
|
|
|
- end: Alignment.topCenter,
|
|
|
- stops: [0.0, 1]),
|
|
|
- ),
|
|
|
- child: Column(
|
|
|
- children: <Widget>[
|
|
|
- SizedBox(
|
|
|
- height: barHeight,
|
|
|
- child: Row(
|
|
|
- children: <Widget>[
|
|
|
- chewieController.isLive
|
|
|
- ? Expanded(child: const Text('LIVE'))
|
|
|
- : _buildPosition(iconColor),
|
|
|
- chewieController.isLive
|
|
|
- ? const SizedBox()
|
|
|
- : _buildProgressBar(),
|
|
|
- chewieController.isLive
|
|
|
- ? const SizedBox()
|
|
|
- : _buildFullPosition(iconColor),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- Offstage(
|
|
|
- offstage: widget.moreVideo.length == 0,
|
|
|
- child: SizedBox(
|
|
|
- height: 80,
|
|
|
- child: Listener(
|
|
|
- child: ListView.builder(
|
|
|
- scrollDirection: Axis.horizontal,
|
|
|
- physics: AlwaysScrollableScrollPhysics(),
|
|
|
- shrinkWrap: false,
|
|
|
- itemCount: widget.moreVideo.length,
|
|
|
- itemBuilder: (ctx, index) {
|
|
|
- return GestureDetector(
|
|
|
- child: Container(
|
|
|
- width: 100,
|
|
|
- height: 60,
|
|
|
- alignment: Alignment.center,
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: Colors.white,
|
|
|
- borderRadius: BorderRadius.circular(15),
|
|
|
- border: widget.moreVideo[index].isSelect
|
|
|
- ? Border.all(
|
|
|
- color: Color(0xFFEF765E), width: 3)
|
|
|
- : null,
|
|
|
- ),
|
|
|
- margin: EdgeInsets.only(
|
|
|
- left: 10, right: 10, bottom: 10),
|
|
|
- child: Stack(
|
|
|
- children: <Widget>[
|
|
|
- ClipRRect(
|
|
|
- borderRadius: BorderRadius.circular(
|
|
|
- 15),
|
|
|
- child: Image.network(
|
|
|
- widget.moreVideo[index].imageUrl,
|
|
|
- fit: BoxFit.cover,
|
|
|
- width: 100,
|
|
|
- height: 60,),
|
|
|
- ),
|
|
|
- Align(
|
|
|
- alignment: Alignment.bottomRight,
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: Colors.black26,
|
|
|
- borderRadius: BorderRadius
|
|
|
- .circular(20),
|
|
|
- ),
|
|
|
- padding: const EdgeInsets.symmetric(
|
|
|
- horizontal: 4, vertical: 2),
|
|
|
- child: Text(formatDuration(
|
|
|
- widget.moreVideo[index]
|
|
|
- .duration),
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white,
|
|
|
- fontSize: 11.0,),),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- onTap: () {
|
|
|
- widget?.onTapMoreVideo(index);
|
|
|
- },
|
|
|
- );
|
|
|
- },
|
|
|
- ),
|
|
|
- onPointerDown: onMoreVideoPointerDown,
|
|
|
- onPointerUp: onMoreVideoPointerUp,
|
|
|
- )
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Expanded _buildHitArea() {
|
|
|
- return Expanded(
|
|
|
- child: GestureDetector(
|
|
|
- onTap: () {
|
|
|
- if (_latestValue != null && _latestValue.isPlaying) {
|
|
|
- if (_displayTapped) {
|
|
|
- setState(() {
|
|
|
- _hideStuff = true;
|
|
|
- });
|
|
|
- } else
|
|
|
- _cancelAndRestartTimer();
|
|
|
- } else {
|
|
|
- _playPause();
|
|
|
- setState(() {
|
|
|
- _hideStuff = true;
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- child: Container(
|
|
|
- color: Colors.transparent,
|
|
|
- child: Center(
|
|
|
- child: AnimatedOpacity(
|
|
|
- opacity:
|
|
|
- _latestValue != null && !_latestValue.isPlaying && !_dragging
|
|
|
- ? 1.0
|
|
|
- : 0.0,
|
|
|
- duration: Duration(milliseconds: 300),
|
|
|
- child: GestureDetector(
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: Theme
|
|
|
- .of(context)
|
|
|
- .dialogBackgroundColor,
|
|
|
- borderRadius: BorderRadius.circular(48.0),
|
|
|
- ),
|
|
|
- child: Padding(
|
|
|
- padding: EdgeInsets.all(12.0),
|
|
|
- child: Icon(
|
|
|
- Icons.play_arrow, size: 32.0, color: Colors.black,),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildPosition(Color iconColor) {
|
|
|
- final position = updateDragDuration ??
|
|
|
- (_latestValue != null && _latestValue.position != null
|
|
|
- ? _latestValue.position
|
|
|
- : Duration.zero);
|
|
|
- final duration = _latestValue != null && _latestValue.duration != null
|
|
|
- ? _latestValue.duration
|
|
|
- : Duration.zero;
|
|
|
-
|
|
|
- return Padding(
|
|
|
- padding: EdgeInsets.only(left: 20.0, right: 14.0),
|
|
|
- child: Text(
|
|
|
- '${formatDuration(position)}',
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white,
|
|
|
- fontSize: 12.0,
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildFullPosition(Color iconColor) {
|
|
|
- final position = _latestValue != null && _latestValue.position != null
|
|
|
- ? _latestValue.position
|
|
|
- : Duration.zero;
|
|
|
- final duration = _latestValue != null && _latestValue.duration != null
|
|
|
- ? _latestValue.duration
|
|
|
- : Duration.zero;
|
|
|
-
|
|
|
- return Padding(
|
|
|
- padding: EdgeInsets.only(left: 14.0, right: 20.0),
|
|
|
- child: Text(
|
|
|
- '${formatDuration(duration)}',
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white,
|
|
|
- fontSize: 12.0,
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- void _cancelAndRestartTimer() {
|
|
|
- _hideTimer?.cancel();
|
|
|
- _startHideTimer();
|
|
|
- setState(() {
|
|
|
- _hideStuff = false;
|
|
|
- _displayTapped = true;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- void _showControlWithoutTimer() {
|
|
|
- _hideTimer?.cancel();
|
|
|
- setState(() {
|
|
|
- _hideStuff = false;
|
|
|
- _displayTapped = true;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- Future<Null> _initialize() async {
|
|
|
- controller.addListener(_updateState);
|
|
|
- _latestValue = controller.value;
|
|
|
-
|
|
|
- if ((controller.value != null && controller.value.isPlaying) ||
|
|
|
- chewieController.autoPlay) {
|
|
|
- _startHideTimer();
|
|
|
- }
|
|
|
-
|
|
|
- if (chewieController.showControlsOnInitialize) {
|
|
|
- _initTimer = Timer(Duration(milliseconds: 200), () {
|
|
|
- setState(() {
|
|
|
- _hideStuff = false;
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void _playPause() {
|
|
|
- if (widget.isLoadingVideo.value == 1) {
|
|
|
- return;
|
|
|
- }
|
|
|
- bool isFinished = _latestValue.position >= _latestValue.duration;
|
|
|
-
|
|
|
- setState(() {
|
|
|
- if (controller.value.isPlaying) {
|
|
|
- _hideStuff = false;
|
|
|
- _hideTimer?.cancel();
|
|
|
- controller.pause();
|
|
|
- } else {
|
|
|
- _cancelAndRestartTimer();
|
|
|
-
|
|
|
- if (!controller.value.initialized) {
|
|
|
- controller.initialize().then((_) {
|
|
|
- controller.play();
|
|
|
- });
|
|
|
- } else {
|
|
|
- if (isFinished) {
|
|
|
- controller.seekTo(Duration(seconds: 0));
|
|
|
- }
|
|
|
- controller.play();
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- void _startHideTimer() {
|
|
|
- _hideTimer = Timer(const Duration(seconds: 3), () {
|
|
|
- setState(() {
|
|
|
- _hideStuff = true;
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- void _updateState() async {
|
|
|
- if (_latestValue.position != controller.value.position)
|
|
|
- setState(() {
|
|
|
- _latestValue = controller.value;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildProgressBar() {
|
|
|
- return Expanded(
|
|
|
- child: Padding(
|
|
|
- padding: EdgeInsets.only(bottom: 3),
|
|
|
- child: MaterialVideoProgressBar(
|
|
|
- controller,
|
|
|
- onDragStart: () {
|
|
|
- setState(() {
|
|
|
- _dragging = true;
|
|
|
- });
|
|
|
-
|
|
|
- _hideTimer?.cancel();
|
|
|
- },
|
|
|
- onDragEnd: () {
|
|
|
- setState(() {
|
|
|
- _dragging = false;
|
|
|
- });
|
|
|
-
|
|
|
- _startHideTimer();
|
|
|
- },
|
|
|
- colors: chewieController.materialProgressColors ??
|
|
|
- ChewieProgressColors(
|
|
|
- playedColor: Color(0xFFEF765E),
|
|
|
- handleColor: Color(0xFFEF765E),
|
|
|
- bufferedColor: Color(0x5AEF765E),
|
|
|
- backgroundColor: Color(0x5AFFFFFF)),
|
|
|
- millionSec: updateDragDuration?.inMilliseconds,
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- void onTapBack() {
|
|
|
- chewieController.exitFullScreen();
|
|
|
- }
|
|
|
-
|
|
|
- void onMoreVideoPointerDown(PointerDownEvent event) {
|
|
|
- _hideTimer?.cancel();
|
|
|
- }
|
|
|
-
|
|
|
- void onMoreVideoPointerUp(PointerUpEvent event) {
|
|
|
- _startHideTimer();
|
|
|
- }
|
|
|
-}
|