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,

相关推荐
宇擎智脑科技3 小时前
Flutter 对接高德地图 SDK 适配鸿蒙踩坑记录与通信架构解析
flutter·架构·harmonyos
嗝o゚3 小时前
鸿蒙智慧屏与Flutter适配:无硬件功能的兼容处理
flutter·华为·开源·harmonyos
kirk_wang3 小时前
Flutter media_info插件在OpenHarmony平台的适配实践
flutter·移动开发·跨平台·arkts·鸿蒙
小a杰.3 小时前
Flutter 后端联动详解
flutter
ujainu4 小时前
Flutter与DevEco Studio结合开发简单项目实战指南
flutter·开发·deveco studio
嗝o゚5 小时前
Flutter 无障碍功能开发最佳实践
python·flutter·华为
嗝o゚5 小时前
Flutter与ArkTS混合开发框架的探索
flutter
小a杰.6 小时前
Flutter国际化(i18n)实现详解
flutter
嗝o゚6 小时前
开源鸿蒙 Flutter 应用包瘦身实战
flutter·华为·开源·harmonyos
小a杰.6 小时前
Flutter 响应式设计基础
flutter