Files
slogan/app/lib/features/home/home_page.dart
T
admin b53c57e02d Add 'app/' from commit 'a11a66886941bba128d89c1124115e1b1c87a128'
git-subtree-dir: app
git-subtree-mainline: 6ebd902c6b
git-subtree-split: a11a668869
2026-08-04 14:59:55 +08:00

138 lines
3.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/ads/ads_service.dart';
import '../mine/mine_page.dart';
import '../outfit/outfit_page.dart';
/// 主框架:2 Tab(穿搭 = 造型方案制作向导 / 我的 = 个人信息管理入口)
class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key});
@override
ConsumerState<HomePage> createState() => _HomePageState();
}
class _HomePageState extends ConsumerState<HomePage> {
int _index = 0;
bool _splashShown = false;
@override
void initState() {
super.initState();
// 开屏广告:仅广告开通时展示一次(P0 Mock 下 pangleAppId 为空 → 跳过)
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_splashShown) return;
if (!ref.read(adsServiceProvider).enabled) return;
_splashShown = true;
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (_) => _SplashAdOverlay(
onSkip: () => Navigator.of(context).pop(),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _index,
children: const [
OutfitPage(),
MinePage(),
],
),
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (i) => setState(() => _index = i),
destinations: const [
NavigationDestination(
icon: Icon(Icons.auto_awesome_outlined),
selectedIcon: Icon(Icons.auto_awesome),
label: '穿搭'),
NavigationDestination(
icon: Icon(Icons.person_outline),
selectedIcon: Icon(Icons.person),
label: '我的'),
],
),
);
}
}
/// 开屏广告:3 秒倒计时后自动关闭,右上角可手动跳过
class _SplashAdOverlay extends StatefulWidget {
final VoidCallback onSkip;
const _SplashAdOverlay({required this.onSkip});
@override
State<_SplashAdOverlay> createState() => _SplashAdOverlayState();
}
class _SplashAdOverlayState extends State<_SplashAdOverlay> {
Timer? _timer;
int _seconds = 3;
@override
void initState() {
super.initState();
_timer = Timer.periodic(const Duration(seconds: 1), (_) {
if (_seconds <= 1) {
_timer?.cancel();
if (mounted) widget.onSkip();
return;
}
setState(() => _seconds -= 1);
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
child: ColoredBox(
color: Theme.of(context).colorScheme.primaryContainer,
child: Stack(
children: [
const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.campaign_outlined, size: 64),
SizedBox(height: 12),
Text('开屏广告位',
style:
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text('P1 接入穿山甲开屏广告',
style: TextStyle(fontSize: 12, color: Colors.grey)),
],
),
),
Positioned(
top: 24,
right: 24,
child: OutlinedButton(
onPressed: widget.onSkip,
child: Text('跳过($_seconds'),
),
),
],
),
),
);
}
}