mod: 首页布局

This commit is contained in:
guozhigq
2023-10-08 23:16:39 +08:00
parent 80e10aeaad
commit e19cf92992
8 changed files with 71 additions and 327 deletions

View File

@ -108,8 +108,7 @@ class Request {
dio.interceptors.add(LogInterceptor( dio.interceptors.add(LogInterceptor(
request: false, request: false,
requestHeader: false, requestHeader: false,
responseHeader: true, responseHeader: false,
requestBody: true,
)); ));
dio.transformer = BackgroundTransformer(); dio.transformer = BackgroundTransformer();

View File

@ -8,7 +8,8 @@ import 'package:pilipala/utils/feed_back.dart';
import './controller.dart'; import './controller.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key); Function? callFn;
HomePage({Key? key, this.callFn}) : super(key: key);
@override @override
State<HomePage> createState() => _HomePageState(); State<HomePage> createState() => _HomePageState();
@ -25,15 +26,16 @@ class _HomePageState extends State<HomePage>
showUserBottonSheet() { showUserBottonSheet() {
feedBack(); feedBack();
showModalBottomSheet( widget.callFn!();
context: context, // showModalBottomSheet(
builder: (_) => const SizedBox( // context: context,
height: 450, // builder: (_) => const SizedBox(
child: MinePage(), // height: 450,
), // child: MinePage(),
clipBehavior: Clip.hardEdge, // ),
isScrollControlled: true, // clipBehavior: Clip.hardEdge,
); // isScrollControlled: true,
// );
} }
@override @override
@ -50,37 +52,6 @@ class _HomePageState extends State<HomePage>
ctr: _homeController, ctr: _homeController,
callback: showUserBottonSheet, callback: showUserBottonSheet,
), ),
const SizedBox(height: 8),
// SizedBox(
// width: double.infinity,
// height: 42,
// child: Align(
// alignment: Alignment.center,
// child: TabBar(
// controller: _homeController.tabController,
// tabs: [
// for (var i in _homeController.tabs) Tab(text: i['label'])
// ],
// isScrollable: true,
// dividerColor: Colors.transparent,
// enableFeedback: true,
// splashBorderRadius: BorderRadius.circular(10),
// onTap: (value) {
// feedBack();
// if (_homeController.initialIndex == value) {
// _homeController.tabsCtrList[value]().animateToTop();
// }
// _homeController.initialIndex = value;
// },
// ),
// ),
// ),
// Expanded(
// child: TabBarView(
// controller: _homeController.tabController,
// children: _homeController.tabsPageList,
// ),
// ),
], ],
), ),
); );
@ -128,8 +99,6 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
), ),
child: Row( child: Row(
children: [ children: [
const Expanded(child: SearchPage()),
const SizedBox(width: 10),
Obx( Obx(
() => ctr!.userLogin.value () => ctr!.userLogin.value
? Stack( ? Stack(
@ -182,6 +151,8 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
), ),
), ),
), ),
const SizedBox(width: 10),
const Expanded(child: SearchPage()),
], ],
), ),
), ),

View File

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:pilipala/pages/media/index.dart';
import 'package:pilipala/pages/mine/index.dart';
class LeftDrawer extends StatefulWidget {
const LeftDrawer({super.key});
@override
State<LeftDrawer> createState() => _LeftDrawerState();
}
class _LeftDrawerState extends State<LeftDrawer> {
@override
Widget build(BuildContext context) {
return Drawer(
width: MediaQuery.of(context).size.width * 0.84,
child: const Column(
children: [
Expanded(child: MinePage()),
Expanded(child: MediaPage()),
],
),
);
}
}

View File

