1
This commit is contained in:
@@ -4,9 +4,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../core/log/action_logger.dart';
|
||||
import '../../core/theme/app_theme.dart';
|
||||
import '../../models/video_item.dart';
|
||||
import '../../providers/feed_provider.dart';
|
||||
import '../../router.dart';
|
||||
import 'widgets/comment_sheet.dart';
|
||||
import 'widgets/feed_overlays.dart';
|
||||
import 'widgets/feed_video_page.dart';
|
||||
@@ -23,7 +25,7 @@ class FeedScreen extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
with WidgetsBindingObserver {
|
||||
with WidgetsBindingObserver, RouteAware {
|
||||
FeedStrategy _strategy = FeedStrategy.recommend;
|
||||
final PageController _pageController = PageController();
|
||||
StreamSubscription<FeedEvent>? _eventSub;
|
||||
@@ -46,9 +48,36 @@ class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
// 注册路由感知:当上层路由 pop 露出 FeedScreen 时(didPopNext),
|
||||
// 若首页 Tab 仍选中,恢复播放——这是处理「搜索页/分类页返回后无声」的唯一可靠入口
|
||||
final route = ModalRoute.of(context);
|
||||
if (route is PageRoute) {
|
||||
routeObserver.subscribe(this, route);
|
||||
}
|
||||
}
|
||||
|
||||
/// 上层路由 pop 后本路由重新可见:恢复播放
|
||||
@override
|
||||
void didPopNext() {
|
||||
if (!mounted) return;
|
||||
if (!ref.read(feedTabVisibleProvider)) return;
|
||||
ActionLogger.I.log('feed_did_pop_next', page: '/home', detail: {
|
||||
'strategy': _strategy.name,
|
||||
});
|
||||
final notifier = ref.read(feedProvider(_strategy).notifier);
|
||||
unawaited(() async {
|
||||
await notifier.pool.resume();
|
||||
await notifier.rebindCurrent();
|
||||
}());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
routeObserver.unsubscribe(this);
|
||||
_eventSub?.cancel();
|
||||
// 离开 Feed 路由(如跳登录页):彻底停止播放(断音+断缓存下载)。
|
||||
// feedProvider 是全局常驻,不处理则播放器池在后台继续出声
|
||||
@@ -101,7 +130,13 @@ class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
.read(feedProvider(_strategy).notifier)
|
||||
.events
|
||||
.listen(_handleEvent);
|
||||
_pageController.jumpToPage(0);
|
||||
// 保留每个策略的播放进度(currentIndex 由 provider 维护):切回时跳到上次位置而非归零
|
||||
final targetIndex = ref.read(feedProvider(_strategy)).currentIndex;
|
||||
if (_pageController.hasClients && targetIndex > 0) {
|
||||
_pageController.jumpToPage(targetIndex);
|
||||
} else if (_pageController.hasClients) {
|
||||
_pageController.jumpToPage(0);
|
||||
}
|
||||
// jumpToPage 后 resume + rebindCurrent:suspend 已 stop 槽位,仅 play
|
||||
// 播不起来,必须 rebind 重新 open(有断点记录则 seek 续播)
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -186,7 +221,9 @@ class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
child: Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
for (final s in FeedStrategy.values) ...[
|
||||
for (final s in FeedStrategy.values.where(
|
||||
(s) => s != FeedStrategy.search,
|
||||
)) ...[
|
||||
_StrategyTab(
|
||||
label: s.label,
|
||||
selected: s == _strategy,
|
||||
|
||||
Reference in New Issue
Block a user