mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: 排行榜改用侧边栏显示分区
This commit is contained in:
@@ -9,20 +9,20 @@ import 'package:PiliPalaX/utils/storage.dart';
|
|||||||
class RankController extends GetxController with GetTickerProviderStateMixin {
|
class RankController extends GetxController with GetTickerProviderStateMixin {
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
late RxList tabs = [].obs;
|
late RxList tabs = [].obs;
|
||||||
RxInt initialIndex = 1.obs;
|
RxInt initialIndex = 0.obs;
|
||||||
late TabController tabController;
|
late TabController tabController;
|
||||||
late List tabsCtrList;
|
late List tabsCtrList;
|
||||||
late List<Widget> tabsPageList;
|
late List<Widget> tabsPageList;
|
||||||
Box setting = GStrorage.setting;
|
Box setting = GStrorage.setting;
|
||||||
late final StreamController<bool> searchBarStream =
|
// late final StreamController<bool> searchBarStream =
|
||||||
StreamController<bool>.broadcast();
|
// StreamController<bool>.broadcast();
|
||||||
late bool enableGradientBg;
|
late bool enableGradientBg;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
enableGradientBg =
|
// enableGradientBg =
|
||||||
setting.get(SettingBoxKey.enableGradientBg, defaultValue: true);
|
// setting.get(SettingBoxKey.enableGradientBg, defaultValue: true);
|
||||||
// 进行tabs配置
|
// 进行tabs配置
|
||||||
setTabConfig();
|
setTabConfig();
|
||||||
}
|
}
|
||||||
@@ -51,20 +51,20 @@ class RankController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
// 监听 tabController 切换
|
// 监听 tabController 切换
|
||||||
if (enableGradientBg) {
|
// if (enableGradientBg) {
|
||||||
tabController.animation!.addListener(() {
|
// tabController.animation!.addListener(() {
|
||||||
if (tabController.indexIsChanging) {
|
// if (tabController.indexIsChanging) {
|
||||||
if (initialIndex.value != tabController.index) {
|
// if (initialIndex.value != tabController.index) {
|
||||||
initialIndex.value = tabController.index;
|
// initialIndex.value = tabController.index;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
final int temp = tabController.animation!.value.round();
|
// final int temp = tabController.animation!.value.round();
|
||||||
if (initialIndex.value != temp) {
|
// if (initialIndex.value != temp) {
|
||||||
initialIndex.value = temp;
|
// initialIndex.value = temp;
|
||||||
tabController.index = initialIndex.value;
|
// tabController.index = initialIndex.value;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/utils/feed_back.dart';
|
import '../../utils/feed_back.dart';
|
||||||
import './controller.dart';
|
import './controller.dart';
|
||||||
|
|
||||||
class RankPage extends StatefulWidget {
|
class RankPage extends StatefulWidget {
|
||||||
@@ -16,8 +16,7 @@ class RankPage extends StatefulWidget {
|
|||||||
class _RankPageState extends State<RankPage>
|
class _RankPageState extends State<RankPage>
|
||||||
with AutomaticKeepAliveClientMixin, TickerProviderStateMixin {
|
with AutomaticKeepAliveClientMixin, TickerProviderStateMixin {
|
||||||
final RankController _rankController = Get.put(RankController());
|
final RankController _rankController = Get.put(RankController());
|
||||||
List videoList = [];
|
late int _selectedTabIndex = 0;
|
||||||
late Stream<bool> stream;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
@@ -25,127 +24,86 @@ class _RankPageState extends State<RankPage>
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
stream = _rankController.searchBarStream.stream;
|
_rankController.tabController =
|
||||||
|
TabController(vsync: this, length: _rankController.tabs.length);
|
||||||
|
_selectedTabIndex = _rankController.initialIndex.value;
|
||||||
|
_rankController.tabController.addListener(() {
|
||||||
|
print("_rankController.tabController.index");
|
||||||
|
print(_rankController.tabController.index);
|
||||||
|
if (!_rankController.tabController.indexIsChanging) {
|
||||||
|
// _rankController.onRefresh();
|
||||||
|
setState(() {
|
||||||
|
_selectedTabIndex = _rankController.tabController.index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_rankController.tabController.removeListener(() {});
|
||||||
|
_rankController.tabController.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
Brightness currentBrightness = MediaQuery.of(context).platformBrightness;
|
|
||||||
// 设置状态栏图标的亮度
|
|
||||||
if (_rankController.enableGradientBg) {
|
|
||||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
|
||||||
statusBarIconBrightness: currentBrightness == Brightness.light
|
|
||||||
? Brightness.dark
|
|
||||||
: Brightness.light,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
extendBody: true,
|
appBar: AppBar(
|
||||||
extendBodyBehindAppBar: false,
|
toolbarHeight: 0,
|
||||||
appBar: _rankController.enableGradientBg
|
elevation: 0,
|
||||||
? null
|
systemOverlayStyle: SystemUiOverlayStyle(
|
||||||
: AppBar(toolbarHeight: 0, elevation: 0),
|
// Customize the status bar here
|
||||||
body: Stack(
|
statusBarIconBrightness:
|
||||||
|
MediaQuery.of(context).platformBrightness == Brightness.dark
|
||||||
|
? Brightness.light
|
||||||
|
: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
// gradient background
|
const SizedBox(
|
||||||
if (_rankController.enableGradientBg) ...[
|
width: StyleString.cardSpace,
|
||||||
Align(
|
),
|
||||||
alignment: Alignment.topLeft,
|
LayoutBuilder(builder: (context, constraint) {
|
||||||
child: Opacity(
|
return SingleChildScrollView(
|
||||||
opacity: 0.6,
|
child: ConstrainedBox(
|
||||||
child: Container(
|
constraints:
|
||||||
width: MediaQuery.of(context).size.width,
|
BoxConstraints(minHeight: constraint.maxHeight + 100),
|
||||||
height: MediaQuery.of(context).size.height,
|
child: IntrinsicHeight(
|
||||||
decoration: BoxDecoration(
|
child: NavigationRail(
|
||||||
gradient: LinearGradient(
|
minWidth: 55.0,
|
||||||
colors: [
|
selectedIndex: _selectedTabIndex,
|
||||||
Theme.of(context)
|
onDestinationSelected: (int index) {
|
||||||
.colorScheme
|
|
||||||
.primary
|
|
||||||
.withOpacity(0.9),
|
|
||||||
Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary
|
|
||||||
.withOpacity(0.5),
|
|
||||||
Theme.of(context).colorScheme.surface
|
|
||||||
],
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
stops: const [0, 0.0034, 0.34]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const CustomAppBar(),
|
|
||||||
if (_rankController.tabs.length > 1) ...[
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 50,
|
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: TabBar(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
|
||||||
controller: _rankController.tabController,
|
|
||||||
tabs: [
|
|
||||||
for (var i in _rankController.tabs)
|
|
||||||
Tab(text: i['label'])
|
|
||||||
],
|
|
||||||
labelPadding: const EdgeInsets.symmetric(horizontal: 4),
|
|
||||||
isScrollable: true,
|
|
||||||
dividerColor: Colors.transparent,
|
|
||||||
enableFeedback: true,
|
|
||||||
splashBorderRadius: BorderRadius.circular(10),
|
|
||||||
tabAlignment: TabAlignment.center,
|
|
||||||
onTap: (value) {
|
|
||||||
feedBack();
|
feedBack();
|
||||||
if (_rankController.initialIndex.value == value) {
|
if (_selectedTabIndex == index) {
|
||||||
_rankController.tabsCtrList[value]().animateToTop();
|
_rankController.tabsCtrList[index]().animateToTop();
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_rankController.tabController.index = index;
|
||||||
|
_selectedTabIndex = index;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_rankController.initialIndex.value = value;
|
|
||||||
},
|
},
|
||||||
),
|
labelType: NavigationRailLabelType.none,
|
||||||
),
|
destinations: [
|
||||||
),
|
for (var tab in _rankController.tabs)
|
||||||
] else ...[
|
NavigationRailDestination(
|
||||||
const SizedBox(height: 6),
|
icon: Text(tab['label']),
|
||||||
],
|
// selectedIcon: Text(tab['label']),
|
||||||
Expanded(
|
label: const SizedBox.shrink(),
|
||||||
child: TabBarView(
|
),
|
||||||
controller: _rankController.tabController,
|
],
|
||||||
children: _rankController.tabsPageList,
|
))));
|
||||||
),
|
}),
|
||||||
),
|
Expanded(
|
||||||
],
|
child: TabBarView(
|
||||||
|
controller: _rankController.tabController,
|
||||||
|
children: _rankController.tabsPageList,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|
||||||
final double height;
|
|
||||||
|
|
||||||
const CustomAppBar({
|
|
||||||
super.key,
|
|
||||||
this.height = kToolbarHeight,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Size get preferredSize => Size.fromHeight(height);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final double top = MediaQuery.of(context).padding.top;
|
|
||||||
return Container(
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
height: top,
|
|
||||||
color: Colors.transparent,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -96,10 +96,10 @@ class _ZonePageState extends State<ZonePage> {
|
|||||||
crossAxisSpacing: StyleString.cardSpace,
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
// 最大宽度
|
// 最大宽度
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
mainAxisExtent: Grid.calculateActualWidth(
|
mainAxisExtent: Grid.calculateActualWidth(context,
|
||||||
context,
|
Grid.maxRowWidth * 2, StyleString.cardSpace,
|
||||||
Grid.maxRowWidth * 2,
|
screenWidthOffset:
|
||||||
StyleString.safeSpace) /
|
StyleString.cardSpace + 55) /
|
||||||
2.1 /
|
2.1 /
|
||||||
StyleString.aspectRatio),
|
StyleString.aspectRatio),
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
delegate: SliverChildBuilderDelegate((context, index) {
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ import 'storage.dart';
|
|||||||
class Grid {
|
class Grid {
|
||||||
static double maxRowWidth = GStrorage.setting.get(SettingBoxKey.maxRowWidth, defaultValue: 240.0) as double;
|
static double maxRowWidth = GStrorage.setting.get(SettingBoxKey.maxRowWidth, defaultValue: 240.0) as double;
|
||||||
|
|
||||||
static double calculateActualWidth(BuildContext context, double maxCrossAxisExtent, double crossAxisSpacing) {
|
static double calculateActualWidth(BuildContext context, double maxCrossAxisExtent, double crossAxisSpacing, {double? screenWidthOffset}) {
|
||||||
double screenWidth = MediaQuery.of(context).size.width;
|
double screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
if (screenWidthOffset != null) {
|
||||||
|
screenWidth -= screenWidthOffset;
|
||||||
|
}
|
||||||
int columnCount = ((screenWidth - crossAxisSpacing) / (maxCrossAxisExtent + crossAxisSpacing)).ceil();
|
int columnCount = ((screenWidth - crossAxisSpacing) / (maxCrossAxisExtent + crossAxisSpacing)).ceil();
|
||||||
if (columnCount < 1){
|
if (columnCount < 1){
|
||||||
columnCount = 1;
|
columnCount = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user