参考文档: https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=zh-cn#8
https://flutter.cn/docs/ui/widgets-intro
完整代码
import 'package:english_words/english_words.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => MyAppState(), child: MaterialApp( title: 'Namer App', theme: ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange), ), home: MyHomePage(), ), ); } } class MyAppState extends ChangeNotifier { var current = WordPair.random(); var title = "Hello Flutter"; void getTitle() { title = "Hello Flutter , I learn Mobile env"; print(title); notifyListeners(); //通知 watch widget 更新 } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { var appState = context.watch<MyAppState>(); return Scaffold( body: Column( children: [ Text('A random idea:'), Text(appState.current.asLowerCase), Text(appState.title), ElevatedButton( onPressed: () { // print('button pressed!'); appState.getTitle(); }, child: Text('Next'), ), ], ), ); } }
程序入口
通过 main
函数只是告知 Flutter 运行 MyApp 中定义的应用。
void main() { runApp(MyApp()); }
该函数只是告知 Flutter 运行 MyApp 中定义的应用。
构建 Widget 结构
MyApp 类扩展 StatelessWidget。在构建每一个 Flutter 应用时,widget 都是一个基本要素。如您所见,应用本身也是一个 widget。
MyApp 中的代码设置了整个应用,包括创建应用级状态、命名应用、定义视觉主题以及设置“主页” widget,即应用的起点。
class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => MyAppState(), child: MaterialApp( title: 'Namer App', theme: ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange), ), home: MyHomePage(), ), ); } }
定义 widget 状态
我们可以定义状态类,来创建 widget
的状态 和事件通信,然后通过 状态类扩展 来更新 widget
class MyAppState extends ChangeNotifier { var current = WordPair.random(); var title = "Hello Flutter"; void getTitle() { title = "Hello Flutter , I learn Mobile env"; print(title); notifyListeners(); //通知 watch widget 更新 } }
定义 widget UI
- 每个
widget
都会有一个build
方法,用于构建和返回 Widget 树。 每当 widget 的环境发生变化时,系统都会自动调用该方法,以便 widget 始终保持最新状态。 - MyHomePage 使用 watch 方法跟踪对应用当前状态的更改。
class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { var appState = context.watch<MyAppState>(); return Scaffold( body: Column( children: [ Text('A random idea:'), Text(appState.current.asLowerCase), Text(appState.title), ElevatedButton( onPressed: () { appState.getTitle(); }, child: Text('Next'), ), ], ), ); } }
获取上下文
通过context.watch
var appState = context.watch<MyAppState>();
关于build()
@override Widget build(BuildContext context) { }
build
方法接收一个BuildContext
参数,它提供了与当前 Widget 相关的上下文信息,例如父级Widget
的信息、主题数据等。build
方法的作用是根据当前的状态(State)和输入属性(Properties)构建并返回一个Widget
树。这个 Widget 树描述了界面的结构和外观。Flutter 框架会根据这个 Widget 树来绘制界面,并在需要时进行重建和更新。- 在 build 方法中,你可以使用各种 Flutter 提供的 Widget 来构建界面,例如 Container、Text、Image 等。你还可以使用自定义的 Widget 来组合和嵌套,以创建复杂的界面布局。
除了基本的 BuildContext 参数之外,build 方法还可以接收其他参数,这些参数可以根据需要进行传递。例如,你可以将一些配置参数或回调函数作为参数传递给自定义的 Widget,并在 build 方法中使用它们来影响界面的构建过程。
build() 常用使用
- 直接返回一个 Widget,例如:
Widget build(BuildContext context) { return Container( // 定义容器的属性和子 Widget ); }
- 使用条件语句或循环来动态构建不同的 Widget 树,例如:
Widget build(BuildContext context) { if (condition) { return Text('Condition is true'); } else { return Text('Condition is false'); } }
- 使用 Builder 模式构建复杂的 Widget 树,例如:
Widget build(BuildContext context) { return Builder( builder: (BuildContext context) { // 在这里构建并返回复杂的 Widget 树 }, ); }