【Flutter 工程】004-代码生成:functional_widget
文章目录
- 【Flutter 工程】004-代码生成:functional_widget
- 一、概述
- 1、Flutter 开发痛点
- 2、functional_widget 函数小部件
- 3、主页
- 二、基本使用
- 1、安装 functional_widget
- 2、传统写法
- 3、运行结果
- 4、代码改造
- 5、代码生成
- 命令
- 生成的代码
- 6、运行结果
一、概述
1、Flutter 开发痛点
部件代码冗长
class Foo extends StatelessWidget {
final int value;
final int value2;
const Foo({Key key, this.value, this.value2}) : super(key: key);
Widget build(BuildContext context) {
return Text('$value $value2');
}
}
使用普通函数可以更好地完成某些事情的代码
Widget foo(BuildContext context, { int value, int value2 }) {
return Text('$value $value2');
}
但不推荐这么做!因为 Flutter 能够对类组件进行 const 优化,如果使用函数的话会丧失这种优化!
2、functional_widget 函数小部件
写完函数,生成对应的小部件!
functional_widget
是一个用于 Flutter 应用程序的第三方包,它提供了一种简化小部件创建的方式,称为函数式小部件(Functional Widgets)。
在传统的Flutter开发中,创建小部件通常需要编写一个继承自StatelessWidget
或StatefulWidget
的类,并实现其build
方法来描述小部件的外观和行为。这种方式需要编写较多的模板代码,尤其是对于简单的小部件而言。
functional_widget
包通过引入函数式小部件的概念,提供了一种更简洁和直观的方式来创建小部件。使用函数式小部件,您可以将小部件的外观和行为直接定义在一个函数内部,而无需创建一个独立的类。
使用functional_widget
,您可以使用注解来标记函数,使其成为一个函数式小部件。该注解会生成一个相应的小部件类,将函数的实现转换为该类的build
方法。这样,您就可以像使用普通小部件一样在您的应用程序中使用函数式小部件。
函数式小部件具有以下优点:
- 简洁性:您可以将小部件的实现直接定义在一个函数内部,避免编写独立的类和模板代码。
- 可读性:函数式小部件更加直观和紧凑,使得代码更易于阅读和理解。
- 可组合性:函数式小部件可以轻松地组合和嵌套,使得构建复杂的用户界面变得更加灵活和便捷。
functional_widget
包不仅提供了函数式小部件的注解,还提供了一些其他的辅助函数和工具,用于进一步简化和优化小部件的创建过程。
总的来说,functional_widget
是一个实用的工具包,可帮助开发者以一种更加简洁和直观的方式创建Flutter小部件。它提供了函数式小部件的概念,并通过注解和工具简化了小部件的创建和使用过程。使用functional_widget
可以提高代码的可读性和可维护性,同时减少样板代码的编写量。
3、主页
https://pub.flutter-io.cn/packages/functional_widget
二、基本使用
1、安装 functional_widget
flutter pub add dev:functional_widget dev:build_runner functional_widget_annotation
2、传统写法
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(
child: Text("hello world!", style: TextStyle(fontSize: 40),),
),
);
}
}
3、运行结果
4、代码改造
import 'package:flutter/material.dart';
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
part 'main.g.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(
child: MyText("Hello World"),
),
);
}
}
Widget myText(String value) {
return Text(
value,
style: const TextStyle(fontSize: 40),
);
}
5、代码生成
命令
# --delete-conflicting-outputs 可选,会在生成代码冲突的时候,删除原来的代码,重新生成
flutter pub run build_runner build --delete-conflicting-outputs
生成的代码
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'main.dart';
// **************************************************************************
// FunctionalWidgetGenerator
// **************************************************************************
class MyText extends StatelessWidget {
const MyText(
this.value, {
Key? key,
}) : super(key: key);
final String value;
Widget build(BuildContext _context) => myText(value);
}