reason

重构首页

......@@ -287,7 +287,7 @@ class AccountPageState extends State<AccountPage> {
children: <Widget>[
InkWell(
onTap: () {
NavigatorUtils.push(context, Routes.home,
NavigatorUtils.push(context, Routes.navBarPage,
clearStack: true);
},
child: Container(
......@@ -298,7 +298,7 @@ class AccountPageState extends State<AccountPage> {
.onePoemBottomNavigationBarItemTitle,
style: const TextStyle(
color: Colors.white54,
fontSize: 15.0,
fontSize: 20.0,
),
),
),
......@@ -313,7 +313,7 @@ class AccountPageState extends State<AccountPage> {
.profileBottomNavigationBarItemTitle,
style: const TextStyle(
color: Colors.white54,
fontSize: 15.0,
fontSize: 20.0,
),
),
),
......
import 'dart:async';
import 'package:Parlando/poem/components/video_slides.dart';
import 'package:flutter/material.dart';
import 'package:getwidget/getwidget.dart';
import '../category/category_router.dart';
import '../events/trans_event.dart';
import '../net/dio_utils.dart';
import '../net/http_api.dart';
import '../routers/fluro_navigator.dart';
import 'package:flutter_easy_permission/easy_permissions.dart';
import '../util/toast_utils.dart';
import 'models/home_entity.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
......@@ -8,9 +21,43 @@ class Home extends StatefulWidget {
HomeState createState() => HomeState();
}
class HomeState extends State<Home> {
class HomeState extends State<Home> with WidgetsBindingObserver {
final PageController _controller = PageController();
bool isLoading = false;
int currentId = 0;
int currentPage = 0;
String currentPoemId = '';
String currentPoemType = '';
bool isFav = false;
bool isPraise = false;
bool isSharing = false;
late StreamSubscription bus;
List<Widget> videos = [];
static const permissions = [
Permissions.CAMERA,
Permissions.READ_EXTERNAL_STORAGE,
Permissions.RECORD_AUDIO,
Permissions.WRITE_EXTERNAL_STORAGE
];
static const permissionGroup = [
PermissionGroup.Camera,
PermissionGroup.Camera,
PermissionGroup.Microphone
];
late FlutterEasyPermission _easyPermission;
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
bus.cancel();
_easyPermission.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
......@@ -21,43 +68,111 @@ class HomeState extends State<Home> {
_getMore();
}
});
FlutterEasyPermission.has(perms: permissions, permsGroup: permissionGroup)
.then((value) {
if (value) {
FlutterEasyPermission.request(
perms: permissions,
permsGroup: permissionGroup,
rationale: "需要使用如下权限");
}
});
_easyPermission = FlutterEasyPermission()
..addPermissionCallback(onGranted: (requestCode, perms, perm) {
debugPrint("android获得授权:$perms");
debugPrint("iOS获得授权:$perm");
}, onDenied: (requestCode, perms, perm, isPermanent) {
if (isPermanent) {
FlutterEasyPermission.showAppSettingsDialog(title: "Camera");
} else {
debugPrint("android授权失败:$perms");
debugPrint("iOS授权失败:$perm");
}
}, onSettingsReturned: () {
FlutterEasyPermission.has(perms: permissions, permsGroup: []).then(
(value) => value
? debugPrint("已获得授权:$permissions")
: debugPrint("未获得授权:$permissions"));
});
_onRefresh();
}
/// 下拉刷新方法,为list重新赋值
Future<void> _onRefresh() async {
await Future.delayed(const Duration(seconds: 1), () {
print('refresh');
setState(() {});
});
isLoading = true;
currentPage = 0;
DioUtils.instance.asyncRequestNetwork<HomeEntity>(
Method.get,
HttpApi.home,
params: {'page_size': 80},
onSuccess: (data) {
isLoading = false;
videos.clear();
for (HomeData data in data!.data!) {
videos.add(VideoSlides(
poemId: data.poemId!,
poemType: data.type!,
url: data.url!,
));
}
setState(() {});
bus = eventBus.on<TransEvent>().listen((event) {});
},
onError: (code, msg) {
Toast.show("获取数据失败,请稍候再试...");
isLoading = false;
},
);
}
/// 上拉加载更多
Future<void> _getMore() async {
await Future.delayed(const Duration(seconds: 1), () {
print('_getMore');
setState(() {});
});
currentPage += 1;
isLoading = true;
DioUtils.instance.asyncRequestNetwork<HomeEntity>(
Method.get,
HttpApi.home,
params: {'page_size': 80, 'page': currentPage},
onSuccess: (data) {
isLoading = false;
for (HomeData data in data!.data!) {
videos.add(VideoSlides(
poemId: data.poemId!,
poemType: data.type!,
url: data.url!,
));
}
setState(() {});
bus = eventBus.on<TransEvent>().listen((event) {});
},
onError: (code, msg) {
Toast.show("获取数据失败,请稍候再试...");
isLoading = false;
},
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
RefreshIndicator(
//下拉刷新触发方法
onRefresh: _onRefresh,
//设置listView
child: PageView(
controller: _controller,
//设置滑动方向
scrollDirection: Axis.vertical,
children: const [
VideoSlides(),
VideoSlides(),
VideoSlides(),
],
),
),
isLoading
? const GFLoader()
: RefreshIndicator(
//下拉刷新触发方法
onRefresh: _onRefresh,
//设置listView
child: PageView(
controller: _controller,
//设置滑动方向
scrollDirection: Axis.vertical,
children: videos,
),
),
Positioned(
top: 18.0,
left: 10.0,
......@@ -81,7 +196,12 @@ class HomeState extends State<Home> {
style: TextStyle(color: Colors.white),
),
TextButton(
onPressed: () {},
onPressed: () {
NavigatorUtils.push(
context,
CategoryRouter.categoryPage,
);
},
child: const Text(
"妙众",
style: TextStyle(
......
import 'package:Parlando/account/page/account_page.dart';
import 'package:Parlando/home/home_page.dart';
import 'package:Parlando/poem/theme/tik_theme.dart';
import 'package:animated_radial_menu/animated_radial_menu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart';
import 'package:provider/provider.dart';
import '../../account/account_router.dart';
import '../../events/trans_event.dart';
import '../../routers/fluro_navigator.dart';
import '../../routers/routers.dart';
class NavBarPage extends StatefulWidget {
const NavBarPage({Key? key, required this.initialPage}) : super(key: key);
......@@ -31,46 +39,77 @@ class NavBarPageState extends State<NavBarPage> {
};
return Scaffold(
body: tabs[_currentPage],
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.home_filled,
size: 24,
),
label: 'Home',
tooltip: '',
),
BottomNavigationBarItem(
icon: Icon(
Icons.add_circle_outline_rounded,
size: 50,
),
activeIcon: Icon(
Icons.add_circle_rounded,
size: 50,
),
label: '',
tooltip: '',
),
BottomNavigationBarItem(
icon: Icon(
Icons.person_rounded,
size: 26,
),
label: 'Profile',
tooltip: '',
)
],
backgroundColor: TikTheme.tertiaryColor,
currentIndex: tabs.keys.toList().indexOf(_currentPage),
selectedItemColor: TikTheme.primaryColor,
unselectedItemColor: const Color(0x53FFFFFF),
onTap: (i) => setState(() => _currentPage = tabs.keys.toList()[i]),
showSelectedLabels: true,
showUnselectedLabels: true,
type: BottomNavigationBarType.fixed,
bottomNavigationBar: Consumer(
builder: (_, provider, __) {
return BottomAppBar(
color: Colors.grey,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
InkWell(
onTap: () {
NavigatorUtils.push(context, Routes.navBarPage,
clearStack: true);
},
child: Container(
alignment: Alignment.center,
height: 36.0,
child: Text(
ParlandoLocalizations.of(context)
.onePoemBottomNavigationBarItemTitle,
style: const TextStyle(
color: Colors.white54,
fontSize: 20.0,
),
),
),
),
InkWell(
onTap: () {
eventBus.fire(TransEvent());
NavigatorUtils.push(
context,
AccountRouter.accountPage,
);
},
child: Container(
alignment: Alignment.center,
height: 36.0,
child: Text(
ParlandoLocalizations.of(context)
.profileBottomNavigationBarItemTitle,
style: const TextStyle(
color: Colors.white54,
fontSize: 20.0,
),
),
),
),
]),
);
},
),
floatingActionButton: SizedBox(
height: 60,
child: RadialMenu(
children: [
RadialButton(
icon: const Icon(Icons.video_call_outlined),
buttonColor: Colors.teal,
onPress: () {
eventBus.fire(TransEvent());
}),
RadialButton(
icon: const Icon(Icons.mic_none_outlined),
buttonColor: Colors.green,
onPress: () {
eventBus.fire(TransEvent());
}),
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
......
import 'package:flutter/material.dart';
import 'package:getwidget/getwidget.dart';
import 'package:share_plus/share_plus.dart';
import '../theme/tik_theme.dart';
import '../theme/tik_video_player.dart';
class VideoSlides extends StatefulWidget {
const VideoSlides({Key? key}) : super(key: key);
const VideoSlides({
Key? key,
required this.poemId,
required this.poemType,
required this.url,
this.isPraise = false,
this.isCollect = false,
}) : super(key: key);
final int poemId;
final int poemType;
final String url;
final bool isPraise;
final bool isCollect;
@override
VideoSlidesState createState() => VideoSlidesState();
......@@ -29,8 +40,8 @@ class VideoSlidesState extends State<VideoSlides> {
color: Colors.black,
),
child: TikVideoPlayer(
path: 'assets/video/1656599376238999.mp4',
videoType: VideoType.asset,
path: widget.url,
videoType: VideoType.network,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 1,
autoPlay: true,
......@@ -50,8 +61,8 @@ class VideoSlidesState extends State<VideoSlides> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 70,
height: 330,
width: 60,
height: 240,
decoration: const BoxDecoration(
color: Color(0x4DC4C4C4),
borderRadius: BorderRadius.only(
......@@ -80,8 +91,8 @@ class VideoSlidesState extends State<VideoSlides> {
padding: const EdgeInsetsDirectional.fromSTEB(
0, 20, 0, 0),
child: Container(
width: 50,
height: 50,
width: 40,
height: 40,
decoration: const BoxDecoration(
color: Color(0x69EEEEEE),
shape: BoxShape.circle,
......@@ -89,19 +100,10 @@ class VideoSlidesState extends State<VideoSlides> {
child: const Icon(
Icons.favorite_rounded,
color: Colors.white,
size: 24,
size: 20,
),
),
),
Text(
'121.9k',
style: TikTheme.bodyText1.override(
fontFamily: 'Poppins',
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w300,
),
),
],
),
],
......@@ -124,8 +126,8 @@ class VideoSlidesState extends State<VideoSlides> {
child: InkWell(
onTap: () async {},
child: Container(
width: 50,
height: 50,
width: 40,
height: 40,
decoration: const BoxDecoration(
color: Color(0x69EEEEEE),
shape: BoxShape.circle,
......@@ -133,20 +135,11 @@ class VideoSlidesState extends State<VideoSlides> {
child: const Icon(
Icons.star,
color: Colors.white,
size: 34,
size: 20,
),
),
),
),
Text(
'+8.5',
style: TikTheme.bodyText1.override(
fontFamily: 'Poppins',
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w300,
),
),
],
),
],
......@@ -172,36 +165,29 @@ class VideoSlidesState extends State<VideoSlides> {
setState(() {});
Future.delayed(const Duration(seconds: 3),
() async {
setState(() => isSharing = false);
await Share.share('Share Me');
setState(() => isSharing = false);
await Share.share('一言以世界 临境不蹉跎');
});
},
child: Container(
width: 50,
height: 50,
width: 40,
height: 40,
decoration: const BoxDecoration(
color: Color(0x69EEEEEE),
shape: BoxShape.circle,
),
child: isSharing
? const Text("I")
? const GFLoader(
type: GFLoaderType.ios,
)
: const Icon(
Icons.share_rounded,
color: Colors.white,
size: 24,
size: 20,
),
),
),
),
Text(
'分享',
style: TikTheme.bodyText1.override(
fontFamily: 'Poppins',
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w300,
),
),
],
),
],
......
......@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class TikTheme {
static const Color primaryColor = Color(0xFFE48900);
static const Color secondaryColor = Color(0xFF1C1C4F);
static const Color tertiaryColor = Color(0xFF131B41);
static const Color primaryColor = Colors.grey;
static const Color secondaryColor = Colors.grey;
static const Color tertiaryColor = Colors.grey;
String primaryFontFamily = 'Poppins';
String secondaryFontFamily = 'Roboto';
......
......@@ -42,18 +42,18 @@ class TikVideoPlayer extends StatefulWidget {
class _TikVideoPlayerState extends State<TikVideoPlayer> {
late VideoPlayerController _videoPlayerController;
late ChewieController _chewieController;
ChewieController? _chewieController;
@override
void initState() {
super.initState();
initializePlayer();
super.initState();
}
@override
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
_chewieController!.dispose();
super.dispose();
}
......@@ -67,7 +67,7 @@ class _TikVideoPlayerState extends State<TikVideoPlayer> {
: widget.height;
double get aspectRatio =>
_chewieController.videoPlayerController.value.aspectRatio;
_chewieController!.videoPlayerController.value.aspectRatio;
Future initializePlayer() async {
_videoPlayerController = widget.videoType == VideoType.network
......@@ -97,8 +97,9 @@ class _TikVideoPlayerState extends State<TikVideoPlayer> {
child: SizedBox(
height: height,
width: width,
child: _chewieController.videoPlayerController.value.isInitialized
? Chewie(controller: _chewieController)
child: _chewieController != null &&
_chewieController!.videoPlayerController.value.isInitialized
? Chewie(controller: _chewieController!)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
......