初始化
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/assets_tool/images.dart';
|
||||
import 'package:hgdj/hj_page/main_page/provider/bottom_bar_provider.dart';
|
||||
import 'package:hgdj/hj_page/pre_sale/pre_sale_provider.dart';
|
||||
import 'package:hgdj/hj_utils/screen.dart';
|
||||
import 'package:hgdj/tools_base/widget/net_image_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../config/config.dart';
|
||||
import '../../../tools_base/event_bus/event_bus_util.dart';
|
||||
import '../../../tools_base/event_bus/events.dart';
|
||||
import '../home/provider/home_update_marker_provider.dart';
|
||||
import '../mine/home_mine_logic.dart';
|
||||
import 'main_logic.dart';
|
||||
|
||||
/// 底部导航栏:按 logic.tabs 渲染各 tab,选中态随 logic.curPageIndex 刷新
|
||||
class MainPageTabbar extends StatelessWidget {
|
||||
const MainPageTabbar({super.key});
|
||||
|
||||
MainPageLogic get logic => Get.find<MainPageLogic>();
|
||||
|
||||
void _selectIndex(int index) {
|
||||
final switchingToHome = index == 0 && logic.curPageIndex.value != 0;
|
||||
logic.jumpToPage(index);
|
||||
eventBus.emit(TabIndexChanged(index: index));
|
||||
//首页
|
||||
if (index == 0) {
|
||||
PreSaleProvider().refreshConfig(); //刷新预售权益
|
||||
// 从其它底栏切回主页时重拉「最新」等更新标记,避免长时间停留 App 内感知不到红点
|
||||
if (switchingToHome) {
|
||||
HomeUpdateMarkerProvider().loadData();
|
||||
}
|
||||
}
|
||||
// 短视频播/停不用在这里管:切走后 IndexedStack 不再 paint 该页,其 RepaintBoundary 图层
|
||||
// 从图层树摘除,VisibilityDetector 收到 detach 回调报可见度 0,播放器自行暂停。
|
||||
// 动短视频页的 RepaintBoundary 前,务必回归「切到别的 tab 还有没有声音」
|
||||
//我的:切到该 tab 时整体刷新(用户信息/钱包/消息/预售/分层配置)
|
||||
if (index == logic.tabs.length - 1 && Get.isRegistered<MineMainLogic>()) {
|
||||
Get.find<MineMainLogic>().onRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//选中态与内容页同源 curPageIndex:底栏点击、deeplink 外部跳转都只改它一处
|
||||
return Obx(() {
|
||||
final cur = logic.curPageIndex.value;
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(12, 0, 12, screen.paddingBottom),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black,
|
||||
border: Border(
|
||||
top: BorderSide(color: Colors.black.withValues(alpha: 0.02))),
|
||||
),
|
||||
child: Row(
|
||||
children: List.generate(logic.tabs.length, (index) {
|
||||
if (index == 0)
|
||||
return _scrollTopItem<HomeBottomProvider>(index, cur);
|
||||
if (Config.darkWebEnable && index == 2)
|
||||
return _scrollTopItem<DarkwebBottomProvider>(index, cur);
|
||||
if (index == logic.communityTab)
|
||||
return _scrollTopItem<CommunityBottomProvider>(index, cur);
|
||||
return _normalItem(index, cur);
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// 选中后再点会变「回到顶部」的 tab(主页/暗网/社区)
|
||||
Widget _scrollTopItem<T extends BaseBottomProvider>(int index, int cur) {
|
||||
final isSelected = index == cur;
|
||||
return Consumer<T>(builder: (_, provider, __) {
|
||||
final isTop = provider.showTop && isSelected;
|
||||
final imagePath =
|
||||
isTop ? 'jump_to_top.png'.homePath : _iconPath(index, isSelected);
|
||||
//暗网配置Icon
|
||||
final isDarkConfigImg = index == 2 &&
|
||||
isSelected &&
|
||||
Config.darkWebEnable &&
|
||||
Config.darkWebIcon?.isNotEmpty == true;
|
||||
return Expanded(
|
||||
child: InkWell(
|
||||
enableFeedback: false,
|
||||
onTap: () => isTop ? provider.scrollToTop() : _selectIndex(index),
|
||||
child: _tabContent(
|
||||
isSelected: isSelected,
|
||||
text: isTop ? '顶部' : logic.tabs[index].title,
|
||||
icon: isDarkConfigImg
|
||||
? NetworkImageLoader(
|
||||
key: const ValueKey('darkIcon'),
|
||||
imageUrl: Config.darkWebIcon)
|
||||
: Image.asset(imagePath, key: ValueKey(imagePath), width: 24),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// 普通 tab
|
||||
Widget _normalItem(int index, int cur) {
|
||||
final isSelected = index == cur;
|
||||
final imagePath = _iconPath(index, isSelected);
|
||||
return Expanded(
|
||||
child: InkWell(
|
||||
enableFeedback: false,
|
||||
onTap: () => _selectIndex(index),
|
||||
child: _tabContent(
|
||||
isSelected: isSelected,
|
||||
text: logic.tabs[index].title,
|
||||
icon: Image.asset(imagePath, key: ValueKey(imagePath), width: 24),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _iconPath(int index, bool isSelected) =>
|
||||
isSelected ? logic.tabs[index].imageSel : logic.tabs[index].imageNor;
|
||||
|
||||
/// 图标 + 文案:图标切换(key 变即图片路径变)交叉淡入,文字颜色平滑过渡
|
||||
Widget _tabContent(
|
||||
{required Widget icon, required bool isSelected, required String text}) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
height: 24,
|
||||
alignment: Alignment.center,
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 180), child: icon),
|
||||
),
|
||||
2.sizeBoxH,
|
||||
AnimatedDefaultTextStyle(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
style: TextStyle(
|
||||
color: isSelected
|
||||
? const Color(0xffF68804)
|
||||
: const Color(0xff656565),
|
||||
fontSize: 10,
|
||||
),
|
||||
child: Text(text),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user