Flutter自定义形状绘制插件shape的使用
Flutter自定义形状绘制插件shape的使用
本插件用于构建可轻松复用、验证和解析的表单。以下是关于如何使用该插件的具体说明。
目录
概要
此插件包含三个部分:
- shape包 包含创建表单主体所需的主要类和注解。
- shape_generator包,这是运行在带有
@GenerateFormBody()
注解的类上的代码生成器。 - shape_starter_kit包,其中包含一组通用且常用的表单字段和函数,供
shape
包使用。
使用
首先,将 shape
包添加到项目的依赖项中。
dart pub add shape
然后,将 shape_generator
和 build_runner
包添加到项目的开发依赖项中。
dart pub add --dev shape_generator build_runner
注意 如果上述命令不起作用,可以考虑手动将包添加到 pubspec.yaml
文件中,将 shape
包置于 dependencies
下,将 shape_generator
和 build_runner
包置于 dev_dependencies
下。
为了生成一个名为 ExampleFormBody
的表单主体,可以按以下步骤操作:
- 创建一个带有
@GenerateFormBody()
注解的抽象类ExampleFormBody
。 - 添加
_$ExampleFormBodyFields
混入类。 - 创建一个未命名的工厂方法,返回一个包含所有表单字段的
_$ExampleFormBody
实例。所有参数必须是一个扩展了FormField
类的实例。
完整的示例代码可能如下所示:
import 'package:shape/shape.dart';
import 'package:shape_addons/shape_addons.dart';
part 'example_form_body.g.dart';
@GenerateFormBody()
abstract class ExampleFormBody with _$ExampleFormBodyFields {
factory ExampleFormBody({
required String? name,
required int? age,
}) {
return _$ExampleFormBody(
name: GenericFormField(
value: name,
isRequired: true,
),
age: IntegerFormField(
value: age,
),
);
}
}
void main() {
final formBody = ExampleFormBody(name: 'John', age: 25);
print('Example form: $formBody');
print('Example form errors: ${formBody.validate()}');
}
原理
Shape 通过将表单字段、表单主体、验证逻辑和解析逻辑分离到不同的类中来工作。
表单主体是一组表单字段。数据进入和离开表单主体的流程如下:
flowchart TD
classDef multipleValues fill:#f0f0f0,stroke:#000000,stroke-dasharray: 5;
classDef classInstance fill:#eeeeff,stroke:#aaaaee
classDef function fill:#d0efe6,stroke:#6cddbd
raw{{Raw String values}}:::multipleValues
fbc(Form body constructor):::function
fbi[Form body instance]:::classInstance
parsed{{Parsed values}}:::multipleValues
fei[Form errors instance]:::classInstance
raw -- "are given to" --> fbc
fbc -- "parses fields and creates" --> fbi
fbi -- "contains" --> parsed
fbi -- "when calling validate() creates" --> fei
特性
访问解析后的值
表单主体接收原始值并生成解析后的值。每次表单主体被构造或复制(使用 copyWith
)时,值会自动解析,并作为具有相同名称的属性可访问。
var formBody = ExampleFormBody(name: 'John');
print('Example form: $formBody');
print('Example form errors: ${formBody.validate()}');
自动生成表单错误
生成表单主体时,会同时创建一个相邻的 [FormErrors]
类,并可访问。
var formBody = ExampleFormBody(name: 'John');
print('Example form: $formBody');
print('Example form errors: ${formBody.validate()}');
示例
要运行示例,需要在 example
文件夹中运行 build_runner
。
cd example
flutter pub run build_runner build --delete-conflicting-outputs
基于 example/lib/example_form_body.dart
文件的内容,将生成一个新的表单主体。生成完成后,检查 example/lib/example_form_body.g.dart
文件的内容。
import 'package:shape_example/example_form_body.dart';
void main() {
print(r'''
This project is not meant to be run like a normal Dart project, but instead
showcases how to generate form bodies using Shape.
Generate the form bodies by running:
dart run build_runner build --delete-conflicting-outputs
''');
final form = ExampleFormBody(name: 'John');
print('Example form: $form');
print('Example form errors: ${form.validate()}');
final invalidForm = ExampleFormBody(name: null, age: 25);
print('Invalid example form: $invalidForm');
print('Invalid example form errors: ${invalidForm.validate()}');
}
更多关于Flutter自定义形状绘制插件shape的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义形状绘制插件shape的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,自定义形状绘制通常涉及使用CustomPaint
和CustomPainter
类。虽然Flutter社区中可能有多个用于绘制自定义形状的插件,但基于你的要求,这里我们不会依赖特定的插件,而是直接展示如何使用CustomPaint
和CustomPainter
来绘制自定义形状。
以下是一个简单的例子,展示如何使用CustomPaint
和CustomPainter
来绘制一个自定义的星形:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Custom Shape Example'),
),
body: Center(
child: CustomPaint(
size: Size(200, 200), // 设置绘制区域的大小
painter: StarPainter(), // 使用自定义的Painter类
),
),
),
);
}
}
class StarPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
// 星形的五个顶点
final List<Offset> points = [
Offset(size.width * 0.5, size.height * 0.2),
Offset(size.width * 0.65, size.height * 0.5),
Offset(size.width * 0.5, size.height * 0.8),
Offset(size.width * 0.35, size.height * 0.5),
Offset(size.width * 0.5, size.height * 0.2),
];
// 绘制多边形
final Path path = Path()
..moveTo(points[0].dx, points[0].dy)
..lineTo(points[1].dx, points[1].dy)
..lineTo(points[2].dx, points[2].dy)
..lineTo(points[3].dx, points[3].dy)
..close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// 如果painter的状态没有改变,返回false
return false;
}
}
在这个例子中,我们创建了一个StarPainter
类,它继承自CustomPainter
。在paint
方法中,我们使用Path
类来定义一个星形的路径,并使用Canvas
的drawPath
方法来绘制这个路径。星形的五个顶点通过Offset
对象定义,这些顶点连接成一个多边形。
CustomPaint
组件用于在Flutter的widget树中嵌入自定义绘制。我们通过设置CustomPaint
的size
属性来定义绘制区域的大小,并通过painter
属性指定自定义的Painter
类。
这个例子展示了如何在Flutter中不使用任何第三方插件来自定义绘制形状。如果你需要使用特定的插件(比如shape
插件,尽管这不是Flutter官方或广泛认知的插件名),你应该查阅该插件的文档来了解其API和用法。不过,基于Flutter的灵活性和强大的绘图能力,大多数情况下,使用CustomPaint
和CustomPainter
已经足够满足自定义绘制的需求。