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,

相关推荐
奋斗的小青年!!1 天前
Flutter浮动按钮在OpenHarmony平台的实践经验
flutter·harmonyos·鸿蒙
程序员老刘1 天前
一杯奶茶钱,PicGo + 阿里云 OSS 搭建永久稳定的个人图床
flutter·markdown
奋斗的小青年!!1 天前
OpenHarmony Flutter 拖拽排序组件性能优化与跨平台适配指南
flutter·harmonyos·鸿蒙
小雨下雨的雨1 天前
Flutter 框架跨平台鸿蒙开发 —— Stack 控件之三维层叠艺术
flutter·华为·harmonyos
行者961 天前
OpenHarmony平台Flutter手风琴菜单组件的跨平台适配实践
flutter·harmonyos·鸿蒙
小雨下雨的雨1 天前
Flutter 框架跨平台鸿蒙开发 —— Flex 控件之响应式弹性布局
flutter·ui·华为·harmonyos·鸿蒙系统
cn_mengbei1 天前
Flutter for OpenHarmony 实战:CheckboxListTile 复选框列表项详解
flutter
cn_mengbei1 天前
Flutter for OpenHarmony 实战:Switch 开关按钮详解
flutter
奋斗的小青年!!1 天前
OpenHarmony Flutter实战:打造高性能订单确认流程步骤条
flutter·harmonyos·鸿蒙
Coder_Boy_1 天前
Flutter基础介绍-跨平台移动应用开发框架
spring boot·flutter