You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter双击视频流切换方向后,AppBar与底部导航栏无法隐藏求助

解决Flutter双击切换屏幕方向时AppBar和底部导航栏无法隐藏的问题

问题根源

核心问题是状态管理范围不匹配:你使用的全局变量isPortrait,其对应的setState调用仅触发了直播流页面(SettingsCameraUser)的重建,但包含Scaffold的主页面无法感知到全局变量的变化,因此AppBar和bottomNavigationBar的显示状态无法同步更新。

解决方案

将状态提升到包含MaterialApp和Scaffold的主页面,通过回调函数让子页面触发主页面的状态更新,从而重建Scaffold来控制导航栏的显示。同时补充系统UI的隐藏逻辑,优化横屏体验。

1. 修改主页面(包含Scaffold的Widget)

class MainApp extends StatefulWidget {
  @override
  _MainAppState createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  // 将状态移至主页面State中,废弃全局变量
  bool isPortrait = true;

  // 定义切换方向的统一逻辑
  void toggleOrientation() {
    setState(() {
      isPortrait = !isPortrait;
    });

    // 设置屏幕方向
    if (isPortrait) {
      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
      // 竖屏恢复系统UI显示
      SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
    } else {
      SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
      // 横屏隐藏状态栏和导航栏
      SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 4,
        child: Scaffold(
          appBar: isPortrait
              ? PreferredSize(
                  preferredSize: Size.fromHeight(120),
                  child: AppBarService(),
                )
              : null,
          bottomNavigationBar: isPortrait ? menu() : null,
          body: TabBarView(
            physics: NeverScrollableScrollPhysics(),
            children: [
              MainPage(),
              HistoryPage(),
              DataBaseUser(),
              // 将切换逻辑回调传给直播流页面
              SettingsCameraUser(onToggleOrientation: toggleOrientation),
            ],
          ),
        ),
      ),
    );
  }
}

2. 修改直播流页面(SettingsCameraUser)

// 接收主页面传来的回调参数
class SettingsCameraUser extends StatelessWidget {
  final VoidCallback onToggleOrientation;

  const SettingsCameraUser({Key? key, required this.onToggleOrientation}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned(
          child: GestureDetector(
            onDoubleTap: () {
              // 直接调用主页面的切换逻辑,无需自行处理状态和方向
              onToggleOrientation();
            },
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              child: InAppWebView(
                onReceivedServerTrustAuthRequest: (controller, challenge) async {
                  return ServerTrustAuthResponse(
                      action: ServerTrustAuthResponseAction.PROCEED);
                },
                initialUrlRequest: URLRequest(
                    url: Uri.parse('https://1stream/home/stream')),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

补充说明

  • 移除原全局isPortrait变量,避免多页面状态冲突。
  • 横屏时使用SystemUiMode.immersiveSticky可让状态栏和导航栏自动隐藏,退出横屏时自动恢复,提升全屏观看体验。
  • 若项目复杂度较高,也可使用Provider、Riverpod等状态管理库实现更灵活的跨页面状态共享。

内容的提问来源于stack exchange,提问作者user16357470

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:40:13