mod: 首页tab配置
This commit is contained in:
@ -37,8 +37,6 @@ class NetworkImgLayer extends StatelessWidget {
|
|||||||
int picQuality = setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10);
|
int picQuality = setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10);
|
||||||
|
|
||||||
// double pr = 2;
|
// double pr = 2;
|
||||||
print(
|
|
||||||
'${src!.startsWith('//') ? 'https:${src!}' : src!}@${quality ?? picQuality}q.webp');
|
|
||||||
return src != ''
|
return src != ''
|
||||||
? ClipRRect(
|
? ClipRRect(
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
|
55
lib/models/common/tab_type.dart
Normal file
55
lib/models/common/tab_type.dart
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/pages/bangumi/index.dart';
|
||||||
|
import 'package:pilipala/pages/hot/index.dart';
|
||||||
|
import 'package:pilipala/pages/live/index.dart';
|
||||||
|
import 'package:pilipala/pages/rcmd/index.dart';
|
||||||
|
|
||||||
|
enum TabType { live, rcmd, hot, bangumi }
|
||||||
|
|
||||||
|
extension TabTypeDesc on TabType {
|
||||||
|
String get description => ['直播', '推荐', '热门', '番剧'][index];
|
||||||
|
}
|
||||||
|
|
||||||
|
List tabsConfig = [
|
||||||
|
{
|
||||||
|
'icon': const Icon(
|
||||||
|
Icons.live_tv_outlined,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
'label': '直播',
|
||||||
|
'type': TabType.live,
|
||||||
|
'ctr': Get.find<LiveController>,
|
||||||
|
'page': const LivePage(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': const Icon(
|
||||||
|
Icons.thumb_up_off_alt_outlined,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
'label': '推荐',
|
||||||
|
'type': TabType.rcmd,
|
||||||
|
'ctr': Get.find<RcmdController>,
|
||||||
|
'page': const RcmdPage(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': const Icon(
|
||||||
|
Icons.whatshot_outlined,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
'label': '热门',
|
||||||
|
'type': TabType.hot,
|
||||||
|
'ctr': Get.find<HotController>,
|
||||||
|
'page': const HotPage(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': const Icon(
|
||||||
|
Icons.play_circle_outlined,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
'label': '番剧',
|
||||||
|
'type': TabType.bangumi,
|
||||||
|
'ctr': Get.find<BangumiController>,
|
||||||
|
'page': const BangumiPage(),
|
||||||
|
},
|
||||||
|
];
|
@ -2,56 +2,16 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/index.dart';
|
import 'package:pilipala/http/index.dart';
|
||||||
import 'package:pilipala/pages/bangumi/index.dart';
|
import 'package:pilipala/models/common/tab_type.dart';
|
||||||
import 'package:pilipala/pages/hot/index.dart';
|
|
||||||
import 'package:pilipala/pages/live/index.dart';
|
|
||||||
import 'package:pilipala/pages/rcmd/index.dart';
|
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
class HomeController extends GetxController with GetTickerProviderStateMixin {
|
class HomeController extends GetxController with GetTickerProviderStateMixin {
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
List tabs = [
|
late List tabs;
|
||||||
{
|
|
||||||
'icon': const Icon(
|
|
||||||
Icons.live_tv_outlined,
|
|
||||||
size: 15,
|
|
||||||
),
|
|
||||||
'label': '直播',
|
|
||||||
'type': 'live'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'icon': const Icon(
|
|
||||||
Icons.thumb_up_off_alt_outlined,
|
|
||||||
size: 15,
|
|
||||||
),
|
|
||||||
'label': '推荐',
|
|
||||||
'type': 'rcm'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'icon': const Icon(
|
|
||||||
Icons.whatshot_outlined,
|
|
||||||
size: 15,
|
|
||||||
),
|
|
||||||
'label': '热门',
|
|
||||||
'type': 'hot'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'icon': const Icon(
|
|
||||||
Icons.play_circle_outlined,
|
|
||||||
size: 15,
|
|
||||||
),
|
|
||||||
'label': '番剧',
|
|
||||||
'type': 'bangumi'
|
|
||||||
},
|
|
||||||
];
|
|
||||||
int initialIndex = 1;
|
int initialIndex = 1;
|
||||||
late TabController tabController;
|
late TabController tabController;
|
||||||
List ctrList = [
|
late List tabsCtrList;
|
||||||
Get.find<LiveController>,
|
late List<Widget> tabsPageList;
|
||||||
Get.find<RcmdController>,
|
|
||||||
Get.find<HotController>,
|
|
||||||
Get.find<BangumiController>,
|
|
||||||
];
|
|
||||||
RxString defaultSearch = '输入关键词搜索'.obs;
|
RxString defaultSearch = '输入关键词搜索'.obs;
|
||||||
Box user = GStrorage.user;
|
Box user = GStrorage.user;
|
||||||
RxBool userLogin = false.obs;
|
RxBool userLogin = false.obs;
|
||||||
@ -60,25 +20,32 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|
||||||
|
searchDefault();
|
||||||
|
userLogin.value = user.get(UserBoxKey.userLogin) ?? false;
|
||||||
|
userFace.value = user.get(UserBoxKey.userFace) ?? '';
|
||||||
|
|
||||||
|
// 进行tabs配置
|
||||||
|
tabs = tabsConfig;
|
||||||
|
tabsCtrList = tabsConfig.map((e) => e['ctr']).toList();
|
||||||
|
tabsPageList = tabsConfig.map<Widget>((e) => e['page']).toList();
|
||||||
|
|
||||||
tabController = TabController(
|
tabController = TabController(
|
||||||
initialIndex: initialIndex,
|
initialIndex: initialIndex,
|
||||||
length: tabs.length,
|
length: tabs.length,
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
searchDefault();
|
|
||||||
userLogin.value = user.get(UserBoxKey.userLogin) ?? false;
|
|
||||||
userFace.value = user.get(UserBoxKey.userFace) ?? '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRefresh() {
|
void onRefresh() {
|
||||||
int index = tabController.index;
|
int index = tabController.index;
|
||||||
var ctr = ctrList[index];
|
var ctr = tabsCtrList[index];
|
||||||
ctr().onRefresh();
|
ctr().onRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void animateToTop() {
|
void animateToTop() {
|
||||||
int index = tabController.index;
|
int index = tabController.index;
|
||||||
var ctr = ctrList[index];
|
var ctr = tabsCtrList[index];
|
||||||
ctr().animateToTop();
|
ctr().animateToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class _HomePageState extends State<HomePage>
|
|||||||
onTap: (value) {
|
onTap: (value) {
|
||||||
feedBack();
|
feedBack();
|
||||||
if (_homeController.initialIndex == value) {
|
if (_homeController.initialIndex == value) {
|
||||||
_homeController.ctrList[value]().animateToTop();
|
_homeController.tabsCtrList[value]().animateToTop();
|
||||||
}
|
}
|
||||||
_homeController.initialIndex = value;
|
_homeController.initialIndex = value;
|
||||||
},
|
},
|
||||||
@ -134,12 +134,7 @@ class _HomePageState extends State<HomePage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TabBarView(
|
child: TabBarView(
|
||||||
controller: _homeController.tabController,
|
controller: _homeController.tabController,
|
||||||
children: const [
|
children: _homeController.tabsPageList,
|
||||||
LivePage(),
|
|
||||||
RcmdPage(),
|
|
||||||
HotPage(),
|
|
||||||
BangumiPage(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -179,25 +174,15 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
height: snapshot.data ? 94 : MediaQuery.of(context).padding.top,
|
height: snapshot.data ? 96 : MediaQuery.of(context).padding.top,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 12,
|
left: 14,
|
||||||
right: 12,
|
right: 12,
|
||||||
bottom: 4,
|
bottom: 4,
|
||||||
top: MediaQuery.of(context).padding.top,
|
top: MediaQuery.of(context).padding.top,
|
||||||
),
|
),
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
const Text(
|
|
||||||
'PLPL',
|
|
||||||
style: TextStyle(
|
|
||||||
height: 2.8,
|
|
||||||
fontSize: 17,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontFamily: 'Jura-Bold',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -206,7 +191,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 250,
|
width: 250,
|
||||||
height: 42,
|
height: 44,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
padding: const EdgeInsets.only(left: 12, right: 22),
|
padding: const EdgeInsets.only(left: 12, right: 22),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -241,33 +226,20 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
// SizedBox(
|
|
||||||
// width: 36,
|
|
||||||
// height: 36,
|
|
||||||
// child: IconButton(
|
|
||||||
// style: ButtonStyle(
|
|
||||||
// padding: MaterialStateProperty.all(EdgeInsets.zero),
|
|
||||||
// ),
|
|
||||||
// onPressed: () {},
|
|
||||||
// icon: const Icon(Icons.notifications_none_outlined,
|
|
||||||
// size: 22),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(width: 8),
|
|
||||||
Obx(
|
Obx(
|
||||||
() => ctr!.userLogin.value
|
() => ctr!.userLogin.value
|
||||||
? GestureDetector(
|
? GestureDetector(
|
||||||
onTap: () => callback!(),
|
onTap: () => callback!(),
|
||||||
child: NetworkImgLayer(
|
child: NetworkImgLayer(
|
||||||
type: 'avatar',
|
type: 'avatar',
|
||||||
width: 34,
|
width: 38,
|
||||||
height: 34,
|
height: 38,
|
||||||
src: ctr!.userFace.value,
|
src: ctr!.userFace.value,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: SizedBox(
|
: SizedBox(
|
||||||
width: 36,
|
width: 38,
|
||||||
height: 36,
|
height: 38,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding:
|
padding:
|
||||||
|
@ -142,7 +142,8 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
|
|||||||
currentIndex: selectedIndex,
|
currentIndex: selectedIndex,
|
||||||
// type: BottomNavigationBarType.shifting,
|
// type: BottomNavigationBarType.shifting,
|
||||||
selectedItemColor: Theme.of(context).colorScheme.primary,
|
selectedItemColor: Theme.of(context).colorScheme.primary,
|
||||||
unselectedItemColor: Theme.of(context).colorScheme.outline,
|
unselectedItemColor:
|
||||||
|
Theme.of(context).colorScheme.outline.withOpacity(0.5),
|
||||||
selectedFontSize: 12.4,
|
selectedFontSize: 12.4,
|
||||||
onTap: (value) => setIndex(value),
|
onTap: (value) => setIndex(value),
|
||||||
items: [
|
items: [
|
||||||
|
@ -23,7 +23,16 @@ class MinePage extends StatelessWidget {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
toolbarHeight: kTextTabBarHeight + 20,
|
toolbarHeight: kTextTabBarHeight + 20,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
title: null,
|
centerTitle: false,
|
||||||
|
title: const Text(
|
||||||
|
'PLPL',
|
||||||
|
style: TextStyle(
|
||||||
|
height: 2.8,
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Jura-Bold',
|
||||||
|
),
|
||||||
|
),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => mineController.onChangeTheme(),
|
onPressed: () => mineController.onChangeTheme(),
|
||||||
|
Reference in New Issue
Block a user