花生壳网站建设,金华金义东轨道建设网站,网站建设亻金手指排名十五,网站打包成app软件Flutter 全屏页面路由实现完全指南
在实际开发中#xff0c;我们经常需要某些页面#xff08;如视频播放器、游戏、图片查看器等#xff09;以全屏模式显示。本文将详细介绍在 Flutter 中实现全屏页面的各种方法、最佳实践和常见问题解决方案。
目录实现原理核心方法完…Flutter 全屏页面路由实现完全指南在实际开发中我们经常需要某些页面如视频播放器、游戏、图片查看器等以全屏模式显示。本文将详细介绍在 Flutter 中实现全屏页面的各种方法、最佳实践和常见问题解决方案。目录· 实现原理· 核心方法· 完整实现方案· 路由集成· 平台差异处理· 常见问题解决· 最佳实践实现原理Flutter 通过 SystemChrome 类来控制系统 UI 的显示和隐藏。全屏的本质是隐藏状态栏、导航栏等系统 UI 元素让应用内容占据整个屏幕。系统 UI 模式说明模式 描述 适用场景SystemUiMode.edgeToEdge 正常模式显示状态栏和导航栏 普通页面SystemUiMode.immersive 全屏模式需要手动退出 游戏、视频播放SystemUiMode.immersiveSticky 全屏模式可临时显示系统 UI 图片查看、阅读器核心方法基本全屏控制importpackage:flutter/services.dart;// 进入全屏SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);// 退出全屏SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);更彻底的全屏控制// 完全隐藏所有系统 UISystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:[],// 空数组表示隐藏所有覆盖层);// 恢复正常SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:SystemUiOverlay.values,// 显示所有覆盖层);完整实现方案方案一基于页面生命周期的实现importpackage:flutter/material.dart;importpackage:flutter/services.dart;importdart:io;classFullScreenPageextendsStatefulWidget{finalWidgetchild;finalbool enableFullScreen;constFullScreenPage({Key?key,requiredthis.child,this.enableFullScreentrue,}):super(key:key);override_FullScreenPageStatecreateState()_FullScreenPageState();}class_FullScreenPageStateextendsStateFullScreenPagewithWidgetsBindingObserver{overridevoidinitState(){super.initState();WidgetsBinding.instance.addObserver(this);if(widget.enableFullScreen){_enterFullScreen();}}Futurevoid_enterFullScreen()async{awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky,);// 可选锁定横屏// await SystemChrome.setPreferredOrientations([// DeviceOrientation.landscapeLeft,// DeviceOrientation.landscapeRight,// ]);}Futurevoid_exitFullScreen()async{awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge,);// 恢复屏幕方向// await SystemChrome.setPreferredOrientations([// DeviceOrientation.portraitUp,// DeviceOrientation.portraitDown,// DeviceOrientation.landscapeLeft,// DeviceOrientation.landscapeRight,// ]);}overridevoiddidChangeMetrics(){// 当系统 UI 状态变化时可以重新进入全屏if(widget.enableFullScreen){_enterFullScreen();}}overridevoiddispose(){WidgetsBinding.instance.removeObserver(this);_exitFullScreen();super.dispose();}overrideWidgetbuild(BuildContextcontext){returnwidget.child;}}方案二全屏管理器类// full_screen_manager.dartimportpackage:flutter/services.dart;importdart:io;classFullScreenManager{staticbool _isFullScreenfalse;/// 进入全屏模式staticFuturevoidenter()async{if(_isFullScreen)return;try{if(Platform.isAndroid){// Android: 使用 immersiveSticky 效果最好awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky,);}elseif(Platform.isIOS){// iOS: 使用 manual 模式控制更精细awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:[],);}_isFullScreentrue;print(进入全屏模式成功);}catch(e){print(进入全屏失败:$e);_isFullScreenfalse;}}/// 退出全屏模式staticFuturevoidexit()async{if(!_isFullScreen)return;try{// 恢复到正常模式awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge,);// 确保所有系统 UI 都显示awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:SystemUiOverlay.values,);_isFullScreenfalse;print(退出全屏模式成功);}catch(e){print(退出全屏失败:$e);}}/// 切换全屏状态staticFuturevoidtoggle()async{if(_isFullScreen){awaitexit();}else{awaitenter();}}/// 获取当前状态staticboolgetisFullScreen_isFullScreen;/// 临时显示系统 UI仅限 immersiveSticky 模式staticvoidshowSystemUI(){if(_isFullScreen){SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:SystemUiOverlay.values,);// 3秒后自动隐藏Future.delayed(Duration(seconds:3),(){if(_isFullScreen){SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:[],);}});}}}方案三全屏路由包装器// full_screen_route.dartimportpackage:flutter/material.dart;importfull_screen_manager.dart;/// 全屏路由包装器classFullScreenRouteTextendsMaterialPageRouteT{FullScreenRoute({requiredWidgetBuilderbuilder,RouteSettings?settings,bool maintainStatetrue,bool fullscreenDialogfalse,}):super(builder:builder,settings:settings,maintainState:maintainState,fullscreenDialog:fullscreenDialog,);overrideWidgetbuildPage(BuildContextcontext,Animationdoubleanimation,AnimationdoublesecondaryAnimation){// 在页面构建时进入全屏Future.microtask(()FullScreenManager.enter());returnFullScreenPage(enableFullScreen:true,child:builder(context),);}overridevoiddidComplete(T?result){// 路由完成时退出全屏FullScreenManager.exit();super.didComplete(result);}}路由集成基本路由跳转// 使用全屏路由跳转Navigator.push(context,FullScreenRoute(builder:(context)VideoPlayerScreen(videoUrl:videoUrl),),);// 或者使用命名路由MaterialApp(title:全屏示例,initialRoute:/,routes:{/:(context)HomeScreen(),/video:(context)FullScreenPage(enableFullScreen:true,child:VideoPlayerScreen(),),},);带参数的全屏路由classFullScreenVideoPageextendsStatelessWidget{finalStringvideoUrl;constFullScreenVideoPage({Key?key,requiredthis.videoUrl}):super(key:key);overrideWidgetbuild(BuildContextcontext){returnFullScreenPage(enableFullScreen:true,child:VideoPlayerScreen(videoUrl:videoUrl),);}}// 跳转Navigator.push(context,MaterialPageRoute(builder:(context)FullScreenVideoPage(videoUrl:https://example.com/video.mp4),),);平台差异处理Android 特殊处理// android_full_screen.dartimportpackage:flutter/services.dart;classAndroidFullScreen{/// Android 专属的全屏处理staticFuturevoidenterFullScreen()async{// 方法1推荐方式awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky,);// 方法2更彻底的全屏// await SystemChrome.setEnabledSystemUIMode(// SystemUiMode.immersive,// );// 处理返回按钮// SystemChrome.setPreferredOrientations([// DeviceOrientation.landscapeLeft,// DeviceOrientation.landscapeRight,// ]);}/// 处理 Android 物理返回键staticWidgetwrapWithBackHandler(Widgetchild,VoidCallbackonBack){returnWillPopScope(onWillPop:()async{onBack();returnfalse;// 阻止默认返回行为},child:child,);}}iOS 特殊处理// ios_full_screen.dartimportpackage:flutter/services.dart;classIOSFullScreen{/// iOS 专属的全屏处理staticFuturevoidenterFullScreen()async{// iOS 对全屏的支持略有不同awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays:[],// 隐藏所有覆盖层);// iOS 通常不需要处理横屏除非特别需求}/// 处理 iOS 状态栏样式staticvoidsetStatusBarStyle(Brightnessbrightness){SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarBrightness:brightness,statusBarIconBrightness:brightnessBrightness.dark?Brightness.light:Brightness.dark,),);}}常见问题解决问题1Android 手势导航冲突现象在 Android 10 使用手势导航时底部导航条可能偶尔出现。解决方案classFullScreenWithGestureHandlerextendsStatefulWidget{finalWidgetchild;constFullScreenWithGestureHandler({Key?key,requiredthis.child}):super(key:key);override_FullScreenWithGestureHandlerStatecreateState()_FullScreenWithGestureHandlerState();}class_FullScreenWithGestureHandlerStateextendsStateFullScreenWithGestureHandler{Timer?_hideTimer;overridevoidinitState(){super.initState();_enterFullScreen();}void_enterFullScreen()async{// 使用更彻底的全屏模式awaitSystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive,);}void_onUserInteraction(){// 用户交互时重新隐藏系统 UI_hideTimer?.cancel();_enterFullScreen();// 设置定时器定期检查并重新进入全屏_hideTimerTimer.periodic(Duration(seconds:1),(timer){_enterFullScreen();});}overrideWidgetbuild(BuildContextcontext){returnGestureDetector(onTap:_onUserInteraction,onPanDown:(_)_onUserInteraction(),behavior:HitTestBehavior.opaque,child:widget.child,);}overridevoiddispose(){_hideTimer?.cancel();SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);super.dispose();}}问题2页面切换动画冲突解决方案自定义页面过渡classFadeFullScreenRouteTextendsPageRouteBuilderT{finalWidgetpage;finalbool enableFullScreen;FadeFullScreenRoute({requiredthis.page,this.enableFullScreentrue,}):super(pageBuilder:(BuildContextcontext,Animationdoubleanimation,AnimationdoublesecondaryAnimation,){if(enableFullScreen){returnFullScreenPage(enableFullScreen:true,child:page,);}returnpage;},transitionsBuilder:(BuildContextcontext,Animationdoubleanimation,AnimationdoublesecondaryAnimation,Widgetchild,){returnFadeTransition(opacity:animation,child:child,);},transitionDuration:Duration(milliseconds:300),);}问题3多个全屏页面连续跳转classFullScreenStackManager{staticfinalListString_fullScreenPages[];staticvoidpush(StringpageName){_fullScreenPages.add(pageName);if(_fullScreenPages.length1){// 第一个全屏页面进入全屏FullScreenManager.enter();}}staticvoidpop(StringpageName){_fullScreenPages.remove(pageName);if(_fullScreenPages.isEmpty){// 最后一个全屏页面退出恢复普通模式FullScreenManager.exit();}}staticboolisFullScreenActive(){return_fullScreenPages.isNotEmpty;}}// 在页面中使用classFullScreenPageWrapperextendsStatefulWidget{finalStringpageName;finalWidgetchild;overridevoidinitState(){super.initState();FullScreenStackManager.push(pageName);}overridevoiddispose(){FullScreenStackManager.pop(pageName);super.dispose();}}最佳实践封装统一的全屏组件// responsive_full_screen.dartimportpackage:flutter/material.dart;importfull_screen_manager.dart;/// 响应式全屏组件根据平台自动适配classResponsiveFullScreenextendsStatefulWidget{finalWidgetchild;finalbool enableFullScreen;finalbool enableGestureControl;finalbool autoExitOnDispose;constResponsiveFullScreen({Key?key,requiredthis.child,this.enableFullScreentrue,this.enableGestureControltrue,this.autoExitOnDisposetrue,}):super(key:key);override_ResponsiveFullScreenStatecreateState()_ResponsiveFullScreenState();}class_ResponsiveFullScreenStateextendsStateResponsiveFullScreen{overridevoidinitState(){super.initState();if(widget.enableFullScreen){_enterFullScreen();}}Futurevoid_enterFullScreen()async{awaitFullScreenManager.enter();}Futurevoid_exitFullScreen()async{if(widget.autoExitOnDispose){awaitFullScreenManager.exit();}}void_handleUserInteraction(){if(widget.enableGestureControlwidget.enableFullScreen){FullScreenManager.showSystemUI();}}overridevoiddispose(){_exitFullScreen();super.dispose();}overrideWidgetbuild(BuildContextcontext){returnwidget.enableGestureControl?GestureDetector(onTap:_handleUserInteraction,behavior:HitTestBehavior.opaque,child:widget.child,):widget.child;}}完整的视频播放器示例// video_player_screen.dartimportpackage:flutter/material.dart;importresponsive_full_screen.dart;classVideoPlayerScreenextendsStatefulWidget{finalStringvideoUrl;constVideoPlayerScreen({Key?key,requiredthis.videoUrl}):super(key:key);override_VideoPlayerScreenStatecreateState()_VideoPlayerScreenState();}class_VideoPlayerScreenStateextendsStateVideoPlayerScreen{bool _showControlsfalse;overrideWidgetbuild(BuildContextcontext){returnResponsiveFullScreen(enableGestureControl:true,child:Scaffold(backgroundColor:Colors.black,body:Stack(children:[// 视频播放器Center(child:Text(视频播放器,style:TextStyle(color:Colors.white,fontSize:24),),),// 控制栏if(_showControls)Positioned(bottom:0,left:0,right:0,child:Container(color:Colors.black54,padding:EdgeInsets.all(16),child:Row(mainAxisAlignment:MainAxisAlignment.spaceBetween,children:[IconButton(icon:Icon(Icons.arrow_back,color:Colors.white),onPressed:()Navigator.pop(context),),IconButton(icon:Icon(Icons.fullscreen_exit,color:Colors.white),onPressed:(){// 退出全屏逻辑},),],),),),],),),);}}配置示例// main.dartimportpackage:flutter/material.dart;importvideo_player_screen.dart;voidmain(){runApp(constMyApp());}classMyAppextendsStatelessWidget{constMyApp({super.key});overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:Flutter 全屏示例,theme:ThemeData(primarySwatch:Colors.blue,useMaterial3:true,),home:constHomeScreen(),);}}classHomeScreenextendsStatelessWidget{constHomeScreen({super.key});overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText(首页)),body:Center(child:Column(mainAxisAlignment:MainAxisAlignment.center,children:[ElevatedButton(onPressed:(){Navigator.push(context,MaterialPageRoute(builder:(context)VideoPlayerScreen(videoUrl:https://example.com/video.mp4,),),);},child:constText(进入全屏视频播放),),constSizedBox(height:20),constText(提示点击屏幕可以临时显示系统控制栏),],),),);}}总结核心方法使用 SystemChrome.setEnabledSystemUIMode() 控制全屏推荐模式SystemUiMode.immersiveSticky 用户体验最佳生命周期管理确保在 dispose() 中恢复系统 UI平台适配Android 和 iOS 需要不同的处理策略用户体验提供手势控制让用户可以临时查看系统 UI错误处理添加适当的异常处理和状态恢复通过以上方案你可以灵活地在 Flutter 应用中实现全屏页面并提供良好的用户体验。根据具体需求选择合适的实现方式建议使用封装好的 ResponsiveFullScreen 组件来简化开发。