首屏展示修改

This commit is contained in:
谢宇宁
2026-09-17 14:19:30 +07:00
parent 069658f4a3
commit 94a509ad93
4 changed files with 9 additions and 117 deletions
@@ -64,7 +64,11 @@ class _CommonSearchBarViewState extends State<CommonSearchBarView> {
borderRadius: BorderRadius.circular(99),
),
child: Config.searchHints.isEmpty
? Text('请输入关键字', style: _hintStyle)
//父级给的是 36 的紧约束,Text 会撑满高度后从顶部起排,要 Align 压回垂直居中
? Align(
alignment: Alignment.centerLeft,
child: Text('请输入关键字', style: _hintStyle),
)
: MarqueeWidget(
count: Config.searchHints.length,
onIndexChanged: (index) =>
@@ -1,95 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jyfans/assets_tool/images.dart';
import 'package:jyfans/config/config.dart';
import 'package:jyfans/hj_utils/light_model.dart';
import 'package:jyfans/hj_utils/store_keys.dart';
import 'main_logic.dart';
/// 「AI爽剧来袭」引导气泡:贴底栏上沿、尾巴指着短剧 tab,原地上下轻跳。
/// 亮出来就算数——装机维度只亮这一次(落 KV),不用等用户点;
/// 后台把 ping 的 entryPopupEnabled 置 false 可全局关掉
class DramaTipBubble extends StatefulWidget {
const DramaTipBubble({super.key});
/// 短剧在底栏的下标。暗网排在它后面,darkWebEnable 关不关都不影响
static const dramaTab = 1;
static final visible = ValueNotifier(false); // 气泡亮不亮
static bool _seen = false; //本次启动是否已进过短剧 tab
/// MainPage 创建时调一次;ping 关掉或以前亮过就不再亮
static Future<void> start() async {
if (!Config.entryPopupEnabled) return;
if (await lightKV.getBool(StoreKeys.DRAMA_TIP_SHOWN) ?? false) return;
if (_seen) return; //读盘这会儿已经进过短剧了(深链直达),这次不亮也不算数,下次冷启动照亮
visible.value = true;
lightKV.setBool(StoreKeys.DRAMA_TIP_SHOWN, true); //亮出来就记下,不等用户点
}
/// 进短剧 tab 就收起,只管本次启动;算不算数在 [start] 亮出来那一刻就定了。
/// 可能早于 [start] 的读盘,所以要留下 [_seen] 挡住它
static void hide() {
visible.value = false;
_seen = true;
}
@override
State<DramaTipBubble> createState() => _DramaTipBubbleState();
}
class _DramaTipBubbleState extends State<DramaTipBubble>
with SingleTickerProviderStateMixin {
//上下轻跳:0→1 映射成向上 0→4,来回循环
late final _ani = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
@override
void initState() {
super.initState();
if (DramaTipBubble.visible.value) _ani.repeat(reverse: true);
DramaTipBubble.visible.addListener(_onVisibleChanged);
}
@override
void dispose() {
DramaTipBubble.visible.removeListener(_onVisibleChanged);
_ani.dispose();
super.dispose();
}
//收起要停 ticker:repeat 的控制器不停会一直请求 vsync 帧
void _onVisibleChanged() {
DramaTipBubble.visible.value ? _ani.repeat(reverse: true) : _ani.stop();
if (mounted) setState(() {});
}
@override
Widget build(BuildContext context) {
if (!DramaTipBubble.visible.value) return const SizedBox.shrink();
final logic = Get.find<MainPageLogic>();
//底栏左右各 12 内边距,剩下的等分给各 tab;51.8 是尾巴尖在图里的横向位置
final tabWidth = (Get.width - 24) / logic.tabs.length;
final tailCenter = 12 + tabWidth * (DramaTipBubble.dramaTab + 0.5);
return Row(
children: [
SizedBox(width: tailCenter - 51.8),
InkWell(
enableFeedback: false,
onTap: () => logic.jumpToPage(DramaTipBubble.dramaTab),
child: AnimatedBuilder(
animation: _ani,
builder: (_, child) => Transform.translate(
offset: Offset(0, -4 * Curves.easeInOut.transform(_ani.value)),
child: child,
),
child:
Image.asset('drama_tip.webp'.homePath, width: 131, height: 35),
),
),
],
);
}
}
+3 -8
View File
@@ -24,7 +24,6 @@ import '../home/home_main_logic.dart';
import '../home/provider/home_update_marker_provider.dart';
import '../mine/mine_vip/vip_product_manager.dart';
import '../short_video/short_main_video_logic.dart';
import 'drama_tip_bubble.dart';
import 'main_page.dart';
import 'provider/msg_provider.dart';
@@ -65,7 +64,7 @@ class MainPageLogic extends GetxController {
imageSel: 'home_0_1.png'.homePath,
),
MainTabModel(
title: '短剧',
title: '抖音',
imageNor: 'home_1_0.png'.homePath,
imageSel: 'home_1_1.png'.homePath,
),
@@ -94,8 +93,8 @@ class MainPageLogic extends GetxController {
];
/// 当前底部 tab 下标:内容页(LazyIndexedStack)和底栏选中态的唯一真相源。
/// 启动固定落在短剧
final curPageIndex = DramaTipBubble.dramaTab.obs;
/// 启动固定落在主页
final curPageIndex = 0.obs;
final shortIndex = (-1).obs; // -1 = 用短剧频道的默认页(AI短剧)
final darkInitTabId = Rx<String?>(null); // 暗网默认亚模块 id
@@ -123,9 +122,6 @@ class MainPageLogic extends GetxController {
MineMsgProvider().loadData();
HomeUpdateMarkerProvider().loadData();
//启动就落在短剧:引导气泡不该再亮(这里早于 DramaTipBubble.start 的读盘)
if (curPageIndex.value == DramaTipBubble.dramaTab) DramaTipBubble.hide();
_yinseSub = eventBus.on<YinseinnerModel>(_onYinse);
_loginSub = eventBus.on<ReLoginEvent>(_onReLogin);
@@ -309,7 +305,6 @@ class MainPageLogic extends GetxController {
/// 切 tab:内容页和底栏选中态都监听 curPageIndex,改它一处即可
void jumpToPage(int index) {
curPageIndex.value = index;
if (index == DramaTipBubble.dramaTab) DramaTipBubble.hide(); //进了短剧就别再指着它
}
/// 双击返回退出:2 秒内连按两次返回键才真正退出
+1 -13
View File
@@ -13,7 +13,6 @@ import '../home/dark_home_page.dart';
import '../home/home_main_page.dart';
import '../home/widget/home_txt_marquee.dart';
import '../mine/home_mine_page.dart';
import 'drama_tip_bubble.dart';
import 'main_logic.dart';
import 'main_tabbar.dart';
@@ -35,7 +34,6 @@ class _MainPageState extends State<MainPage> with RouteAware {
void initState() {
super.initState();
GuidePushBanner.start(); //进 app 满3分钟后开始推 VIP「特享内容」横幅
DramaTipBubble.start(); //「AI爽剧来袭」引导气泡,装机维度只亮一次
}
@override
@@ -71,17 +69,7 @@ class _MainPageState extends State<MainPage> with RouteAware {
resizeToAvoidBottomInset: false,
body: Column(
children: [
Expanded(
child: Stack(
fit: StackFit.expand,
children: [
_buildPages(),
//引导气泡贴着底栏上沿,尾巴指短剧 tab
const Positioned(
left: 0, right: 0, bottom: 0, child: DramaTipBubble()),
],
),
),
Expanded(child: _buildPages()),
const MainPageTabbar(),
],
),