flutter 五:MaterialApp

发布时间:2024年01月05日
MaterialApp
 const MaterialApp({
    super.key,
    this.navigatorKey,   //导航键
    this.scaffoldMessengerKey,   //scaffold管理
    this.home,   //首页
    Map<String, WidgetBuilder> this.routes = const <String, WidgetBuilder>{},  //路由
    this.initialRoute,  //初始路由
    this.onGenerateRoute,  //路由生成器
    this.onGenerateInitialRoutes, //生成初始化路由
    this.onUnknownRoute,  //onGenerateRoute 无法生成路由时调用
    List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],   //导航观察者
    this.builder,   //页面构建者
    this.title = '',  //标题
    this.onGenerateTitle, //不为空则调用此回调函数生成标题  为空则使用title
    this.color,  //主色
    this.theme,  //主题
    this.darkTheme,  //暗色主题
    this.highContrastTheme,  //高对比度 主题
    this.highContrastDarkTheme, //高对比度 暗色主题
    this.themeMode = ThemeMode.system,  //主题模式  默认跟随系统
    this.themeAnimationDuration = kThemeAnimationDuration, //主题动画时长
    this.themeAnimationCurve = Curves.linear,  //主题动画曲线
    this.locale,      //app语言支持
    this.localizationsDelegates,   //多语言代理
    this.localeListResolutionCallback,
    this.localeResolutionCallback, //监听系统语言切换事件
    this.supportedLocales = const <Locale>[Locale('en', 'US')],  //多语言支持
    this.debugShowMaterialGrid = false,   //显示网格
    this.showPerformanceOverlay = false,   //是否打开性能监控
    this.checkerboardRasterCacheImages = false,
    this.checkerboardOffscreenLayers = false,
    this.showSemanticsDebugger = false,   //打开一个覆盖图,显示框架报告的可访问性  显示边框
    this.debugShowCheckedModeBanner = true,  //右上角的 debug图标
    this.shortcuts,
    this.actions,
    this.restorationScopeId,
    this.scrollBehavior,
    @Deprecated(
      'Remove this parameter as it is now ignored. '
      'MaterialApp never introduces its own MediaQuery; the View widget takes care of that. '
      'This feature was deprecated after v3.7.0-29.0.pre.'
    )
    this.useInheritedMediaQuery = false,
  })

routes 配置路由跳转

  • routes 配置路由跳转页面
  • initialRoute 初始化显示路由页面
以下例子实现点击B跳转B页面 点击C跳转C页面
import 'package:flutter/material.dart';

void main() {     //程序入口
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      initialRoute: '/A',   //初始显示的页面
      routes: {   //配置页面路由
        "/A": (context) => A(),
        "/B": (context) => B(),
        "/C": (context) => C(),
      },
    );
  }
}

class A extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => AState();
}

class AState extends State<A>{
  @override
  Widget build(BuildContext context) {
     return Scaffold(
       body: Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: [
             Text("AAAAAAAAAAAAAAAAAAAAAAA"),
             TextButton(
               child: Text("jump to BBBB"),
               onPressed: _onPressedB,
             ),
             TextButton(
               child: Text("jump to CCCC"),
               onPressed: _onPressedC,
             )
           ],
         )
       ),
     );
  }

//点击跳转B
  _onPressedB(){
 //   Navigator.of(context).pushNamed('/B');
   Navigator.pushNamed(context, '/B');
  }
//点击跳转C
  _onPressedC(){
   // Navigator.of(context).pushNamed('/C');
     Navigator.pushNamed(context, '/C');
  }
}

//页面A
class B extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => BState();
}

class BState extends State<B>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"),
      ),
    );
  }
}

//页面C
class C extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => CState();
}

class CState extends State<C>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("CCCCCCCCCCCCCCCCCCCCCCCCC"),
      ),
    );
  }
}

结果:
请添加图片描述

navigatorKey

  • navigatorKey 可以获取context 从而在外部实现页面跳转
以下例子 启动app5s后自动跳转到C页面
  • 在MaterialApp 下添加navigatorKey 属性
    在这里插入图片描述
  • 并添加以下代码 启动项目后5s自动跳转到C页面
GlobalKey<NavigatorState> _navigatorKey = GlobalKey();

void main() {     //程序入口
  runApp(const MyApp());

  //5s后自动跳转到C
  Future.delayed(Duration(seconds: 5))
  .then((value){
    var context = _navigatorKey.currentState?.overlay?.context; //也可以使用_navigatorKey.currentContext!
    Navigator.pushNamed(context!, "/C");
  });
}

运行结果请添加图片描述

scaffoldMessengerKey

  • 管理scaffold 可以实现无context 显示SnackBar
MaterialApp 增加
scaffoldMessengerKey:_scaffoldMessengerKey,
GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey = GlobalKey();

void main() {     //程序入口
  runApp(const MyApp());

  //5s后自动跳转到C
  Future.delayed(Duration(seconds: 5))
  .then((value){
    _scaffoldMessengerKey.currentState?.showSnackBar(SnackBar(content: Text("wo li ge qu")));  //5S后显示SnackBar
  });

}

请添加图片描述

home initialRoute

  • home 显示首页weight
  • initialRoute 显示初始化的页面
  • 两个属性同时存在时 都会执行 home优先执行 且页面可以回退到home页
   home: B(),   //使用B页面   
   initialRoute: '/A',  //使用A页面

A B 页面构造函数打印页面信息
结果

B页面启动!
A页面启动!
  • 只有home
     home: B(),
      // initialRoute: '/A',

