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(
request: false,
requestHeader: false,
responseHeader: true,
requestBody: true,
responseHeader: false,
));
dio.transformer = BackgroundTransformer();

View File

@ -8,7 +8,8 @@ import 'package:pilipala/utils/feed_back.dart';
import './controller.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
Function? callFn;
HomePage({Key? key, this.callFn}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
@ -25,15 +26,16 @@ class _HomePageState extends State<HomePage>
showUserBottonSheet() {
feedBack();
showModalBottomSheet(
context: context,
builder: (_) => const SizedBox(
height: 450,
child: MinePage(),
),
clipBehavior: Clip.hardEdge,
isScrollControlled: true,
);
widget.callFn!();
// showModalBottomSheet(
// context: context,
// builder: (_) => const SizedBox(
// height: 450,
// child: MinePage(),
// ),
// clipBehavior: Clip.hardEdge,
// isScrollControlled: true,
// );
}
@override
@ -50,37 +52,6 @@ class _HomePageState extends State<HomePage>
ctr: _homeController,
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(
children: [
const Expanded(child: SearchPage()),
const SizedBox(width: 10),
Obx(
() => ctr!.userLogin.value
? 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:hive/hive.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/utils.dart';
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 =
StreamController<bool>.broadcast();
Box setting = GStrorage.setting;

View File

@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/pages/dynamics/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/utils/event_bus.dart';
import 'package:pilipala/utils/feed_back.dart';
@ -18,80 +19,16 @@ class MainApp extends StatefulWidget {
class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
final MainController _mainController = Get.put(MainController());
final HomeController _homeController = Get.put(HomeController());
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;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
int selectedIndex = 0;
int? _lastSelectTime; //上次点击时间
@override
void 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 {
feedBack();
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();
}
void openDrawer() {
_scaffoldKey.currentState?.openDrawer();
}
@override
@ -113,55 +50,10 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
return WillPopScope(
onWillPop: () => _mainController.onBackPressed(context),
child: Scaffold(
key: _scaffoldKey,
extendBody: true,
body: FadeTransition(
opacity: _fadeAnimation!,
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(),
],
),
);
},
),
drawer: const LeftDrawer(),
body: HomePage(callFn: openDrawer),
),
);
}

View File

@ -1,9 +1,6 @@
import 'package:flutter/material.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/utils/utils.dart';
class MediaPage extends StatefulWidget {
const MediaPage({super.key});
@ -15,7 +12,6 @@ class MediaPage extends StatefulWidget {
class _MediaPageState extends State<MediaPage>
with AutomaticKeepAliveClientMixin {
late MediaController mediaController;
late Future _futureBuilderFuture;
@override
bool get wantKeepAlive => true;
@ -24,13 +20,6 @@ class _MediaPageState extends State<MediaPage>
void initState() {
super.initState();
mediaController = Get.put(MediaController());
_futureBuilderFuture = mediaController.queryFavFolder();
mediaController.userLogin.listen((status) {
setState(() {
_futureBuilderFuture = mediaController.queryFavFolder();
});
});
}
@override
@ -38,22 +27,8 @@ class _MediaPageState extends State<MediaPage>
super.build(context);
Color primary = Theme.of(context).colorScheme.primary;
return Scaffold(
appBar: AppBar(toolbarHeight: 30),
body: Column(
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) ...[
ListTile(
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,38 +72,30 @@ class _MinePageState extends State<MinePage> {
const SizedBox(width: 10),
],
),
body: LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: SizedBox(
height: constraint.maxHeight,
child: Column(
children: [
const SizedBox(height: 10),
FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
return Obx(
() => userInfoBuild(mineController, context));
} else {
return userInfoBuild(mineController, context);
}
} else {
return userInfoBuild(mineController, context);
}
},
),
],
),
body: SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: Column(
children: [
const SizedBox(height: 10),
FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
return Obx(() => userInfoBuild(mineController, context));
} else {
return userInfoBuild(mineController, context);
}
} else {
return userInfoBuild(mineController, context);
}
},
),
);
},
],
),
),
);
}

View File

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