import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutterappfuyou/code/base/YSNetWorking.dart'; import 'package:flutterappfuyou/code/base/YSTools.dart'; import 'package:video_player/video_player.dart'; import 'package:wakelock/wakelock.dart'; class YSVideoDetail extends StatefulWidget { final videoId; const YSVideoDetail({Key key, this.videoId}) : super(key: key); @override _YSVideoDetailState createState() => _YSVideoDetailState(); } class _YSVideoDetailState extends State { Map _infoDict = {}; @override void initState() { Wakelock.enable(); Future.delayed(Duration(seconds: 0)).then((value) { _getVideoDetailData(); }); super.initState(); } @override void dispose() { Wakelock.disable(); super.dispose(); } @override Widget build(BuildContext context) { return AnnotatedRegion( value: SystemUiOverlayStyle.light, child: Scaffold( body: SingleChildScrollView( child: Column( children: [ Container( height: MediaQuery.of(context).size.height-50, width: MediaQuery.of(context).size.width, color: Color(0xFFF5F3F0), child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return Column( children: [ Stack( children: [ Container( height: constraints.maxHeight*0.4, color: Colors.black, child: _infoDict.isNotEmpty?YSVideoView(url: _infoDict['url_play'],):Container(), ), Container( child: GestureDetector( child: Icon(Icons.chevron_left,size: 30,color: Colors.white,), onTap: (){Navigator.pop(context);}, ), padding: EdgeInsets.only(top: ysTOP(context)+10,left: 15), ) ], ), Container( height: constraints.maxHeight*0.1, alignment: Alignment.centerLeft, child: Text(_infoDict['title']??'',style: TextStyle(fontSize: 15,color: Color(0xFF3A3A3C)),maxLines: 2,), padding: EdgeInsets.only(left: 10,right: 10), decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey,width: 0.1)) ), ), Container( height: constraints.maxHeight*0.05, padding: EdgeInsets.only(left: 10,right: 10), decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey.withOpacity(0.1),width: 5)) ), child: Row( children: [ Container( width: (constraints.maxWidth-20)*0.8, child: Text(_infoDict['created_at']??'',style: TextStyle(fontSize: 12,color: Color(0xFF707070)),maxLines: 1,), ), Container( width: (constraints.maxWidth-20)*0.2, child: RichText( text: TextSpan( style: TextStyle(fontSize: 12,color: Color(0xFF707070)), children: [ WidgetSpan(child: Icon(Icons.remove_red_eye_outlined,size: 15,color: Color(0xFF707070))), TextSpan(text: ' ${_infoDict['view']??''}') ] ), ), alignment: Alignment.centerRight, ) ], ), ), Container( height: constraints.maxHeight*0.05, alignment: Alignment.centerLeft, child: Text('${_infoDict['comment_count']??''}条评论',style: TextStyle(fontSize: 12,color: Color(0xFF707070)),maxLines: 1,), padding: EdgeInsets.only(left: 10,right: 10), decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey,width: 0.1)) ), ), Container( height: constraints.maxHeight*0.4, child: YSCommentView(videoId: widget.videoId,), ) ], ); }, ) ), Container( height: 50, color: Colors.white, width: MediaQuery.of(context).size.width, padding: EdgeInsets.only(left: 20,right: 20,top: 10,bottom: 10), child: GestureDetector( onTap: (){ ysShowBottomAlertView2(context, YSInputView(valueSetter: (value) async{ Map dict = await ysRequestHttp(context, requestType.post, 'train/video/comment', {'video_id':widget.videoId,'body':value}); if(dict!=null){ FocusScope.of(context).unfocus(); refreshKey2.currentState.refresh(); } },)); }, child: Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(left: 20,right: 20), child: Text('我来说两句',style: TextStyle(fontSize: 15,color: Color(0xFF707070)),), decoration: BoxDecoration( color: Color(0xFFF5F3F0), borderRadius: BorderRadius.all(Radius.circular(50)) ), ), ), ) ], ), ), ), ); } _getVideoDetailData() async{ Map dict = await ysRequestHttp(context, requestType.get, 'train/video/info', {'video_id':widget.videoId}); if(dict!=null){ _infoDict = dict['data']; setState(() {}); } } } class YSVideoView extends StatefulWidget { final String url; const YSVideoView({Key key, this.url}) : super(key: key); @override _YSVideoViewState createState() => _YSVideoViewState(); } class _YSVideoViewState extends State { VideoPlayerController _videoPlayerController; StateSetter _progressSet; String _startTime = '00:00:00'; String _endTime = '00:00:00'; @override void initState() { _videoPlayerController = VideoPlayerController.network(widget.url) ..addListener(() { Duration duration = _videoPlayerController.value.duration; Duration position = _videoPlayerController.value.position; _endTime = '${duration.inHours}'.padLeft(2,'0')+':'+'${duration.inMinutes}'.padLeft(2,'0')+':'+'${duration.inSeconds}'.padLeft(2,'0'); _startTime = '${position.inHours}'.padLeft(2,'0')+':'+'${position.inMinutes}'.padLeft(2,'0')+':'+'${position.inSeconds}'.padLeft(2,'0'); if(mounted&&_progressSet!=null){ _progressSet(() {}); } }) ..initialize().then((_) { _videoPlayerController.setLooping(true); _videoPlayerController.play(); setState(() {}); }); super.initState(); } @override void dispose() { _videoPlayerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( child: Stack( children: [ _videoPlayerController.value.aspectRatio<1?Center( child: AspectRatio( aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController,), ), ):VideoPlayer(_videoPlayerController,), _pauseView(controller: _videoPlayerController,), Positioned( left: 10, right: 10, top: (MediaQuery.of(context).size.height-50)*0.4-50, child: StatefulBuilder( builder: (context,progressSet){ _progressSet = progressSet; return Container( child: Row( children: [ Container( width: 100, child: Row( children: [ GestureDetector( onTap: (){ progressSet(() { _videoPlayerController.value.isPlaying?_videoPlayerController.pause() : _videoPlayerController.play(); }); progressSet(() {}); }, child: Icon(_videoPlayerController.value.isPlaying?Icons.pause:Icons.play_arrow,size: 25,color: Colors.white,), ), Container( alignment: Alignment.center, width: 75, child: Text(_startTime,style: TextStyle(fontSize: 10,color: Colors.white),), ) ], ), ), Container( width: MediaQuery.of(context).size.width-230, height:6.5, child: VideoProgressIndicator( _videoPlayerController, allowScrubbing: true, colors: VideoProgressColors(playedColor: Colors.white,backgroundColor: Colors.black), ) ), Container( width: 100, child: Row( children: [ Container( alignment: Alignment.center, width: 75, child: Text(_endTime,style: TextStyle(fontSize: 12,color: Colors.white),), ), GestureDetector( onTap: (){ Navigator.of(context).push( CupertinoPageRoute(builder: (context){ return YSVideoHorizontal(player: _videoPlayerController,title: '',); }) ); }, child: Image.asset('lib/images/spsx.png',height: 25,width: 25,), ) ], ) ), ], ), ); }, ) ) ], ) ); } _pauseView({VideoPlayerController controller}) { return StatefulBuilder( builder: (context,playSet){ return Stack( children: [ AnimatedSwitcher( duration: Duration(milliseconds: 50), reverseDuration: Duration(milliseconds: 200), child: controller.value.isPlaying? Container():Container( alignment: Alignment.center, color: Colors.transparent, child: Icon( Icons.play_circle_filled, color: Colors.white, size: 50, ), ), ), GestureDetector( onTap: () { playSet(() { controller.value.isPlaying ? controller.pause() : controller.play(); }); _progressSet(() {}); }, ), ], ); }, ); } } class YSInputView extends StatefulWidget { final ValueSetter valueSetter; const YSInputView({Key key, this.valueSetter}) : super(key: key); @override _YSInputViewState createState() => _YSInputViewState(); } class _YSInputViewState extends State { TextEditingController _editingController = TextEditingController(); @override void dispose() { _editingController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( height: 50, color: Colors.white, width: MediaQuery.of(context).size.width, padding: EdgeInsets.only(left: 20,right: 20,top: 10,bottom: 10), child: CupertinoTextField( autofocus: true, placeholder: '我来说两句', style: TextStyle(fontSize: 15,color: Color(0xFF707070)), placeholderStyle: TextStyle(fontSize: 15,color: Color(0xFF707070)), padding: EdgeInsets.only(left: 20,right: 20), controller: _editingController, decoration: BoxDecoration( color: Color(0xFFF5F3F0), borderRadius: BorderRadius.all(Radius.circular(50)) ), textInputAction: TextInputAction.send, onSubmitted: (value){ if(value.isNotEmpty){ widget.valueSetter(value); _editingController.text = ''; Navigator.pop(context); } }, ), ); } } class YSCommentView extends StatefulWidget { final videoId; const YSCommentView({Key key, this.videoId}) : super(key: key); @override _YSCommentViewState createState() => _YSCommentViewState(); } class _YSCommentViewState extends State { List _commentArray = []; @override Widget build(BuildContext context) { return YSRefreshLoad( key: refreshKey2, dataWidget: SingleChildScrollView( child: ListView.separated( itemBuilder: (context,index){ Map item = _commentArray[index]; return Container( padding: EdgeInsets.only(top: 10,bottom: 10), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 40, width: 40, decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.all(Radius.circular(50)), image: DecorationImage(image: NetworkImage(item['user_avatar']),fit: BoxFit.cover) ), ), Container( width: MediaQuery.of(context).size.width-60, padding: EdgeInsets.only(left: 15), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item['user_simple_name']??'',style: TextStyle(fontSize: 15,color: Color(0xFF3A3A3C),fontWeight: FontWeight.bold),maxLines: 1,), Container( padding: EdgeInsets.only(top: 8,bottom: 8), child: Text(item['body']??'',style: TextStyle(fontSize: 15,color: Color(0xFF707070)),maxLines: 1,), ), Text(item['created_at']??'',style: TextStyle(fontSize: 12,color: Color(0xFF707070)),maxLines: 1,), ], ), ) ], ), ); }, separatorBuilder: (context,index){ return Divider(color: Colors.grey,height: 0.1,thickness: 0.1,); }, itemCount: _commentArray.length, padding: EdgeInsets.only(left: 10,right: 10), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), ), ), url: 'train/video/comment', request: {'video_id':widget.videoId}, postData: (value){ _commentArray = value; setState(() {}); }, ); } } class YSVideoHorizontal extends StatefulWidget { final VideoPlayerController player; final title; const YSVideoHorizontal({Key key, this.player, this.title}) : super(key: key); @override _YSVideoHorizontalState createState() => _YSVideoHorizontalState(); } class _YSVideoHorizontalState extends State { var _playSet,_progressSet; String _startTime = '00:00:00'; String _endTime = '00:00:00'; @override void initState() { SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, //全屏时旋转方向,左边 ]); widget.player..addListener(() { Duration duration = widget.player.value.duration; Duration position = widget.player.value.position; _endTime = '${duration.inHours}'.padLeft(2,'0')+':'+'${duration.inMinutes}'.padLeft(2,'0')+':'+'${duration.inSeconds}'.padLeft(2,'0'); _startTime = '${position.inHours}'.padLeft(2,'0')+':'+'${position.inMinutes}'.padLeft(2,'0')+':'+'${position.inSeconds}'.padLeft(2,'0'); if(mounted&&_progressSet!=null){ _progressSet(() {}); } }); super.initState(); } @override void dispose() { widget.player..removeListener(() { }); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values); SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, ]); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Container( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: Stack( children: [ widget.player.value.aspectRatio<1?Center( child: AspectRatio( aspectRatio: widget.player.value.aspectRatio, child: VideoPlayer(widget.player,), ), ):VideoPlayer(widget.player,), _pauseView(controller: widget.player,), Container( width: MediaQuery.of(context).size.width, height: 30, margin: EdgeInsets.only(left: 15,right: 35,top: MediaQuery.of(context).padding.top+10), child: Row( children: [ GestureDetector( onTap: (){Navigator.pop(context);}, child: Icon(Icons.chevron_left,size: 30,color: Colors.white,), ), Container( width: MediaQuery.of(context).size.width-80, child: Text('${widget.title}',style: TextStyle(fontSize: 16,color: Colors.white),), ) ], ), ), StatefulBuilder( builder: (context,progressSet){ _progressSet = progressSet; return Container( margin: EdgeInsets.only(top: MediaQuery.of(context).size.height-50,left: 15,right: 15), child: Row( children: [ Container( width: 100, child: Row( children: [ GestureDetector( onTap: (){ _playSet(() { widget.player.value.isPlaying?widget.player.pause() : widget.player.play(); }); progressSet(() {}); }, child: Icon(widget.player.value.isPlaying?Icons.pause:Icons.play_arrow,size: 25,color: Colors.white,), ), Container( alignment: Alignment.center, width: 75, child: Text(_startTime,style: TextStyle(fontSize: 12,color: Colors.white),), ) ], ), ), Container( width: MediaQuery.of(context).size.width-230, height:6.5, child: VideoProgressIndicator( widget.player, allowScrubbing: true, colors: VideoProgressColors(playedColor: Colors.white,backgroundColor: Colors.black), ) ), Container( width: 100, child: Row( children: [ Container( alignment: Alignment.center, width: 75, child: Text(_endTime,style: TextStyle(fontSize: 12,color: Colors.white),), ), GestureDetector( onTap: (){Navigator.pop(context);}, child: Image.asset('lib/images/spsx.png',height: 25,width: 25,), ) ], ) ), ], ), ); }, ), ], ), ) , ); } _pauseView({VideoPlayerController controller}) { return StatefulBuilder( builder: (context,playSet){ _playSet = playSet; return Stack( children: [ AnimatedSwitcher( duration: Duration(milliseconds: 50), reverseDuration: Duration(milliseconds: 200), child: controller.value.isPlaying? Container():Container( alignment: Alignment.center, color: Colors.transparent, child: Icon( Icons.play_circle_filled, color: Colors.white, size: 50, ), ), ), GestureDetector( onTap: () { playSet(() { controller.value.isPlaying ? controller.pause() : controller.play(); }); _progressSet(() {}); }, ), ], ); }, ); } }