import 'dart:async'; import 'dart:io'; import 'package:android_intent/android_intent.dart'; import 'package:device_apps/device_apps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:sport/bean/feed_back.dart'; import 'package:sport/bean/game.dart'; import 'package:sport/pages/my/feedback_detail_page.dart'; import 'package:sport/router/navigator_util.dart'; import 'package:sport/services/api/inject_api.dart'; import 'package:sport/services/game_manager.dart'; import 'package:sport/sharesdk/wechat.dart'; import 'package:sport/utils/toast.dart'; import 'package:sport/widgets/dialog/alert_dialog.dart'; import 'package:sport/widgets/dialog/request_dialog.dart'; import 'package:sport/widgets/image.dart'; import 'package:sport/widgets/misc.dart'; import 'package:sport/widgets/popmenu_bg.dart'; import 'package:video_player/video_player.dart'; class GameDetailsVideo extends StatefulWidget { final Function changeIsFullScreen; final bool _isFullScreen; VideoPlayerController controller; bool isLoading; GameInfoData data; GameDetailsVideo(this.changeIsFullScreen, this._isFullScreen, this.controller, this.isLoading, this.data, {Key key}) : super(key: key); @override State createState() { // TODO: implement createState return _GameDetailsVideoState(); } } class _GameDetailsVideoState extends State with WechatMixin, InjectLoginApi { void changeIsFullScreen; Timer timer; var opacity = 1.0; VoidCallback _listener; ValueNotifier timeEnd = ValueNotifier(Duration()); // 播放的时间 ValueNotifier timeStart = ValueNotifier(Duration()); // final spinkit = SpinKitDualRing( color: Colors.white, ); @override void initState() { super.initState(); widget.controller.addListener(_listener = () { if (!mounted) return; setState(() { timeStart.value = widget.controller.value.position; }); timeEnd.value = widget.controller.value.duration; }); } @override void dispose() { super.dispose(); timer?.cancel(); widget.controller?.removeListener(_listener); timeStart?.dispose(); timeEnd?.dispose(); } void initdelay() { if (timer != null) { timer.cancel(); } setState(() { opacity = 1; }); timer = Timer(new Duration(seconds: 3), () { setState(() { if (mounted) opacity = 0; }); }); } @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; final width = size.width; final height = size.height; bool isLoading = widget.isLoading; bool isPlaying = widget.controller.value.isPlaying; VideoPlayerController controller = widget.controller; Widget top = Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( onPressed: () { if (widget._isFullScreen) { widget.changeIsFullScreen(); } else { // 原生的返回上一页? Navigator.pop(context); } }, icon: Image.asset( "lib/assets/img/topbar_return_white.png", width: 26, height: 38, ), ), if (widget._isFullScreen == false) FutureBuilder( future: DeviceApps.isAppInstalled(widget.data.packageNameAndroid), builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.data == true ? PopupMenuTheme( data: PopupMenuThemeData(shape: PopmenuShape(borderRadius: BorderRadius.all(Radius.circular(10.0)))), child: PopupMenuButton( offset: Offset(0, kToolbarHeight / 2 + 15), icon: iconMore(), onSelected: (val) { _onPopMenuSelected(val); }, itemBuilder: (context) { return divideMenus([ menuItem('运动记录', 'linkpop_icon_record.png', '运动记录'), menuItem('设备测试', 'linkpop_icon_motion.png', '设备测试'), menuItem('问题反馈', 'linkpop_icon_feedback.png', '问题反馈'), menuItem('删除运动', 'linkpop_icon_del.png', '删除运动'), ]); }, )) : PopupMenuTheme( data: PopupMenuThemeData(shape: PopmenuShape(borderRadius: BorderRadius.all(Radius.circular(10.0)))), child: PopupMenuButton( offset: Offset(0, kToolbarHeight / 2 + 15), icon: iconMore(), onSelected: (val) { _onPopMenuSelected(val); }, itemBuilder: (context) { return divideMenus([ menuItem('运动记录', 'linkpop_icon_record.png', '运动记录'), menuItem('设备测试', 'linkpop_icon_motion.png', '设备测试'), menuItem('问题反馈', 'linkpop_icon_feedback.png', '问题反馈'), ]); }, ))) ], ); Widget body = Stack( children: [ isLoading == false ? InkWell( child: (VideoPlayer(controller)), onTap: () { initdelay(); }, onDoubleTap: () { if (isPlaying) { controller.pause(); } else { controller.play(); } }, ) : spinkit, isPlaying != true && isLoading == false ? InkWell( child: Center( child: Image.asset( "lib/assets/img/game_icon_play.png", width: 50, height: 50, )), onTap: () async { if (isPlaying) { controller.pause(); } else { if (controller.value.position.compareTo(controller.value.duration) == 0) { controller.seekTo(Duration.zero); } else { initdelay(); } controller.play(); } }, ) : Container(), Positioned( left: 0, right: 0, child: AnimatedOpacity( duration: new Duration(seconds: 1), opacity: opacity, child: Container( padding: EdgeInsets.symmetric(horizontal: 0), // color: Colors.red, decoration: BoxDecoration( gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFF000000).withOpacity(.5), Color(0x00000000) // Color(0x00000000), ])), child: widget._isFullScreen ? SafeArea( child: top, right: false, ) : top, ), ), ), Positioned( bottom: 5, left: 0, right: 0, child: AnimatedOpacity( duration: new Duration(seconds: 1), opacity: opacity, child: Container( padding: EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0x00000000), Color(0xFF000000).withOpacity(.5) // Color(0x00000000), ])), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.end, children: [ InkWell( child: isPlaying != true ? Image.asset( "lib/assets/img/gamevideo_play_white.png", width: 26, height: 38, ) : Image.asset( "lib/assets/img/gamevideo_suspend.png", width: 26, height: 38, ), onTap: () { if (isPlaying) { controller.pause(); } else { if (controller.value.position.compareTo(controller.value.duration) == 0) { controller.seekTo(Duration.zero); } else { initdelay(); } controller.play(); } }, ), Padding( padding: EdgeInsets.symmetric(horizontal: 5.0), child: ValueListenableBuilder( valueListenable: timeStart, builder: (_, v, __) => Text(v.toString().substring(2, 7), style: TextStyle(color: Colors.white))), ), Expanded( child: SizedBox( height: 3, child: VideoProgressIndicator(controller, allowScrubbing: true, // 是否可以拖动 padding: const EdgeInsets.all(0), colors: VideoProgressColors(playedColor: Theme.of(context).accentColor))), ), Padding( padding: EdgeInsets.symmetric(horizontal: 5.0), child: ValueListenableBuilder( valueListenable: timeEnd, builder: (_, v, __) => Text(v.toString().substring(2, 7), style: TextStyle(color: Colors.white))), ), InkWell( // 全屏按钮 child: Image.asset( "lib/assets/img/gamevideo_fullscreen.png", width: 26, height: 38, ), onTap: () { widget.changeIsFullScreen(); }) ], ), ], ), ), ), ), // ClosedCaption(text: _controller.value.caption.text), ], ); return Container( color: Colors.black, // 约束宽高的 child: widget._isFullScreen ? body : AspectRatio( aspectRatio: 1.78, child: body, )); } _onPopMenuSelected(var val) async { switch (val) { case '运动记录': NavigatorUtil.goGameHistory(context, widget.data); break; case '设备测试': ToastUtil.show("设备测试"); break; case '问题反馈': FeedTypeInfoData group; await request(context, () async { FeedTypeInfo _feedTypeInfo = await loginApi.getFeedBackTypes(); if (_feedTypeInfo.code == 0) { group = _feedTypeInfo.data.singleWhere((element) => element.groupId == '3'); } }); if (group != null) { NavigatorUtil.goPage(context, (context) => FeedbackDetailPage(group)); } break; case '删除运动': if (Platform.isAndroid) { var installed = await DeviceApps.isAppInstalled(widget.data.packageNameAndroid); if (installed == true) { if (await showDialog( context: context, builder: (context) => CustomAlertDialog(title: '是否删除运动', ok: () => Navigator.of(context).pop(true)), ) == true) { GameManager.deleteFile(widget.data); if (Platform.isAndroid) { AndroidIntent intent = AndroidIntent( action: 'android.intent.action.DELETE', data: 'package:${widget.data.packageNameAndroid}', ); await intent.launch(); } } } else {} } break; } } }