From bc8f3bcab7bb87bf15be9c67f52bda479677b982 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Tue, 20 Oct 2026 14:27:36 +0800 Subject: [PATCH] =?UTF-8?q?fix(flutter):=20=E5=9B=9E=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=E5=A4=8D=E4=BD=8D=E6=AE=8B=E7=95=99=E7=94=BB=E4=B8=AD=E7=94=BB?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/player/player_logic.dart | 8 ++++++++ test/player/player_logic_test.dart | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/pages/player/player_logic.dart b/lib/pages/player/player_logic.dart index c9c94aa..5920184 100644 --- a/lib/pages/player/player_logic.dart +++ b/lib/pages/player/player_logic.dart @@ -313,6 +313,14 @@ class PlayerLogic extends ChangeNotifier { void onLifecycle(AppLifecycleState state) { if (state != AppLifecycleState.resumed) unawaited(saveCurrentProgress()); if (state == AppLifecycleState.resumed) { + // 部分机型退出画中画不会回调 onPipChanged(false):回前台先兜底复位, + // 否则 chromeHidden 恒为 true,播放浮层与首页底栏都会消失。 + if (pip || pipPreparing) { + pip = false; + pipPreparing = false; + notify(); + notifyImmersive(); + } // 签名地址有有效期:回前台时若票据已过期,重新取一张再起播, // 否则会撞上 403(契约 §1.4) final episode = trackedEpisode; diff --git a/test/player/player_logic_test.dart b/test/player/player_logic_test.dart index 44084d9..c0235c2 100644 --- a/test/player/player_logic_test.dart +++ b/test/player/player_logic_test.dart @@ -187,6 +187,34 @@ void main() { expect(logic.pip, isFalse); }); + + test('should_clear_stale_pip_when_app_returns_to_foreground', () async { + final factory = _RecordingFactory(); + final drama = _drama('signal'); + final logic = _logic(FakeWatchHistory()); + final immersive = []; + logic.attach( + PlayerPage(drama: drama, initialIndex: 0), + isMounted: () => true, + ); + logic.onImmersiveChanged = immersive.add; + logic.start(factory: factory.create, coordinator: PlaybackCoordinator()); + await _drain(logic); + + // 模拟画中画已进入但退出时没有回调 false。 + logic.onPipChanged(true); + expect(logic.chromeHidden, isTrue); + + logic.onLifecycle(AppLifecycleState.resumed); + + expect(logic.pip, isFalse); + expect(logic.pipPreparing, isFalse); + expect(logic.chromeHidden, isFalse); + expect(immersive.last, isFalse); + + logic.dispose(); + await _drain(logic); + }); }); group('history writes', () {