Commit 91fe517ac54706dd7f9aadea04042299247df8c5

Authored by liangchengyou
1 parent ea2c8205

feat:看视频功能开发

assets/images/video_stop.png 0 → 100644

9.56 KB

lib/app/app.dart
@@ -24,7 +24,7 @@ class App extends StatelessWidget { @@ -24,7 +24,7 @@ class App extends StatelessWidget {
24 title: 'WowEnglish', 24 title: 'WowEnglish',
25 theme: ThemeData( 25 theme: ThemeData(
26 fontFamily: 'HannotateSC', 26 fontFamily: 'HannotateSC',
27 - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), 27 + colorScheme: ColorScheme.fromSeed(seedColor: Colors.white),
28 useMaterial3: true, 28 useMaterial3: true,
29 ), 29 ),
30 builder: EasyLoading.init( 30 builder: EasyLoading.init(
lib/video/lookvideo/look_video_page.dart
@@ -3,14 +3,20 @@ import 'package:flutter_bloc/flutter_bloc.dart'; @@ -3,14 +3,20 @@ import 'package:flutter_bloc/flutter_bloc.dart';
3 import 'package:wow_english/video/lookvideo/bloc/look_video_bloc.dart'; 3 import 'package:wow_english/video/lookvideo/bloc/look_video_bloc.dart';
4 import 'package:wow_english/video/lookvideo/widgets/video_widget.dart'; 4 import 'package:wow_english/video/lookvideo/widgets/video_widget.dart';
5 5
6 -class LookVideoPage extends StatelessWidget { 6 +class LookVideoPage extends StatefulWidget {
7 const LookVideoPage({super.key}); 7 const LookVideoPage({super.key});
8 8
9 @override 9 @override
  10 + State<StatefulWidget> createState() {
  11 + return _LookVideoPageState();
  12 + }
  13 +}
  14 +
  15 +class _LookVideoPageState extends State<LookVideoPage> {
  16 + @override
10 Widget build(BuildContext context) { 17 Widget build(BuildContext context) {
11 - return BlocProvider(  
12 - create: (context) => LookVideoBloc(),  
13 - child: _LookVideoPage(), 18 + return const VideoWidget(
  19 + videoUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4',
14 ); 20 );
15 } 21 }
16 } 22 }
lib/video/lookvideo/widgets/video_opera_widget.dart
@@ -2,13 +2,32 @@ import &#39;package:flutter/material.dart&#39;; @@ -2,13 +2,32 @@ import &#39;package:flutter/material.dart&#39;;
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/extension/string_extension.dart'; 3 import 'package:wow_english/common/extension/string_extension.dart';
4 4
  5 +enum OperationType {
  6 + //返回
  7 + back,
  8 + //字幕
  9 + subtitlesState,
  10 + //静音
  11 + audioState,
  12 + //暂停/播放
  13 + playState,
  14 +}
  15 +
5 class VideoOperaWidget extends StatefulWidget { 16 class VideoOperaWidget extends StatefulWidget {
6 - const VideoOperaWidget({super.key, this.currentTime = '00:00', this.totalTime = '00:00', this.degree = 0.0,}); 17 + const VideoOperaWidget({super.key,
  18 + this.currentTime = '00:00',
  19 + this.totalTime = '00:00',
  20 + this.degree = 0.0,
  21 + this.actionEvent,
  22 + this.isPlay = true
  23 + });
7 //当前播放时间 24 //当前播放时间
8 final String currentTime; 25 final String currentTime;
9 //总时间 26 //总时间
10 final String totalTime; 27 final String totalTime;
11 final double degree; 28 final double degree;
  29 + final bool isPlay;
  30 + final Function(OperationType type)? actionEvent;
12 31
13 @override 32 @override
14 State<StatefulWidget> createState() { 33 State<StatefulWidget> createState() {
@@ -17,26 +36,43 @@ class VideoOperaWidget extends StatefulWidget { @@ -17,26 +36,43 @@ class VideoOperaWidget extends StatefulWidget {
17 } 36 }
18 37
19 class _VideoOperaWidgetState extends State<VideoOperaWidget> { 38 class _VideoOperaWidgetState extends State<VideoOperaWidget> {
  39 +
  40 + //是否在滑动
  41 + late bool isSlider;
  42 + late double sliderValue;
  43 +
  44 + @override
  45 + void initState() {
  46 + super.initState();
  47 + isSlider = false;
  48 + sliderValue = 0.0;
  49 + }
  50 +
20 @override 51 @override
21 Widget build(BuildContext context) { 52 Widget build(BuildContext context) {
22 - return SafeArea(  
23 - child: SizedBox(  
24 - width: double.infinity,  
25 - height: double.infinity,  
26 - child: Column(  
27 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
28 - children: [  
29 - Padding(  
30 - padding: EdgeInsets.only(left: 8.5.w,right: 8.5.w,top: 11.h), 53 + return SizedBox(
  54 + width: double.infinity,
  55 + height: double.infinity,
  56 + child: Column(
  57 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  58 + children: [
  59 + SafeArea(
  60 + child: Padding(
  61 + padding: EdgeInsets.only(top: 11.h),
31 child: Row( 62 child: Row(
32 mainAxisAlignment: MainAxisAlignment.spaceBetween, 63 mainAxisAlignment: MainAxisAlignment.spaceBetween,
33 children: [ 64 children: [
34 Row( 65 Row(
35 children: [ 66 children: [
36 - Image.asset(  
37 - 'back_around'.assetPng,  
38 - height: 40,  
39 - width: 40 67 + GestureDetector(
  68 + onTap: (){
  69 + widget.actionEvent?.call(OperationType.back);
  70 + },
  71 + child: Image.asset(
  72 + 'back_around'.assetPng,
  73 + height: 40,
  74 + width: 40
  75 + ),
40 ), 76 ),
41 18.horizontalSpace, 77 18.horizontalSpace,
42 Container( 78 Container(
@@ -62,31 +98,83 @@ class _VideoOperaWidgetState extends State&lt;VideoOperaWidget&gt; { @@ -62,31 +98,83 @@ class _VideoOperaWidgetState extends State&lt;VideoOperaWidget&gt; {
62 ) 98 )
63 ], 99 ],
64 ), 100 ),
65 - Container(  
66 - height: 40.h,  
67 - alignment: Alignment.center,  
68 - decoration: BoxDecoration(  
69 - color: Colors.white,  
70 - borderRadius: BorderRadius.circular(6.r),  
71 - border: Border.all(  
72 - width: 1.5,  
73 - color: const Color(0xFF140C10)  
74 - )  
75 - ),  
76 - padding: EdgeInsets.symmetric(horizontal: 10.w),  
77 - child: Text(  
78 - '中/英',  
79 - style: TextStyle(  
80 - fontSize: 20.sp,  
81 - color: const Color(0xFF333333), 101 + GestureDetector(
  102 + onTap: () {
  103 + widget.actionEvent?.call(OperationType.subtitlesState);
  104 + },
  105 + child: Container(
  106 + height: 40.h,
  107 + alignment: Alignment.center,
  108 + decoration: BoxDecoration(
  109 + color: Colors.white,
  110 + borderRadius: BorderRadius.circular(6.r),
  111 + border: Border.all(
  112 + width: 1.5,
  113 + color: const Color(0xFF140C10)
  114 + )
  115 + ),
  116 + padding: EdgeInsets.symmetric(horizontal: 10.w),
  117 + child: Text(
  118 + '中/英',
  119 + style: TextStyle(
  120 + fontSize: 20.sp,
  121 + color: const Color(0xFF333333),
  122 + ),
82 ), 123 ),
83 ), 124 ),
84 ) 125 )
85 ], 126 ],
86 ), 127 ),
87 - )  
88 - ],  
89 - ), 128 + ),
  129 + ),
  130 + Container(
  131 + color: Colors.white10,
  132 + height: 47.h+ScreenUtil().bottomBarHeight,
  133 + padding: EdgeInsets.symmetric(horizontal: 11.w),
  134 + child: Column(
  135 + mainAxisAlignment: MainAxisAlignment.start,
  136 + children: [
  137 + Row(
  138 + children: [
  139 + IconButton(onPressed: (){
  140 + widget.actionEvent?.call(OperationType.playState);
  141 + }, icon: widget.isPlay?const Icon(Icons.pause,color: Colors.white,):const Icon(Icons.play_arrow,color: Colors.white),),
  142 + Expanded(
  143 + child: Slider(
  144 + activeColor: Colors.blue,
  145 + inactiveColor: Colors.white,
  146 + value: isSlider?sliderValue:widget.degree,
  147 + onChangeStart: (value) {
  148 + setState(() {
  149 + isSlider = true;
  150 + sliderValue = value;
  151 + });
  152 + },
  153 + onChangeEnd: (value) {
  154 + setState(() {
  155 + isSlider = false;
  156 + });
  157 + },
  158 + onChanged: (value) {
  159 + setState(() {
  160 + sliderValue = value;
  161 + });
  162 + },
  163 + ),
  164 + ),
  165 + Text(
  166 + '${widget.currentTime}/${widget.totalTime}',
  167 + style: TextStyle(
  168 + color: Colors.white,
  169 + fontSize: 12.sp
  170 + ),
  171 + )
  172 + ],
  173 + ),
  174 + ],
  175 + ),
  176 + )
  177 + ],
90 ), 178 ),
91 ); 179 );
92 } 180 }
lib/video/lookvideo/widgets/video_widget.dart
@@ -2,6 +2,7 @@ import &#39;package:common_utils/common_utils.dart&#39;; @@ -2,6 +2,7 @@ import &#39;package:common_utils/common_utils.dart&#39;;
2 import 'package:flutter/foundation.dart'; 2 import 'package:flutter/foundation.dart';
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
4 import 'package:video_player/video_player.dart'; 4 import 'package:video_player/video_player.dart';
  5 +import 'package:wow_english/common/extension/string_extension.dart';
5 import 'package:wow_english/video/lookvideo/widgets/video_opera_widget.dart'; 6 import 'package:wow_english/video/lookvideo/widgets/video_opera_widget.dart';
6 7
7 class VideoWidget extends StatefulWidget { 8 class VideoWidget extends StatefulWidget {
@@ -72,6 +73,21 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; { @@ -72,6 +73,21 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
72 timerUtil = null; 73 timerUtil = null;
73 } 74 }
74 75
  76 + void actionType(OperationType type) async {
  77 + if (type == OperationType.back) {
  78 + Navigator.pop(context);
  79 + } else if (type == OperationType.playState) {
  80 + if (_controller!.value.isPlaying) {
  81 + _controller!.pause();
  82 + } else {
  83 + _controller!.play();
  84 + }
  85 + setState(() {
  86 +
  87 + });
  88 + }
  89 + }
  90 +
75 @override 91 @override
76 void initState() { 92 void initState() {
77 super.initState(); 93 super.initState();
@@ -111,6 +127,9 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; { @@ -111,6 +127,9 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
111 } else { 127 } else {
112 _controller!.play(); 128 _controller!.play();
113 } 129 }
  130 + setState(() {
  131 +
  132 + });
114 } 133 }
115 }, 134 },
116 child: Center( 135 child: Center(
@@ -131,6 +150,23 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; { @@ -131,6 +150,23 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
131 currentTime: _currentTime, 150 currentTime: _currentTime,
132 totalTime: _totalTime, 151 totalTime: _totalTime,
133 degree: _playDegree, 152 degree: _playDegree,
  153 + isPlay: _controller!.value.isPlaying,
  154 + actionEvent: (OperationType type) {
  155 + actionType(type);
  156 + },
  157 + ),
  158 + ),
  159 + Offstage(
  160 + offstage: _controller!.value.isPlaying,
  161 + child: IconButton(
  162 + onPressed: () {
  163 + _controller!.play();
  164 + },
  165 + icon: Image.asset(
  166 + 'video_stop'.assetPng,
  167 + width: 70,
  168 + height: 70,
  169 + ),
134 ), 170 ),
135 ) 171 )
136 ], 172 ],