04.基础组件
2024/10/3大约 4 分钟
04.基础组件
4.1 StatelessWidget
StatelessWidget用于创建不需要维护状态的内容- 继承
StatelessWidget构建不需要维护状态的组件只需要重写build
import 'package:flutter/material.dart';
class BasicText extends StatelessWidget {
const BasicText({super.key, required this.text,});
final String text;
@override
Widget build(BuildContext context) {
return Text(text);
}
}4.2 StatefulWidget
StatefulWidget用于创建状态可变的内容- 继承
StatefulWidget需要重写createState返回对应的状态, 还需要声明对应的状态State<WidgetName>类,并至少重写state中的build方法,之后在需要更新页面内容时使用setState(()=>{更新值}) state有对应的生命周期,在每个阶段都有对应的钩子函数initState: 当widget第一次插入到widget树时会被调用, 对每一个State对象,Flutter框架只会调用一次该回调, 所以, 通常在该回调中做一些一次性的操作, 如状态初始化、订阅子树的事件通知等- 不能在该回调中调用
BuildContext.dependOnInheritedWidgetOfExactType,该方法用于在widget树上获取离当前 widget 最近的一个父级InheritedWidget,原因是在初始化完成后,widget树中的InheritFrom widget也可能会发生变化, 所以正确的做法应该在在build方法或didChangeDependencies中调用它
- 不能在该回调中调用
didChangeDependencies(): 当State对象的依赖发生变化时会被调用;例如: 在之前build()中包含了一个InheritedWidget,然后在之后的build()中Inherited widget发生了变化, 那么此时InheritedWidget的子 widget 的didChangeDependencies()回调都会被调用。典型的场景是当系统语言Locale或应用主题改变时,Flutter框架会通知widget调用此回调。需要注意, 组件第一次被创建后挂载的时候(包括重创建)对应的didChangeDependencies也会被调用build(): 此回调读者现在应该已经相当熟悉了, 它主要是用于构建widget子树的, 会在如下场景被调用:- 在调用
initState()之后 - 在调用
didUpdateWidget()之后 - 在调用
setState()之后 - 在调用
didChangeDependencies()之后 - 在State对象从树中一个位置移除后(会调用
deactivate)又重新插入到树的其他位置之后
- 在调用
reassemble(): 此回调是专门为了开发调试而提供的, 在热重载时会被调用, 此回调在Release模式下永远不会被调用didUpdateWidget(): 在widget重新构建时,Flutter框架会调用widget.canUpdate来检测widget树中同一位置的新旧节点, 然后决定是否需要更新, 如果widget.canUpdate返回true则会调用此回调。正如之前所述,widget.canUpdate会在新旧widget的key和runtimeType同时相等时会返回true, 也就是说在在新旧widget的key和runtimeType同时相等时didUpdateWidget()就会被调用deactivate(): 当State对象从树中被移除时, 会调用此回调。在一些场景下,Flutter框架会将State对象重新插到树中, 如包含此State对象的子树在树的一个位置移动到另一个位置时(可以通过GlobalKey来实现)。如果移除后没有重新插入到树中则紧接着会调用dispose()方法dispose(): 当State对象从树中被永久移除时调用;通常在此回调中释放资源

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ProgressBar extends StatefulWidget {
const ProgressBar({super.key, this.initValue = 0});
final int initValue;
@override
State<StatefulWidget> createState() => _ProgressBarState();
}
class _ProgressBarState extends State<ProgressBar> {
int _counter = 0;
late Timer _timer;
@override
void initState() {
super.initState();
//初始化状态
_counter = widget.initValue;
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
_counter++;
});
});
}
@override
Widget build(BuildContext context) {
return LinearProgressIndicator(value: _counter.toDouble()/100);
}
@override
void didUpdateWidget(ProgressBar oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void deactivate() {
super.deactivate();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
void reassemble() {
super.reassemble();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
}4.3 MaterialApp
MaterialApp:作为一个基础的框架,通过此框架作为入口组件,创建应用,配置全局相关信息,比如下列设置:title: 设置应用程序的标题,通常会显示在设备的任务管理器中theme: 配置应用程序的主题,包括主色(primarySwatch)和强调色(accentColor),还可以设置字体(fontFamily)和其他主题属性initialRoute: 设置初始路由名称,即应用程序启动时显示的页面,也可以使用home设置需要显示的组件routes: 定义应用程序的路由表,将路由名称与对应的Widget关联起来onGenerateRoute: 可选参数,用于自定义路由生成器。当应用程序尝试访问未在路由表中定义的路由时,会调用该回调函数。你可以根据settings参数生成相应的路由,并返回一个PageRoute对象,用于实现页面切换动画等效果onUnknownRoute: 可选参数,用于指定404页面。当应用程序无法匹配到路由表中定义的路由且未提供自定义路由生成器时,会调用该回调函数。你可以返回一个PageRoute对象,用于显示404页面或其他错误提示页面localizationsDelegates和supportedLocales: 用于支持应用程序的本地化。你可以添加本地化代理(localizationsDelegates)和支持的语言列表(supportedLocales),以便应用程序能够根据用户的语言偏好显示相应的翻译内容
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}