@ -5,52 +5,10 @@ import 'package:get/get.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
// import 'package:pilipala/pages/dynamics/index.dart'; // import 'package:pilipala/pages/dynamics/index.dart';
import 'package:pilipala/pages/home/view.dart';
import 'package:pilipala/pages/media/index.dart';
import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/storage.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
class MainController extends GetxController { class MainController extends GetxController {
List<Widget> pages = <Widget>[
const HomePage(),
// const DynamicsPage(),
const MediaPage(),
];
RxList navigationBars = [
{
'icon': const Icon(
Icons.favorite_outline,
size: 21,
),
'selectIcon': const Icon(
Icons.favorite,
size: 21,
),
'label': "首页",
},
// {
// 'icon': const Icon(
// Icons.motion_photos_on_outlined,
// size: 21,
// ),
// 'selectIcon': const Icon(
// Icons.motion_photos_on,
// size: 21,
// ),
// 'label': "动态",
// },
{
'icon': const Icon(
Icons.folder_outlined,
size: 20,
),
'selectIcon': const Icon(
Icons.folder,
size: 21,
),
'label': "媒体库",
}
].obs;
final StreamController<bool> bottomBarStream = final StreamController<bool> bottomBarStream =
StreamController<bool>.broadcast(); StreamController<bool>.broadcast();
Box setting = GStrorage.setting; Box setting = GStrorage.setting;

View File

@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:pilipala/pages/dynamics/index.dart'; import 'package:pilipala/pages/dynamics/index.dart';
import 'package:pilipala/pages/home/index.dart'; import 'package:pilipala/pages/home/index.dart';
import 'package:pilipala/pages/home/widgets/left_drawer.dart';
import 'package:pilipala/pages/media/index.dart'; import 'package:pilipala/pages/media/index.dart';
import 'package:pilipala/utils/event_bus.dart'; import 'package:pilipala/utils/event_bus.dart';
import 'package:pilipala/utils/feed_back.dart'; import 'package:pilipala/utils/feed_back.dart';
@ -18,80 +19,16 @@ class MainApp extends StatefulWidget {
class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin { class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
final MainController _mainController = Get.put(MainController()); final MainController _mainController = Get.put(MainController());
final HomeController _homeController = Get.put(HomeController()); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final DynamicsController _dynamicController = Get.put(DynamicsController());
final MediaController _mediaController = Get.put(MediaController());
PageController? _pageController;
late AnimationController? _animationController;
late Animation<double>? _fadeAnimation;
late Animation<double>? _slideAnimation;
int selectedIndex = 0; int selectedIndex = 0;
int? _lastSelectTime; //上次点击时间
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 800),
reverseDuration: const Duration(milliseconds: 0),
value: 1,
vsync: this,
);
_fadeAnimation =
Tween<double>(begin: 0.8, end: 1.0).animate(_animationController!);
_slideAnimation =
Tween(begin: 0.8, end: 1.0).animate(_animationController!);
_lastSelectTime = DateTime.now().millisecondsSinceEpoch;
_pageController = PageController(initialPage: selectedIndex);
} }
void setIndex(int value) async { void openDrawer() {
feedBack(); _scaffoldKey.currentState?.openDrawer();
if (selectedIndex != value) {
selectedIndex = value;
_animationController!.reverse().then((_) {
selectedIndex = value;
_animationController!.forward();
});
setState(() {});
}
_pageController!.jumpToPage(value);
var currentPage = _mainController.pages[value];
if (currentPage is HomePage) {
if (_homeController.flag) {
// 单击返回顶部 双击并刷新
if (DateTime.now().millisecondsSinceEpoch - _lastSelectTime! < 500) {
_homeController.onRefresh();
} else {
_homeController.animateToTop();
}
_lastSelectTime = DateTime.now().millisecondsSinceEpoch;
}
_homeController.flag = true;
} else {
_homeController.flag = false;
}
if (currentPage is DynamicsPage) {
if (_dynamicController.flag) {
// 单击返回顶部 双击并刷新
if (DateTime.now().millisecondsSinceEpoch - _lastSelectTime! < 500) {
_dynamicController.onRefresh();
} else {
_dynamicController.animateToTop();
}
_lastSelectTime = DateTime.now().millisecondsSinceEpoch;
}
_dynamicController.flag = true;
} else {
_dynamicController.flag = false;
}
if (currentPage is MediaPage) {
_mediaController.queryFavFolder();
}
} }
@override @override
@ -113,55 +50,10 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
return WillPopScope( return WillPopScope(
onWillPop: () => _mainController.onBackPressed(context), onWillPop: () => _mainController.onBackPressed(context),
child: Scaffold( child: Scaffold(
key: _scaffoldKey,
extendBody: true, extendBody: true,
body: FadeTransition( drawer: const LeftDrawer(),
opacity: _fadeAnimation!, body: HomePage(callFn: openDrawer),
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0.5),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: _slideAnimation!,
curve: Curves.fastOutSlowIn,
reverseCurve: Curves.linear,
),
),
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: (index) {
selectedIndex = index;
setState(() {});
},
children: _mainController.pages,
),
),
),
bottomNavigationBar: StreamBuilder(
stream: _mainController.bottomBarStream.stream,
initialData: true,
builder: (context, AsyncSnapshot snapshot) {
return AnimatedSlide(
curve: Curves.easeInOutCubicEmphasized,
duration: const Duration(milliseconds: 1000),
offset: Offset(0, snapshot.data ? 0 : 1),
child: NavigationBar(
onDestinationSelected: (value) => setIndex(value),
selectedIndex: selectedIndex,
destinations: <Widget>[
..._mainController.navigationBars.map((e) {
return NavigationDestination(
icon: e['icon'],
selectedIcon: e['selectIcon'],
label: e['label'],
);
}).toList(),
],
),
);
},
),
), ),
); );
} }

View File

