reason

重构首页

...@@ -6,7 +6,7 @@ buildscript { ...@@ -6,7 +6,7 @@ buildscript {
6 } 6 }
7 7
8 dependencies { 8 dependencies {
9 - classpath 'com.android.tools.build:gradle:7.0.2' 9 + classpath 'com.android.tools.build:gradle:7.0.4'
10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 classpath "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 11 classpath "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
12 } 12 }
......
...@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
3 distributionPath=wrapper/dists 3 distributionPath=wrapper/dists
4 zipStoreBase=GRADLE_USER_HOME 4 zipStoreBase=GRADLE_USER_HOME
5 zipStorePath=wrapper/dists 5 zipStorePath=wrapper/dists
6 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
...\ No newline at end of file ...\ No newline at end of file
6 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
...\ No newline at end of file ...\ No newline at end of file
......
No preview for this file type
1 -import 'package:Parlando/common/permission_request_widget.dart'; 1 +import 'package:Parlando/poem/components/video_slides.dart';
2 -import 'package:Parlando/routers/fluro_navigator.dart';
3 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
4 -import 'package:Parlando/account/page/account_page.dart';
5 -import 'package:Parlando/poem/page/poem_page.dart';
6 -import 'package:Parlando/widgets/double_tap_back_exit_app.dart';
7 -import 'package:provider/provider.dart';
8 -import 'provider/home_provider.dart';
9 -import 'package:permission_handler/permission_handler.dart';
10 3
11 class Home extends StatefulWidget { 4 class Home extends StatefulWidget {
12 const Home({Key? key}) : super(key: key); 5 const Home({Key? key}) : super(key: key);
13 6
14 @override 7 @override
15 - _HomeState createState() => _HomeState(); 8 + HomeState createState() => HomeState();
16 } 9 }
17 10
18 -class _HomeState extends State<Home> with RestorationMixin { 11 +class HomeState extends State<Home> {
19 - late List<Widget> _pageList; 12 + final PageController _controller = PageController();
20 - final PageController _pageController = PageController();
21 -
22 - HomeProvider provider = HomeProvider();
23 13
24 @override 14 @override
25 void initState() { 15 void initState() {
26 super.initState(); 16 super.initState();
27 - initData(); 17 + //设置pageView 滑动监听
28 - List<String> list = [ 18 + _controller.addListener(() {
29 - "为您更好的体验应用,所以需要获取您的手机摄像头权限,以保存您的一些偏好设置", 19 + if (_controller.position.pixels == _controller.position.maxScrollExtent) {
30 - "您已拒绝权限,所以无法保存您的一些偏好设置,将无法使用APP", 20 + print('滑动到了最底部');
31 - "您已拒绝权限,请在设置中心中同意APP的权限请求", 21 + _getMore();
32 - "其他错误" 22 + }
33 - ]; 23 + });
34 -
35 - Future.delayed(
36 - Duration.zero,
37 - () {
38 - NavigatorUtils.pushPageByFade(
39 - context: context,
40 - //目标页面
41 - targetPage: PermissionRequestWidget(
42 - //所需要申请的权限
43 - permission: Permission.camera,
44 - //显示关闭应用按钮
45 - isCloseApp: true,
46 - //提示文案
47 - permissionList: list,
48 - ),
49 - //权限申请结果
50 - dismissCallBack: (value) {},
51 - );
52 - },
53 - );
54 } 24 }
55 25
56 - @override 26 + /// 下拉刷新方法,为list重新赋值
57 - void dispose() { 27 + Future<void> _onRefresh() async {
58 - _pageController.dispose(); 28 + await Future.delayed(const Duration(seconds: 1), () {
59 - super.dispose(); 29 + print('refresh');
30 + setState(() {});
31 + });
60 } 32 }
61 33
62 - void initData() { 34 + /// 上拉加载更多
63 - _pageList = [ 35 + Future<void> _getMore() async {
64 - const PoemPage(), 36 + await Future.delayed(const Duration(seconds: 1), () {
65 - const AccountPage(), 37 + print('_getMore');
66 - ]; 38 + setState(() {});
39 + });
67 } 40 }
68 41
69 @override 42 @override
70 Widget build(BuildContext context) { 43 Widget build(BuildContext context) {
71 - return ChangeNotifierProvider<HomeProvider>( 44 + return Stack(
72 - create: (_) => provider, 45 + children: [
73 - child: DoubleTapBackExitApp( 46 + RefreshIndicator(
74 - child: Scaffold( 47 + //下拉刷新触发方法
75 - // 使用PageView的原因参看 https://zhuanlan.zhihu.com/p/58582876 48 + onRefresh: _onRefresh,
76 - body: PageView( 49 + //设置listView
77 - physics: const NeverScrollableScrollPhysics(), // 禁止滑动 50 + child: PageView(
78 - controller: _pageController, 51 + controller: _controller,
79 - onPageChanged: (int index) => provider.value = index, 52 + //设置滑动方向
80 - children: _pageList, 53 + scrollDirection: Axis.vertical,
54 + children: const [
55 + VideoSlides(),
56 + VideoSlides(),
57 + VideoSlides(),
58 + ],
59 + ),
60 + ),
61 + Positioned(
62 + top: 18.0,
63 + left: 10.0,
64 + right: 10.0,
65 + child: Center(
66 + child: Row(
67 + mainAxisAlignment: MainAxisAlignment.center,
68 + children: [
69 + TextButton(
70 + onPressed: () {},
71 + child: const Text(
72 + "临境",
73 + style: TextStyle(
74 + color: Colors.white,
75 + fontSize: 15,
76 + ),
77 + ),
78 + ),
79 + const Text(
80 + "|",
81 + style: TextStyle(color: Colors.white),
82 + ),
83 + TextButton(
84 + onPressed: () {},
85 + child: const Text(
86 + "妙众",
87 + style: TextStyle(
88 + color: Colors.white,
89 + fontSize: 15,
90 + ),
91 + ),
92 + ),
93 + const Text(
94 + "|",
95 + style: TextStyle(color: Colors.white),
96 + ),
97 + TextButton(
98 + onPressed: () => {},
99 + child: const Text(
100 + "新鲜",
101 + style: TextStyle(
102 + color: Colors.white,
103 + fontSize: 15,
104 + ),
105 + ),
106 + ),
107 + ],
108 + ),
81 ), 109 ),
82 ), 110 ),
83 - ), 111 + ],
84 ); 112 );
85 } 113 }
86 -
87 - @override
88 - String? get restorationId => 'home';
89 -
90 - @override
91 - void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
92 - registerForRestoration(provider, 'BottomNavigationBarCurrentIndex');
93 - }
94 } 114 }
......
...@@ -115,7 +115,7 @@ class _SplashPageState extends State<SplashPage> { ...@@ -115,7 +115,7 @@ class _SplashPageState extends State<SplashPage> {
115 115
116 void _goLogin() { 116 void _goLogin() {
117 if (SpUtil.containsKey(Constant.userToken)!) { 117 if (SpUtil.containsKey(Constant.userToken)!) {
118 - NavigatorUtils.push(context, Routes.home, clearStack: true); 118 + NavigatorUtils.push(context, Routes.navBarPage, clearStack: true);
119 } else { 119 } else {
120 NavigatorUtils.push(context, LoginRouter.loginPage, replace: true); 120 NavigatorUtils.push(context, LoginRouter.loginPage, replace: true);
121 } 121 }
......
...@@ -113,7 +113,7 @@ class _LoginPageState extends State<LoginPage> ...@@ -113,7 +113,7 @@ class _LoginPageState extends State<LoginPage>
113 params: params, 113 params: params,
114 onSuccess: (data) { 114 onSuccess: (data) {
115 SpUtil.putString(Constant.userToken, data!.data!.token!); 115 SpUtil.putString(Constant.userToken, data!.data!.token!);
116 - NavigatorUtils.push(context, Routes.home, clearStack: true); 116 + NavigatorUtils.push(context, Routes.navBarPage, clearStack: true);
117 _isLoading = false; 117 _isLoading = false;
118 }, 118 },
119 onError: (code, msg) { 119 onError: (code, msg) {
......
...@@ -90,7 +90,7 @@ class _RegisterPageState extends State<RegisterPage> ...@@ -90,7 +90,7 @@ class _RegisterPageState extends State<RegisterPage>
90 params: params, 90 params: params,
91 onSuccess: (data) { 91 onSuccess: (data) {
92 SpUtil.putString(Constant.userToken, data!.data!.token!); 92 SpUtil.putString(Constant.userToken, data!.data!.token!);
93 - NavigatorUtils.push(context, Routes.home, clearStack: true); 93 + NavigatorUtils.push(context, Routes.navBarPage, clearStack: true);
94 _isLoading = false; 94 _isLoading = false;
95 }, 95 },
96 onError: (code, msg) { 96 onError: (code, msg) {
......
1 +import 'package:Parlando/account/page/account_page.dart';
2 +import 'package:Parlando/home/home_page.dart';
3 +import 'package:Parlando/poem/theme/tik_theme.dart';
4 +import 'package:flutter/material.dart';
5 +
6 +class NavBarPage extends StatefulWidget {
7 + const NavBarPage({Key? key, required this.initialPage}) : super(key: key);
8 +
9 + final String initialPage;
10 +
11 + @override
12 + NavBarPageState createState() => NavBarPageState();
13 +}
14 +
15 +/// This is the private State class that goes with NavBarPage.
16 +class NavBarPageState extends State<NavBarPage> {
17 + String _currentPage = 'HomePage';
18 +
19 + @override
20 + void initState() {
21 + super.initState();
22 + _currentPage = widget.initialPage;
23 + }
24 +
25 + @override
26 + Widget build(BuildContext context) {
27 + final tabs = {
28 + 'HomePage': const Home(),
29 + 'UploadStatusPage': const AccountPage(),
30 + 'UserProfile': const AccountPage(),
31 + };
32 + return Scaffold(
33 + body: tabs[_currentPage],
34 + bottomNavigationBar: BottomNavigationBar(
35 + items: const <BottomNavigationBarItem>[
36 + BottomNavigationBarItem(
37 + icon: Icon(
38 + Icons.home_filled,
39 + size: 24,
40 + ),
41 + label: 'Home',
42 + tooltip: '',
43 + ),
44 + BottomNavigationBarItem(
45 + icon: Icon(
46 + Icons.add_circle_outline_rounded,
47 + size: 50,
48 + ),
49 + activeIcon: Icon(
50 + Icons.add_circle_rounded,
51 + size: 50,
52 + ),
53 + label: '',
54 + tooltip: '',
55 + ),
56 + BottomNavigationBarItem(
57 + icon: Icon(
58 + Icons.person_rounded,
59 + size: 26,
60 + ),
61 + label: 'Profile',
62 + tooltip: '',
63 + )
64 + ],
65 + backgroundColor: TikTheme.tertiaryColor,
66 + currentIndex: tabs.keys.toList().indexOf(_currentPage),
67 + selectedItemColor: TikTheme.primaryColor,
68 + unselectedItemColor: const Color(0x53FFFFFF),
69 + onTap: (i) => setState(() => _currentPage = tabs.keys.toList()[i]),
70 + showSelectedLabels: true,
71 + showUnselectedLabels: true,
72 + type: BottomNavigationBarType.fixed,
73 + ),
74 + );
75 + }
76 +}
1 +import 'package:flutter/material.dart';
2 +import 'package:share_plus/share_plus.dart';
3 +
4 +import '../theme/tik_theme.dart';
5 +import '../theme/tik_video_player.dart';
6 +
7 +class VideoSlides extends StatefulWidget {
8 + const VideoSlides({Key? key}) : super(key: key);
9 +
10 + @override
11 + VideoSlidesState createState() => VideoSlidesState();
12 +}
13 +
14 +class VideoSlidesState extends State<VideoSlides> {
15 + bool isSharing = false;
16 +
17 + @override
18 + Widget build(BuildContext context) {
19 + return Stack(
20 + children: [
21 + Container(
22 + width: double.infinity,
23 + height: double.infinity,
24 + constraints: const BoxConstraints(
25 + maxWidth: double.infinity,
26 + maxHeight: double.infinity,
27 + ),
28 + decoration: const BoxDecoration(
29 + color: Colors.black,
30 + ),
31 + child: TikVideoPlayer(
32 + path: 'assets/video/1656599376238999.mp4',
33 + videoType: VideoType.asset,
34 + width: MediaQuery.of(context).size.width,
35 + height: MediaQuery.of(context).size.height * 1,
36 + autoPlay: true,
37 + looping: true,
38 + showControls: false,
39 + allowFullScreen: false,
40 + allowPlaybackSpeedMenu: false,
41 + ),
42 + ),
43 + Row(
44 + mainAxisSize: MainAxisSize.max,
45 + mainAxisAlignment: MainAxisAlignment.end,
46 + crossAxisAlignment: CrossAxisAlignment.center,
47 + children: [
48 + Column(
49 + mainAxisSize: MainAxisSize.max,
50 + mainAxisAlignment: MainAxisAlignment.center,
51 + children: [
52 + Container(
53 + width: 70,
54 + height: 330,
55 + decoration: const BoxDecoration(
56 + color: Color(0x4DC4C4C4),
57 + borderRadius: BorderRadius.only(
58 + bottomLeft: Radius.circular(40),
59 + bottomRight: Radius.circular(0),
60 + topLeft: Radius.circular(40),
61 + topRight: Radius.circular(0),
62 + ),
63 + shape: BoxShape.rectangle,
64 + ),
65 + child: Column(
66 + crossAxisAlignment: CrossAxisAlignment.center,
67 + children: [
68 + Padding(
69 + padding:
70 + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0),
71 + child: Row(
72 + mainAxisSize: MainAxisSize.max,
73 + mainAxisAlignment: MainAxisAlignment.center,
74 + crossAxisAlignment: CrossAxisAlignment.start,
75 + children: [
76 + Column(
77 + mainAxisSize: MainAxisSize.max,
78 + children: [
79 + Padding(
80 + padding: const EdgeInsetsDirectional.fromSTEB(
81 + 0, 20, 0, 0),
82 + child: Container(
83 + width: 50,
84 + height: 50,
85 + decoration: const BoxDecoration(
86 + color: Color(0x69EEEEEE),
87 + shape: BoxShape.circle,
88 + ),
89 + child: const Icon(
90 + Icons.favorite_rounded,
91 + color: Colors.white,
92 + size: 24,
93 + ),
94 + ),
95 + ),
96 + Text(
97 + '121.9k',
98 + style: TikTheme.bodyText1.override(
99 + fontFamily: 'Poppins',
100 + color: Colors.white,
101 + fontSize: 16,
102 + fontWeight: FontWeight.w300,
103 + ),
104 + ),
105 + ],
106 + ),
107 + ],
108 + ),
109 + ),
110 + Padding(
111 + padding:
112 + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0),
113 + child: Row(
114 + mainAxisSize: MainAxisSize.max,
115 + mainAxisAlignment: MainAxisAlignment.center,
116 + crossAxisAlignment: CrossAxisAlignment.start,
117 + children: [
118 + Column(
119 + mainAxisSize: MainAxisSize.max,
120 + children: [
121 + Padding(
122 + padding: const EdgeInsetsDirectional.fromSTEB(
123 + 0, 20, 0, 0),
124 + child: InkWell(
125 + onTap: () async {},
126 + child: Container(
127 + width: 50,
128 + height: 50,
129 + decoration: const BoxDecoration(
130 + color: Color(0x69EEEEEE),
131 + shape: BoxShape.circle,
132 + ),
133 + child: const Icon(
134 + Icons.star,
135 + color: Colors.white,
136 + size: 34,
137 + ),
138 + ),
139 + ),
140 + ),
141 + Text(
142 + '+8.5',
143 + style: TikTheme.bodyText1.override(
144 + fontFamily: 'Poppins',
145 + color: Colors.white,
146 + fontSize: 16,
147 + fontWeight: FontWeight.w300,
148 + ),
149 + ),
150 + ],
151 + ),
152 + ],
153 + ),
154 + ),
155 + Padding(
156 + padding:
157 + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0),
158 + child: Row(
159 + mainAxisSize: MainAxisSize.max,
160 + mainAxisAlignment: MainAxisAlignment.center,
161 + crossAxisAlignment: CrossAxisAlignment.start,
162 + children: [
163 + Column(
164 + mainAxisSize: MainAxisSize.max,
165 + children: [
166 + Padding(
167 + padding: const EdgeInsetsDirectional.fromSTEB(
168 + 0, 20, 0, 0),
169 + child: InkWell(
170 + onTap: () async {
171 + isSharing = true;
172 + setState(() {});
173 + Future.delayed(const Duration(seconds: 3),
174 + () async {
175 + setState(() => isSharing = false);
176 + await Share.share('Share Me');
177 + });
178 + },
179 + child: Container(
180 + width: 50,
181 + height: 50,
182 + decoration: const BoxDecoration(
183 + color: Color(0x69EEEEEE),
184 + shape: BoxShape.circle,
185 + ),
186 + child: isSharing
187 + ? const Text("I")
188 + : const Icon(
189 + Icons.share_rounded,
190 + color: Colors.white,
191 + size: 24,
192 + ),
193 + ),
194 + ),
195 + ),
196 + Text(
197 + '分享',
198 + style: TikTheme.bodyText1.override(
199 + fontFamily: 'Poppins',
200 + color: Colors.white,
201 + fontSize: 16,
202 + fontWeight: FontWeight.w300,
203 + ),
204 + ),
205 + ],
206 + ),
207 + ],
208 + ),
209 + ),
210 + ],
211 + ),
212 + ),
213 + ],
214 + ),
215 + ],
216 + ),
217 + ],
218 + );
219 + }
220 +}
1 +import 'package:flutter/material.dart';
2 +
3 +class TikIconButton extends StatelessWidget {
4 + const TikIconButton(
5 + {Key? key,
6 + this.borderColor,
7 + this.borderRadius,
8 + this.borderWidth,
9 + this.buttonSize,
10 + this.fillColor,
11 + this.icon,
12 + this.onPressed})
13 + : super(key: key);
14 +
15 + final double? borderRadius;
16 + final double? buttonSize;
17 + final Color? fillColor;
18 + final Color? borderColor;
19 + final double? borderWidth;
20 + final Widget? icon;
21 + final void Function()? onPressed;
22 +
23 + @override
24 + Widget build(BuildContext context) => Material(
25 + borderRadius:
26 + borderRadius != null ? BorderRadius.circular(borderRadius!) : null,
27 + color: Colors.transparent,
28 + clipBehavior: Clip.antiAlias,
29 + child: Ink(
30 + width: buttonSize,
31 + height: buttonSize,
32 + decoration: BoxDecoration(
33 + color: fillColor,
34 + border: Border.all(
35 + color: borderColor ?? Colors.transparent,
36 + width: borderWidth ?? 0,
37 + ),
38 + borderRadius: borderRadius != null
39 + ? BorderRadius.circular(borderRadius!)
40 + : null,
41 + ),
42 + child: IconButton(
43 + icon: icon!,
44 + onPressed: onPressed,
45 + splashRadius: buttonSize,
46 + ),
47 + ),
48 + );
49 +}
1 +import 'package:flutter/material.dart';
2 +import 'package:google_fonts/google_fonts.dart';
3 +
4 +class TikTheme {
5 + static const Color primaryColor = Color(0xFFE48900);
6 + static const Color secondaryColor = Color(0xFF1C1C4F);
7 + static const Color tertiaryColor = Color(0xFF131B41);
8 +
9 + String primaryFontFamily = 'Poppins';
10 + String secondaryFontFamily = 'Roboto';
11 +
12 + static TextStyle get title1 => GoogleFonts.getFont(
13 + 'Poppins',
14 + color: const Color(0xFF303030),
15 + fontWeight: FontWeight.w600,
16 + fontSize: 24,
17 + );
18 +
19 + static TextStyle get title2 => GoogleFonts.getFont(
20 + 'Poppins',
21 + color: const Color(0xFF303030),
22 + fontWeight: FontWeight.w500,
23 + fontSize: 22,
24 + );
25 +
26 + static TextStyle get title3 => GoogleFonts.getFont(
27 + 'Poppins',
28 + color: const Color(0xFF303030),
29 + fontWeight: FontWeight.w500,
30 + fontSize: 20,
31 + );
32 +
33 + static TextStyle get subtitle1 => GoogleFonts.getFont(
34 + 'Poppins',
35 + color: const Color(0xFF757575),
36 + fontWeight: FontWeight.w500,
37 + fontSize: 18,
38 + );
39 +
40 + static TextStyle get subtitle2 => GoogleFonts.getFont(
41 + 'Poppins',
42 + color: const Color(0xFF616161),
43 + fontWeight: FontWeight.normal,
44 + fontSize: 16,
45 + );
46 +
47 + static TextStyle get bodyText1 => GoogleFonts.getFont(
48 + 'Poppins',
49 + color: const Color(0xFF303030),
50 + fontWeight: FontWeight.normal,
51 + fontSize: 14,
52 + );
53 +
54 + static TextStyle get bodyText2 => GoogleFonts.getFont(
55 + 'Poppins',
56 + color: const Color(0xFF424242),
57 + fontWeight: FontWeight.normal,
58 + fontSize: 14,
59 + );
60 +}
61 +
62 +extension TextStyleHelper on TextStyle {
63 + TextStyle override({
64 + required String fontFamily,
65 + required Color color,
66 + double? fontSize,
67 + FontWeight? fontWeight,
68 + FontStyle? fontStyle,
69 + bool useGoogleFonts = true,
70 + }) =>
71 + useGoogleFonts
72 + ? GoogleFonts.getFont(
73 + fontFamily,
74 + color: this.color,
75 + fontSize: fontSize ?? this.fontSize,
76 + fontWeight: fontWeight ?? this.fontWeight,
77 + fontStyle: fontStyle ?? this.fontStyle,
78 + )
79 + : copyWith(
80 + fontFamily: fontFamily,
81 + color: color,
82 + fontSize: fontSize,
83 + fontWeight: fontWeight,
84 + fontStyle: fontStyle,
85 + );
86 +}
1 +import 'package:chewie/chewie.dart';
2 +import 'package:flutter/material.dart';
3 +import 'package:flutter/services.dart';
4 +import 'package:video_player/video_player.dart';
5 +
6 +const kDefaultAspectRatio = 16 / 9;
7 +
8 +enum VideoType {
9 + asset,
10 + network,
11 +}
12 +
13 +class TikVideoPlayer extends StatefulWidget {
14 + const TikVideoPlayer({
15 + Key? key,
16 + required this.path,
17 + this.videoType = VideoType.network,
18 + this.width,
19 + this.height,
20 + this.aspectRatio,
21 + this.autoPlay = false,
22 + this.looping = false,
23 + this.showControls = true,
24 + this.allowFullScreen = true,
25 + this.allowPlaybackSpeedMenu = false,
26 + }) : super(key: key);
27 +
28 + final String path;
29 + final VideoType videoType;
30 + final double? width;
31 + final double? height;
32 + final double? aspectRatio;
33 + final bool autoPlay;
34 + final bool looping;
35 + final bool showControls;
36 + final bool allowFullScreen;
37 + final bool allowPlaybackSpeedMenu;
38 +
39 + @override
40 + State<StatefulWidget> createState() => _TikVideoPlayerState();
41 +}
42 +
43 +class _TikVideoPlayerState extends State<TikVideoPlayer> {
44 + late VideoPlayerController _videoPlayerController;
45 + late ChewieController _chewieController;
46 +
47 + @override
48 + void initState() {
49 + super.initState();
50 + initializePlayer();
51 + }
52 +
53 + @override
54 + void dispose() {
55 + _videoPlayerController.dispose();
56 + _chewieController.dispose();
57 + super.dispose();
58 + }
59 +
60 + double? get width => widget.width == null || widget.width! >= double.infinity
61 + ? MediaQuery.of(context).size.width
62 + : widget.width;
63 +
64 + double? get height =>
65 + widget.height == null || widget.height! >= double.infinity
66 + ? (width != null ? width! / aspectRatio : null)
67 + : widget.height;
68 +
69 + double get aspectRatio =>
70 + _chewieController.videoPlayerController.value.aspectRatio;
71 +
72 + Future initializePlayer() async {
73 + _videoPlayerController = widget.videoType == VideoType.network
74 + ? VideoPlayerController.network(widget.path)
75 + : VideoPlayerController.asset(widget.path);
76 + await _videoPlayerController.initialize();
77 + _chewieController = ChewieController(
78 + videoPlayerController: _videoPlayerController,
79 + deviceOrientationsOnEnterFullScreen: [
80 + DeviceOrientation.landscapeLeft,
81 + DeviceOrientation.landscapeRight,
82 + ],
83 + deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
84 + aspectRatio: widget.aspectRatio,
85 + autoPlay: widget.autoPlay,
86 + looping: widget.looping,
87 + showControls: widget.showControls,
88 + allowFullScreen: widget.allowFullScreen,
89 + allowPlaybackSpeedChanging: widget.allowPlaybackSpeedMenu,
90 + );
91 + setState(() {});
92 + }
93 +
94 + @override
95 + Widget build(BuildContext context) => FittedBox(
96 + fit: BoxFit.cover,
97 + child: SizedBox(
98 + height: height,
99 + width: width,
100 + child: _chewieController.videoPlayerController.value.isInitialized
101 + ? Chewie(controller: _chewieController)
102 + : Column(
103 + mainAxisAlignment: MainAxisAlignment.center,
104 + children: const [
105 + CircularProgressIndicator(),
106 + SizedBox(height: 20),
107 + Text('Loading'),
108 + ],
109 + ),
110 + ),
111 + );
112 +}
1 +import 'package:Parlando/poem/components/nav_bar_page.dart';
1 import 'package:fluro/fluro.dart'; 2 import 'package:fluro/fluro.dart';
2 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
3 import 'package:Parlando/account/account_router.dart'; 4 import 'package:Parlando/account/account_router.dart';
...@@ -15,6 +16,7 @@ import 'i_router.dart'; ...@@ -15,6 +16,7 @@ import 'i_router.dart';
15 import 'not_found_page.dart'; 16 import 'not_found_page.dart';
16 17
17 class Routes { 18 class Routes {
19 + static String navBarPage = '/nav/bar/page';
18 static String home = '/home'; 20 static String home = '/home';
19 static String webViewPage = '/webView'; 21 static String webViewPage = '/webView';
20 22
...@@ -30,6 +32,12 @@ class Routes { ...@@ -30,6 +32,12 @@ class Routes {
30 return const NotFoundPage(); 32 return const NotFoundPage();
31 }); 33 });
32 34
35 + router.define(navBarPage,
36 + handler: Handler(
37 + handlerFunc:
38 + (BuildContext? context, Map<String, List<String>> params) =>
39 + const NavBarPage(initialPage: 'HomePage')));
40 +
33 router.define(home, 41 router.define(home,
34 handler: Handler( 42 handler: Handler(
35 handlerFunc: 43 handlerFunc:
......
...@@ -183,6 +183,13 @@ packages: ...@@ -183,6 +183,13 @@ packages:
183 url: "https://pub.flutter-io.cn" 183 url: "https://pub.flutter-io.cn"
184 source: hosted 184 source: hosted
185 version: "2.0.1" 185 version: "2.0.1"
186 + chewie:
187 + dependency: "direct main"
188 + description:
189 + name: chewie
190 + url: "https://pub.flutter-io.cn"
191 + source: hosted
192 + version: "1.3.4"
186 clock: 193 clock:
187 dependency: transitive 194 dependency: transitive
188 description: 195 description:
...@@ -572,6 +579,13 @@ packages: ...@@ -572,6 +579,13 @@ packages:
572 url: "https://pub.flutter-io.cn" 579 url: "https://pub.flutter-io.cn"
573 source: hosted 580 source: hosted
574 version: "2.1.0" 581 version: "2.1.0"
582 + google_fonts:
583 + dependency: "direct main"
584 + description:
585 + name: google_fonts
586 + url: "https://pub.flutter-io.cn"
587 + source: hosted
588 + version: "3.0.1"
575 graphs: 589 graphs:
576 dependency: transitive 590 dependency: transitive
577 description: 591 description:
...@@ -1506,6 +1520,41 @@ packages: ...@@ -1506,6 +1520,41 @@ packages:
1506 url: "https://pub.flutter-io.cn" 1520 url: "https://pub.flutter-io.cn"
1507 source: hosted 1521 source: hosted
1508 version: "8.2.2" 1522 version: "8.2.2"
1523 + wakelock:
1524 + dependency: transitive
1525 + description:
1526 + name: wakelock
1527 + url: "https://pub.flutter-io.cn"
1528 + source: hosted
1529 + version: "0.6.1+2"
1530 + wakelock_macos:
1531 + dependency: transitive
1532 + description:
1533 + name: wakelock_macos
1534 + url: "https://pub.flutter-io.cn"
1535 + source: hosted
1536 + version: "0.4.0"
1537 + wakelock_platform_interface:
1538 + dependency: transitive
1539 + description:
1540 + name: wakelock_platform_interface
1541 + url: "https://pub.flutter-io.cn"
1542 + source: hosted
1543 + version: "0.3.0"
1544 + wakelock_web:
1545 + dependency: transitive
1546 + description:
1547 + name: wakelock_web
1548 + url: "https://pub.flutter-io.cn"
1549 + source: hosted
1550 + version: "0.4.0"
1551 + wakelock_windows:
1552 + dependency: transitive
1553 + description:
1554 + name: wakelock_windows
1555 + url: "https://pub.flutter-io.cn"
1556 + source: hosted
1557 + version: "0.2.0"
1509 watcher: 1558 watcher:
1510 dependency: transitive 1559 dependency: transitive
1511 description: 1560 description:
......
...@@ -86,7 +86,8 @@ dependencies: ...@@ -86,7 +86,8 @@ dependencies:
86 url: 'https://gitee.com/reasonpun/flutter_2d_amap.git' 86 url: 'https://gitee.com/reasonpun/flutter_2d_amap.git'
87 87
88 # tiktok 88 # tiktok
89 - video_player: ^2.2.10 89 + video_player: ^2.4.5
90 + chewie: ^1.3.4
90 # map取值 91 # map取值
91 safemap: ^2.0.0-nullsafety.0 92 safemap: ^2.0.0-nullsafety.0
92 # 基础的点击 93 # 基础的点击
...@@ -123,6 +124,9 @@ dependencies: ...@@ -123,6 +124,9 @@ dependencies:
123 image_gallery_saver: ^1.7.1 124 image_gallery_saver: ^1.7.1
124 125
125 flutter_easy_permission: ^1.1.2 126 flutter_easy_permission: ^1.1.2
127 +
128 + google_fonts: ^3.0.1
129 +
126 dependency_overrides: 130 dependency_overrides:
127 decimal: 1.5.0 131 decimal: 1.5.0
128 132
...@@ -206,6 +210,7 @@ flutter: ...@@ -206,6 +210,7 @@ flutter:
206 - assets/images/membership/ 210 - assets/images/membership/
207 - assets/images/share/ 211 - assets/images/share/
208 - assets/data/ 212 - assets/data/
213 + - assets/video/
209 - assets/data/Data.json 214 - assets/data/Data.json
210 - assets/data/friends/ 215 - assets/data/friends/
211 216
......