调换tab顺序
This commit is contained in:
@@ -44,12 +44,16 @@ class HomeMainLogic extends GetxController {
|
|||||||
|
|
||||||
int get selectedTabIndex => tabCtr?.index ?? _initIndex;
|
int get selectedTabIndex => tabCtr?.index ?? _initIndex;
|
||||||
|
|
||||||
|
/// 主页固定注入的「热门短剧」tab(从短剧频道挪过来),不走后端模块
|
||||||
|
static const hotDramaTabId = '-120';
|
||||||
|
|
||||||
//服务端下发的原始顺序(抽屉「恢复默认」用)
|
//服务端下发的原始顺序(抽屉「恢复默认」用)
|
||||||
List<ModuleData> get defaultList {
|
List<ModuleData> get defaultList {
|
||||||
if (isDarkStyle) return Config.plateModule?.deepWeb ?? [];
|
if (isDarkStyle) return Config.plateModule?.deepWeb ?? [];
|
||||||
// 固定最新模块
|
// 固定最新 + 热门短剧模块,热门短剧排第二个
|
||||||
return [
|
return [
|
||||||
ModuleData(id: "-110", moduleName: "最新", type: 1, showType: 1),
|
ModuleData(id: "-110", moduleName: "最新", type: 1, showType: 1),
|
||||||
|
ModuleData(id: hotDramaTabId, moduleName: "热门短剧"),
|
||||||
...?Config.plateModule?.homePage,
|
...?Config.plateModule?.homePage,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -74,6 +78,7 @@ class HomeMainLogic extends GetxController {
|
|||||||
/// 应用抽屉里的新排序:顺序没变只切 tab,变了就落盘并换 key 重建 TabView
|
/// 应用抽屉里的新排序:顺序没变只切 tab,变了就落盘并换 key 重建 TabView
|
||||||
Future<void> resortTabs(List<ModuleData> dataArr, ModuleData? tagData) async {
|
Future<void> resortTabs(List<ModuleData> dataArr, ModuleData? tagData) async {
|
||||||
final curTagData = tagData ?? tabs[selectedTabIndex];
|
final curTagData = tagData ?? tabs[selectedTabIndex];
|
||||||
|
dataArr = _pinHotDrama(dataArr);
|
||||||
bool isSameArr = true;
|
bool isSameArr = true;
|
||||||
int selectIndex = 0;
|
int selectIndex = 0;
|
||||||
//抽屉只重排不增删,长度必然一致;逐项比名字,顺带定位选中项的新位置
|
//抽屉只重排不增删,长度必然一致;逐项比名字,顺带定位选中项的新位置
|
||||||
@@ -102,13 +107,15 @@ class HomeMainLogic extends GetxController {
|
|||||||
serverTabs: defaultList,
|
serverTabs: defaultList,
|
||||||
key: _sortKey,
|
key: _sortKey,
|
||||||
);
|
);
|
||||||
|
if (!isDarkStyle) tabs = _pinHotDrama(tabs);
|
||||||
if (darkDefaultId?.isNotEmpty == true) {
|
if (darkDefaultId?.isNotEmpty == true) {
|
||||||
// 初始化指定模块(一般暗网模块用)
|
// 初始化指定模块(一般暗网模块用)
|
||||||
final index = tabs.indexWhere((e) => e.id == darkDefaultId);
|
final index = tabs.indexWhere((e) => e.id == darkDefaultId);
|
||||||
if (index >= 0) _initIndex = index;
|
if (index >= 0) _initIndex = index;
|
||||||
} else if (!isDarkStyle) {
|
} else if (!isDarkStyle) {
|
||||||
//默认不显示最新模块,选中「热门」(index 1);但 tab 不足 2 个时回退到 0,避免越界
|
//默认选中「热门短剧」
|
||||||
_initIndex = (tabs.first.moduleName == "最新" && tabs.length > 1) ? 1 : 0;
|
final index = tabs.indexWhere((e) => e.id == hotDramaTabId);
|
||||||
|
_initIndex = index >= 0 ? index : 0;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugLog(e);
|
debugLog(e);
|
||||||
@@ -117,6 +124,15 @@ class HomeMainLogic extends GetxController {
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 「热门短剧」固定排第二个:本地排序里新 tab 会被追加到末尾,抽屉里也可能被拖走,这里统一挪回来
|
||||||
|
List<ModuleData> _pinHotDrama(List<ModuleData> list) {
|
||||||
|
final index = list.indexWhere((e) => e.id == hotDramaTabId);
|
||||||
|
if (index < 0 || index == 1 || list.length < 2) return list;
|
||||||
|
final result = [...list];
|
||||||
|
result.insert(1, result.removeAt(index));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// 首页弹窗链:预售 → 支付分层 → VIP 引导。
|
/// 首页弹窗链:预售 → 支付分层 → VIP 引导。
|
||||||
/// 逐个 await 串行弹,每次启动只跑一次。
|
/// 逐个 await 串行弹,每次启动只跑一次。
|
||||||
/// 广告类弹窗(九宫格/图片公告/文字公告)不在这里:它们跟着启动落地页弹,见 MainPageLogic.onReady
|
/// 广告类弹窗(九宫格/图片公告/文字公告)不在这里:它们跟着启动落地页弹,见 MainPageLogic.onReady
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:tgdj/tools_base/widget/keep_alive_widget.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../cartoon/cartoon_sub_detail_page.dart';
|
import '../cartoon/cartoon_sub_detail_page.dart';
|
||||||
|
import '../drama/drama_list_page.dart';
|
||||||
import '../main_page/provider/bottom_bar_provider.dart';
|
import '../main_page/provider/bottom_bar_provider.dart';
|
||||||
import 'activity_float/home_float_widget.dart';
|
import 'activity_float/home_float_widget.dart';
|
||||||
import 'home_drawer.dart';
|
import 'home_drawer.dart';
|
||||||
@@ -203,6 +204,9 @@ class _HomeTabViewState extends State<HomeTabView>
|
|||||||
/// 按 module type/showType/isACG 分发到对应子页,统一 keepAlive
|
/// 按 module type/showType/isACG 分发到对应子页,统一 keepAlive
|
||||||
Widget _tabPage(int index) {
|
Widget _tabPage(int index) {
|
||||||
final module = logic.tabs[index];
|
final module = logic.tabs[index];
|
||||||
|
if (module.id == HomeMainLogic.hotDramaTabId) {
|
||||||
|
return const DramaListPage().keepAlive;
|
||||||
|
}
|
||||||
if (module.type == 1 || module.type == 3) {
|
if (module.type == 1 || module.type == 3) {
|
||||||
//showType==2 走分区聚合页,其余走排序列表页
|
//showType==2 走分区聚合页,其余走排序列表页
|
||||||
return module.showType == 2
|
return module.showType == 2
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
//短剧频道的二级 tab:写死这 4 个,顺序与 ShortVideoMainPage 的 TabBarView children 一一对应
|
//短剧频道的二级 tab:写死这 3 个,顺序与 ShortVideoMainPage 的 TabBarView children 一一对应
|
||||||
const kDramaTabs = ["直播", "抖音", "AI短剧", "热门短剧"];
|
const kDramaTabs = ["直播", "抖音", "AI短剧"]; //热门短剧已挪到主页 tab
|
||||||
|
|
||||||
//默认打开 AI短剧
|
//默认打开 AI短剧
|
||||||
const kDramaDefaultTab = 2;
|
const kDramaDefaultTab = 2;
|
||||||
const kDramaHotTab = 3;
|
|
||||||
|
|
||||||
/// 短剧频道的 tab 调度。被 MainPageLogic.skipToLive 和 ShortTopMenu 按类型 Get.find,
|
/// 短剧频道的 tab 调度。被 MainPageLogic.skipToLive 和 ShortTopMenu 按类型 Get.find,
|
||||||
/// 所以必须保持全局注册、不能加 tag
|
/// 所以必须保持全局注册、不能加 tag
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ import 'package:tgdj/hj_page/short_video/view/short_top_menu.dart';
|
|||||||
import 'package:tgdj/tools_base/widget/keep_alive_widget.dart';
|
import 'package:tgdj/tools_base/widget/keep_alive_widget.dart';
|
||||||
|
|
||||||
import '../drama/drama_feed_page.dart';
|
import '../drama/drama_feed_page.dart';
|
||||||
import '../drama/drama_list_page.dart';
|
|
||||||
import '../live/live_main_page.dart';
|
import '../live/live_main_page.dart';
|
||||||
|
|
||||||
/// 短剧频道:直播 / 抖音 / AI短剧 / 热门短剧
|
/// 短剧频道:直播 / 抖音 / AI短剧
|
||||||
class ShortVideoMainPage extends StatelessWidget {
|
class ShortVideoMainPage extends StatelessWidget {
|
||||||
/// 指定初始 tab;<0(默认) 表示用 [kDramaDefaultTab]
|
/// 指定初始 tab;<0(默认) 表示用 [kDramaDefaultTab]
|
||||||
final int index;
|
final int index;
|
||||||
@@ -30,9 +29,7 @@ class ShortVideoMainPage extends StatelessWidget {
|
|||||||
() => logic.tabIndex.value == 0
|
() => logic.tabIndex.value == 0
|
||||||
? Image.asset('live_main_bg2.webp'.livePath,
|
? Image.asset('live_main_bg2.webp'.livePath,
|
||||||
alignment: Alignment.topCenter, fit: BoxFit.cover)
|
alignment: Alignment.topCenter, fit: BoxFit.cover)
|
||||||
: logic.tabIndex.value == kDramaHotTab
|
: const SizedBox.shrink(),
|
||||||
? const ColoredBox(color: Color(0xFF05000E))
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SafeArea(
|
SafeArea(
|
||||||
@@ -44,7 +41,7 @@ class ShortVideoMainPage extends StatelessWidget {
|
|||||||
child: TabBarView(
|
child: TabBarView(
|
||||||
controller: logic.tabCtr,
|
controller: logic.tabCtr,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
//顺序必须与 kDramaTabs 一致。直播/热门短剧是普通页面,要给顶部菜单让位;两个信息流页自己铺满
|
//顺序必须与 kDramaTabs 一致。直播是普通页面,要给顶部菜单让位;两个信息流页自己铺满
|
||||||
children: [
|
children: [
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.only(top: 44),
|
padding: EdgeInsets.only(top: 44),
|
||||||
@@ -56,10 +53,6 @@ class ShortVideoMainPage extends StatelessWidget {
|
|||||||
.keepAlive,
|
.keepAlive,
|
||||||
DramaFeedPage(tabIndex: 2, superTabCtr: logic.tabCtr)
|
DramaFeedPage(tabIndex: 2, superTabCtr: logic.tabCtr)
|
||||||
.keepAlive,
|
.keepAlive,
|
||||||
const Padding(
|
|
||||||
padding: EdgeInsets.only(top: 44),
|
|
||||||
child: DramaListPage())
|
|
||||||
.keepAlive,
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class ShortTopMenu extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// 选中态、下划线位移全交给 TabBar 自己按 tabCtr 动画,不用 Obx 整条重建
|
// 选中态、下划线位移全交给 TabBar 自己按 tabCtr 动画,不用 Obx 整条重建
|
||||||
//高度 48 与 ShortVideoMainPage 里两个普通 tab 的 Padding(top: 44) 对应,改一处要同步
|
//高度 48 与 ShortVideoMainPage 里直播 tab 的 Padding(top: 44) 对应,改一处要同步
|
||||||
return Container(
|
return Container(
|
||||||
height: 48,
|
height: 48,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
@@ -65,7 +65,7 @@ class ShortTopMenu extends StatelessWidget {
|
|||||||
/// 单个 tab:只画文字(直播原来是图标,改版后统一成文字)。
|
/// 单个 tab:只画文字(直播原来是图标,改版后统一成文字)。
|
||||||
/// 底部留 7 = 与文字间距 3 + 指示器高 4,腾给贴底绘制的 CustomIndicator
|
/// 底部留 7 = 与文字间距 3 + 指示器高 4,腾给贴底绘制的 CustomIndicator
|
||||||
Widget _menuItem(String title) => Container(
|
Widget _menuItem(String title) => Container(
|
||||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 7),
|
padding: const EdgeInsets.fromLTRB(20, 0, 20, 7),
|
||||||
child: Text(title),
|
child: Text(title),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user