@ -1,9 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/models/user/fav_folder.dart';
import 'package:pilipala/pages/media/index.dart'; import 'package:pilipala/pages/media/index.dart';
import 'package:pilipala/utils/utils.dart';
class MediaPage extends StatefulWidget { class MediaPage extends StatefulWidget {
const MediaPage({super.key}); const MediaPage({super.key});
@ -15,7 +12,6 @@ class MediaPage extends StatefulWidget {
class _MediaPageState extends State<MediaPage> class _MediaPageState extends State<MediaPage>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late MediaController mediaController; late MediaController mediaController;
late Future _futureBuilderFuture;
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
@ -24,13 +20,6 @@ class _MediaPageState extends State<MediaPage>
void initState() { void initState() {
super.initState(); super.initState();
mediaController = Get.put(MediaController()); mediaController = Get.put(MediaController());
_futureBuilderFuture = mediaController.queryFavFolder();
mediaController.userLogin.listen((status) {
setState(() {
_futureBuilderFuture = mediaController.queryFavFolder();
});
});
} }
@override @override
@ -38,22 +27,8 @@ class _MediaPageState extends State<MediaPage>
super.build(context); super.build(context);
Color primary = Theme.of(context).colorScheme.primary; Color primary = Theme.of(context).colorScheme.primary;
return Scaffold( return Scaffold(
appBar: AppBar(toolbarHeight: 30),
body: Column( body: Column(
children: [ children: [
ListTile(
leading: null,
title: Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
'媒体库',
style: TextStyle(
fontSize: Theme.of(context).textTheme.titleLarge!.fontSize,
fontWeight: FontWeight.bold,
),
),
),
),
for (var i in mediaController.list) ...[ for (var i in mediaController.list) ...[
ListTile( ListTile(
onTap: () => i['onTap'](), onTap: () => i['onTap'](),
@ -79,71 +54,3 @@ class _MediaPageState extends State<MediaPage>
); );
} }
} }
class FavFolderItem extends StatelessWidget {
const FavFolderItem({super.key, this.item, this.index});
final FavFolderItemData? item;
final int? index;
@override
Widget build(BuildContext context) {
String heroTag = Utils.makeHeroTag(item!.fid);
return Container(
margin: EdgeInsets.only(left: index == 0 ? 20 : 0, right: 14),
child: GestureDetector(
onTap: () => Get.toNamed('/favDetail',
arguments: item,
parameters: {'mediaId': item!.id.toString(), 'heroTag': heroTag}),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 12),
Container(
width: 180,
height: 110,
margin: const EdgeInsets.only(bottom: 8),
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Theme.of(context).colorScheme.onInverseSurface,
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.onInverseSurface,
offset: const Offset(4, -12), // 阴影与容器的距离
blurRadius: 0.0, // 高斯的标准偏差与盒子的形状卷积。
spreadRadius: 0.0, // 在应用模糊之前,框应该膨胀的量。
),
],
),
child: LayoutBuilder(
builder: (context, BoxConstraints box) {
return Hero(
tag: heroTag,
child: NetworkImgLayer(
src: item!.cover,
width: box.maxWidth,
height: box.maxHeight,
),
);
},
),
),
Text(
' ${item!.title}',
overflow: TextOverflow.fade,
maxLines: 1,
),
Text(
'${item!.mediaCount}条视频',
style: Theme.of(context)
.textTheme
.labelSmall!
.copyWith(color: Theme.of(context).colorScheme.outline),
)
],
),
),
);
}
}

View File

@ -72,12 +72,8 @@ class _MinePageState extends State<MinePage> {
const SizedBox(width: 10), const SizedBox(width: 10),
], ],
), ),
body: LayoutBuilder( body: SingleChildScrollView(
builder: (context, constraint) {
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
child: SizedBox(
height: constraint.maxHeight,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 10), const SizedBox(height: 10),
@ -89,8 +85,7 @@ class _MinePageState extends State<MinePage> {
return const SizedBox(); return const SizedBox();
} }
if (snapshot.data['status']) { if (snapshot.data['status']) {
return Obx( return Obx(() => userInfoBuild(mineController, context));
() => userInfoBuild(mineController, context));
} else { } else {
return userInfoBuild(mineController, context); return userInfoBuild(mineController, context);
} }
@ -103,9 +98,6 @@ class _MinePageState extends State<MinePage> {
), ),
), ),
); );
},
),
);
} }
Widget userInfoBuild(_mineController, context) { Widget userInfoBuild(_mineController, context) {

View File

@ -43,7 +43,7 @@ bool iosTransition =
class Routes { class Routes {
static final List<GetPage> getPages = [ static final List<GetPage> getPages = [
// 首页(推荐) // 首页(推荐)
CustomGetPage(name: '/', page: () => const HomePage()), CustomGetPage(name: '/', page: () => HomePage()),
// 热门 // 热门
CustomGetPage(name: '/hot', page: () => const HotPage()), CustomGetPage(name: '/hot', page: () => const HotPage()),
// 视频详情 // 视频详情