结果

B页面启动!
  • 只有initialRoute
// home: B(),
      initialRoute: '/A',

结果

A页面启动!

onGenerateRoute

  • 页面跳转时 如果找不到页面 会执行该回调,返回一个RouteSettings
  • 添加参数
  onGenerateRoute: _onGenerateRoute,
RouteFactory _onGenerateRoute = (settings){
    print(settings.name);
    print(settings.runtimeType);
    print(settings.arguments);
};
  • 添加点击事件 跳转到D routes中无 ‘/D’
    在这里插入图片描述

在这里插入图片描述
结果 且会报错

/D
RouteSettings
null

======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Could not find a generator for route RouteSettings("/D", null) in the _WidgetsAppState.
onGenerateRoute可用于页面跳转错误时的纠错处理
RouteFactory _onGenerateRoute = (settings){
    print(settings.name);
    print(settings.runtimeType);
    print(settings.arguments);
    return MaterialPageRoute(builder: (context)=>C());   //返回要跳转的页面路由
};

结果

/D
RouteSettings
null
B页面启动!

onGenerateInitialRoutes

  • final InitialRouteListFactory? onGenerateInitialRoutes;
  • typedef InitialRouteListFactory = List<Route> Function(String initialRoute);
  • initialRoute 设置了,生成initialRoute时回调
 onGenerateInitialRoutes: (initialRoute){
        print("initialRoute>>${initialRoute}");
        return [

           MaterialPageRoute(builder: (context) => B()),
           MaterialPageRoute(builder: (context) => C()),
          MaterialPageRoute(builder: (context) => A()),
        ];
      },

结果

initialRoute>>/A
B页面启动!
A页面启动!

请添加图片描述

onUnknownRoute

  • final RouteFactory? onUnknownRoute;
  • typedef RouteFactory = Route? Function(RouteSettings settings);
  • 路由页面不存在时 onGenerateRoute 不返回指定路由页面时 回调
  • 作用基本与onGenerateRoute 的回调一样

在这里插入图片描述

onUnknownRoute: (settings){
        print("onUnknownRoute>>${settings.name}");
        print("onUnknownRoute>>${settings.runtimeType}");
        print("onUnknownRoute>>${settings.arguments}");
      },

结果

/D
RouteSettings
null
onUnknownRoute>>/D
onUnknownRoute>>RouteSettings
onUnknownRoute>>null
======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
The onUnknownRoute callback returned null.

添加 : return MaterialPageRoute(builder: (context)=>B()); 亦可跳转到Bye

navigatorObservers

  • List this.navigatorObservers = const [],
  • 路由跳转监听

class _NavigatorObserver extends NavigatorObserver{
  @override
  void didStartUserGesture(Route route, Route? previousRoute) {
    print("didStartUserGesture>>route:${route}  previousRoute:${previousRoute}");
    super.didStartUserGesture(route, previousRoute);
  }


  @override
  void didPop(Route route, Route? previousRoute) {
    print("didPop>>route:${route}  previousRoute:${previousRoute}");
    super.didPop(route, previousRoute);
  }
  
  @override
  void didPush(Route route, Route? previousRoute) {
    print("didPush>>route:${route}  previousRoute:${previousRoute}");
    super.didPush(route, previousRoute);
  }

  @override
  void didRemove(Route route, Route? previousRoute) {
    print("didRemove>>route:${route}  previousRoute:${previousRoute}");
    super.didRemove(route, previousRoute);
  }


  @override
  void didReplace({Route? newRoute, Route? oldRoute}) {
    print("didReplace>>newRoute:${newRoute}  oldRoute:${oldRoute}");
    super.didReplace(newRoute:newRoute, oldRoute:oldRoute);
  }

  @override
  void didStopUserGesture() {
    print("didStopUserGesture>>");
    super.didStopUserGesture();
  }
}

navigatorObservers: [
         _NavigatorObserver()
      ],

结果

didPush>>route:MaterialPageRoute<dynamic>(RouteSettings("/A", null), animation: AnimationController#239da(? 1.000; paused; for MaterialPageRoute<dynamic>(/A)))  previousRoute:null
A页面启动!

//点击跳转B
didPush>>route:MaterialPageRoute<dynamic>(RouteSettings("/B", null), animation: AnimationController#d51ac(? 0.000; for MaterialPageRoute<dynamic>(/B)))  previousRoute:MaterialPageRoute<dynamic>(RouteSettings("/A", null), animation: AnimationController#239da(? 1.000; paused; for MaterialPageRoute<dynamic>(/A)))
B页面启动!

//返回A
didPop>>route:MaterialPageRoute<dynamic>(RouteSettings("/B", null), animation: AnimationController#d51ac(? 1.000; for MaterialPageRoute<dynamic>(/B)))  previousRoute:MaterialPageRoute<dynamic>(RouteSettings("/A", null), animation: AnimationController#239da(? 1.000; paused; for MaterialPageRoute<dynamic>(/A)))

builder

  • 页面构建着 在Weight前调用
  • 返回一个Weight 一般时参数 child的包装Wight
  • 返回 脚手架Scaffold 用于初始化一些基础配置 比如字体大小主题色
 builder: (context,child){
        return child!;
      },
 builder: (context,child){
        return Scaffold(
          appBar: AppBar(title: Text("实例"),backgroundColor: Colors.green,),
          body: child,
        );
      },

在这里插入图片描述

文章来源:https://blog.csdn.net/weixin_41648633/article/details/135366530
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。