1
This commit is contained in:
@@ -32,30 +32,46 @@ class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
// 登记当前策略,HomeShell 切回首页时只恢复这个策略的播放器池
|
||||
ref.read(activeFeedStrategyProvider.notifier).state = _strategy;
|
||||
// 监听计费/UI 事件(弹窗与 Toast 由 Notifier 事件流驱动)
|
||||
_eventSub = ref
|
||||
.read(feedProvider(_strategy).notifier)
|
||||
.events
|
||||
.listen(_handleEvent);
|
||||
// 从登录页等返回时恢复播放:provider 全局常驻保留了列表,
|
||||
// 但槽位已在 dispose 时 stopAll,需重新绑定(冷启动列表为空时为 no-op)
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) ref.read(feedProvider(_strategy).notifier).rebindCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_eventSub?.cancel();
|
||||
// 离开 Feed 路由(如跳登录页):彻底停止播放(断音+断缓存下载)。
|
||||
// feedProvider 是全局常驻,不处理则播放器池在后台继续出声
|
||||
ref.read(feedProvider(_strategy).notifier).pool.stopAll();
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// App 退后台暂停、回前台恢复播放
|
||||
/// App 退后台挂起、回前台恢复播放(suspend/resume 防在途 open 竞态)
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
final notifier = ref.read(feedProvider(_strategy).notifier);
|
||||
if (state == AppLifecycleState.paused ||
|
||||
state == AppLifecycleState.inactive) {
|
||||
notifier.pool.pauseCurrent();
|
||||
notifier.pool.suspend();
|
||||
} else if (state == AppLifecycleState.resumed) {
|
||||
notifier.pool.playCurrent();
|
||||
// 仅在首页 Tab 可见时恢复(在"我的"等页面回前台不播)
|
||||
if (ref.read(feedTabVisibleProvider)) {
|
||||
unawaited(() async {
|
||||
await notifier.pool.resume();
|
||||
await notifier.rebindCurrent();
|
||||
}());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,15 +89,23 @@ class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
|
||||
void _switchStrategy(FeedStrategy next) {
|
||||
if (next == _strategy) return;
|
||||
// 暂停旧策略播放,切换后新策略独立维护状态与播放器池
|
||||
ref.read(feedProvider(_strategy).notifier).pool.pauseCurrent();
|
||||
// 挂起旧策略池(防在途 open 完成后自动出声)
|
||||
ref.read(feedProvider(_strategy).notifier).pool.suspend();
|
||||
setState(() => _strategy = next);
|
||||
ref.read(activeFeedStrategyProvider.notifier).state = next;
|
||||
_eventSub?.cancel();
|
||||
_eventSub = ref
|
||||
.read(feedProvider(_strategy).notifier)
|
||||
.events
|
||||
.listen(_handleEvent);
|
||||
_pageController.jumpToPage(0);
|
||||
// jumpToPage 触发新策略 bindWindow 后再 resume:等其在途 open 完成再播放,
|
||||
// 同时解除新策略池可能残留的挂起态
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
unawaited(ref.read(feedProvider(_strategy).notifier).pool.resume());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// 打开评论弹层:打开期间暂停当前播放,关闭后恢复
|
||||
@@ -142,6 +166,7 @@ class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
onLike: notifier.toggleLike,
|
||||
onFavorite: notifier.toggleFavorite,
|
||||
onComment: _openComments,
|
||||
onReturnFromPlayer: notifier.rebindCurrent,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user