flutter 五:MaterialApp

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 可以获取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

  • 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,
    );
    },

title

title: 'Flutter',
     title: 'Hellow',

onGenerateTitle

  • final GenerateAppTitle? onGenerateTitle;

  • typedef GenerateAppTitle = String Function(BuildContext context);

  • 重建页面时改函数回调 例如重新运行程序

    var pageChange = 1;

    onGenerateTitle: (context){
    pageChange++;
    return "页面重建${pageChange}";
    },

Theme 单独整

国际化 单独整locale/localizationsDelegates/localeListResolutionCallback/localeResolutionCallback/supportedLocales

debugShowMaterialGrid

  • this.debugShowMaterialGrid = false,

showSemanticsDebugger

showSemanticsDebugger:true,

相关推荐
problc8 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人17 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人20 小时前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
起司锅仔1 天前
Flutter启动流程(2)
flutter
hello world smile1 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
lqj_本人1 天前
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
flutter·harmonyos
iFlyCai1 天前
极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
flutter
lqj_本人1 天前
Flutter&鸿蒙next 中使用 MobX 进行状态管理
flutter·华为·harmonyos
lqj_本人1 天前
Flutter&鸿蒙next 中的 setState 使用场景与最佳实践
flutter·华为·harmonyos
hello world smile1 天前
Flutter常用命令整理
android·flutter·移动开发·android studio·安卓