有状态无状态组件
无状态 StatelessWidget
准备两张图片
const img1 =
"https://ducafecat.tech/2021/12/09/blog/2021-jetbrains-fleet-vs-vscode/2021-12-09-10-30-00.png";
const img2 =
"https://ducafecat.tech/2021/12/09/blog/2021-jetbrains-fleet-vs-vscode/2021-12-09-20-45-02.png";
编写图片显示组件 BannerWidget
class BannerWidget extends StatelessWidget {
const BannerWidget({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Image.network(img1);
}
}
MyApp
执行
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: const [
Text('有无状态组件'),
BannerWidget(),
],
),
),
debugShowCheckedModeBanner: false,
);
}
}
运行
有状态 StatefulWidget
改写成有状态组件
class BannerWidget extends StatefulWidget {
const BannerWidget({Key? key}) : super(key: key);
State<BannerWidget> createState() => _BannerWidgetState();
}
class _BannerWidgetState extends State<BannerWidget> {
String? imgUrl;
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () {
setState(() {
imgUrl = imgUrl == img1 ? img2 : img1;
});
},
child: const Text("切换图片"),
),
Image.network(imgUrl ?? img1),
],
);
}
}
运行
可以发现通过
setState
来管理和维护内部数据状态
有状态包裹无状态组件
编写图片显示组件
class ImageWidget extends StatelessWidget {
const ImageWidget({Key? key, required this.imgUrl}) : super(key: key);
final String imgUrl;
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(10),
color: Colors.amber,
child: Image.network(imgUrl));
}
}
这里加了个 Container 显示边框
直接调用
children: [
...
ImageWidget(
imgUrl: imgUrl ?? img1,
),
],
执行
可以发现很多组件都是无状态的,文本、图片、输入框、按钮、卡片、图标...
组件树
使用函数编写组件
编写函数组件
Widget imageWidget({required String imgUrl}) {
return Container(
padding: const EdgeInsets.all(10),
color: Colors.amber,
child: Image.network(imgUrl),
);
}
调用
...
imageWidget(
imgUrl: imgUrl ?? img1,
),
查看组件树
可以发现没有显示组件的名称
imageWidget
只是 ContainerFlutter 这样做是出于性能考虑,所以如果你是可复用组件,需要用 class 包裹
参考
错误处理
- 在 macos 中网络请求
macos 网络访问没有权限
修改文件 macos/Runner/DebugProfile.entitlements
和 macos/Runner/Release.entitlements
<key>com.apple.security.network.client</key>
<true/>