Flutter自定义绘图插件mini_canvas的使用
Flutter自定义绘图插件mini_canvas的使用
利用Canvas绘制控件。
导包
import 'package:mini_canvas/mini_canvas.dart';
主要实现的内容
-
五角星
-
仪表盘
-
圆弧
-
时钟
-
水波纹进度
-
自定义状态图
使用
引入库
flutter pub add mini_canvas
更多功能可以clone项目并运行demo。
完整示例Demo
import 'package:flutter/material.dart';
import 'time_clock_page.dart';
import 'package:mini_canvas/mini_canvas.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Widget> items = [];
[@override](/user/override)
Widget build(BuildContext context) {
items.clear();
initWaveProgress();
initBashBoarWidget();
initClockWidget();
initArcWidgets();
initFiveWidgets();
initStateWidgets();
initStringWidget();
return Scaffold(
appBar: AppBar(title: const Text("MiniCanvas 测试页面")),
backgroundColor: Colors.grey[300],
body: SingleChildScrollView(
child: Column(children: items),
));
}
void initWaveProgress() {
items.add(_buildItem(
"波浪进度",
ListView(
children: [
const WaveProgress(
100,
20,
label: '空置面积剩余',
subLabel: '5000㎡',
),
const WaveProgress(
300,
20,
label: '进度',
),
WaveProgress(
MediaQuery.of(context).size.width,
70,
label: '出勤率',
),
],
)));
}
void initBashBoarWidget() {
items.add(_buildItem(
"仪表盘",
ListView(
children: [
const BashBoardWidget(100,
strokeWidth: 8, label: '收缴率', value: 68.23),
const BashBoardWidget(300,
strokeWidth: 10, label: '出勤率', value: 100),
BashBoardWidget(MediaQuery.of(context).size.width,
strokeWidth: 20, label: '出租率', value: 35.33),
],
)));
}
void initClockWidget() {
items.add(_buildItem("时钟", const TimeClockPage()));
}
void initStringWidget() {
items.add(_buildItem(
"旋转字符串",
const Stack(
children: [
StringWidget(
"↖",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.left,
verticalAlign: VerticalAlign.top,
),
StringWidget(
"↑",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.center,
verticalAlign: VerticalAlign.top,
),
StringWidget(
"↗",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.right,
verticalAlign: VerticalAlign.top,
),
StringWidget(
"←",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.left,
verticalAlign: VerticalAlign.center,
),
StringWidget(
"+",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.center,
verticalAlign: VerticalAlign.center,
),
StringWidget(
"→",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.right,
verticalAlign: VerticalAlign.center,
),
StringWidget(
"↙",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.left,
verticalAlign: VerticalAlign.bottom,
),
StringWidget(
"↓",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.center,
verticalAlign: VerticalAlign.bottom,
),
StringWidget(
"↘",
width: 100,
height: 100,
horizontalTextAlign: TextAlign.right,
verticalAlign: VerticalAlign.bottom,
)
],
)));
}
void initStateWidgets() {
items.add(_buildItem(
"状态图标",
const Wrap(
children: [
StateWidget("进行中", color: Colors.blue, size: 60),
StateWidget("已删除", color: Colors.red, size: 100, fontSize: 18),
StateWidget("已完成", color: Colors.green, size: 180, fontSize: 38)
],
)));
}
void initFiveWidgets() {
items.add(_buildItem(
"五角星",
const Wrap(
children: [
FiveStarWidget(50),
FiveStarWidget(50, rotateAngle: 30),
FiveStarWidget(50, rotateAngle: 60, color: Colors.blue),
FiveStarWidget(50, rotateAngle: 90, color: Colors.blue),
FiveStarWidget(50, rotateAngle: 120),
FiveStarWidget(50, rotateAngle: 140)
],
)));
}
void initArcWidgets() {
items.add(_buildItem(
"圆弧、圆",
Wrap(
children: [
ArcWidget(50,
startAngle: 0.0,
sweepAngle: 300.0,
color: Colors.red,
strokeWidth: 15,
borderColor: Colors.grey[200]!),
ArcWidget(100,
startAngle: 0.0,
sweepAngle: 90.0,
color: Colors.red,
strokeWidth: 15,
borderColor: Colors.grey[200]!),
ArcWidget(200,
startAngle: 270.0,
sweepAngle: 90.0,
color: Colors.red,
strokeWidth: 15,
borderColor: Colors.grey[200]!),
const ArcWidget(300,
startAngle: 0.0,
sweepAngle: 360.0,
color: Colors.red,
strokeWidth: 10),
const ArcWidget(50, color: Colors.red),
const ArcWidget(50, startAngle: 0.0, sweepAngle: 90.0),
const ArcWidget(50, startAngle: 0.0, sweepAngle: 180.0),
const ArcWidget(50, startAngle: 0.0, sweepAngle: 270.0),
],
)));
}
Widget _buildItem(String title, Widget widget) =>
ListTile(title: Text(title), onTap: () => gotoPage(widget, title));
void gotoPage(Widget widget, String title) => Navigator.push(
context,
MaterialPageRoute(
builder: (ctx) =>
Scaffold(appBar: AppBar(title: Text(title)), body: widget)));
}
更多关于Flutter自定义绘图插件mini_canvas的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义绘图插件mini_canvas的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用自定义绘图插件mini_canvas
的示例代码。请注意,mini_canvas
并非一个官方的Flutter插件,因此这个示例假设你已经有一个名为mini_canvas
的插件,并且该插件提供了基本的绘图功能。如果mini_canvas
插件的API有所不同,请根据实际的文档进行调整。
首先,确保你已经在pubspec.yaml
文件中添加了mini_canvas
依赖:
dependencies:
flutter:
sdk: flutter
mini_canvas: ^x.y.z # 替换为实际的版本号
然后,运行flutter pub get
来获取依赖。
接下来,我们编写一个Flutter应用,展示如何使用mini_canvas
进行自定义绘图。假设mini_canvas
提供了一个MiniCanvas
小部件,允许我们进行绘图操作。
import 'package:flutter/material.dart';
import 'package:mini_canvas/mini_canvas.dart'; // 假设插件的主文件是mini_canvas.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Mini Canvas Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Mini Canvas Demo'),
),
body: Center(
child: CustomDrawing(),
),
),
);
}
}
class CustomDrawing extends StatefulWidget {
@override
_CustomDrawingState createState() => _CustomDrawingState();
}
class _CustomDrawingState extends State<CustomDrawing> {
@override
Widget build(BuildContext context) {
return Container(
height: 300,
width: 300,
child: MiniCanvas(
onDraw: (Canvas canvas, Size size) {
// 绘制背景颜色
final paint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint);
// 绘制一个红色矩形
final rectPaint = Paint()
..color = Colors.red
..style = PaintingStyle.fill;
canvas.drawRect(Rect.fromLTWH(50, 50, 100, 100), rectPaint);
// 绘制一条蓝色直线
final linePaint = Paint()
..color = Colors.blue
..strokeWidth = 4.0;
canvas.drawLine(Offset(50, 200), Offset(200, 50), linePaint);
// 绘制一些文本
final textPaint = TextPaint()
..color = Colors.black
..style = TextStyle(fontSize: 24);
canvas.drawText('Hello Mini Canvas!', Offset(100, 250), textPaint);
},
),
);
}
}
// 假设TextPaint是一个自定义的Paint类,用于绘制文本(如果mini_canvas没有提供,需要自定义)
class TextPaint extends Paint {
TextStyle style;
@override
void draw(Canvas canvas, String text, Offset position) {
final TextPainter textPainter = TextPainter(
text: TextSpan(text: text, style: style),
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
);
textPainter.layout(minWidth: 0, maxWidth: double.infinity);
textPainter.paint(canvas, position);
}
}
// 注意:如果mini_canvas插件提供了自己的绘图API,请直接使用它们,而不是上面的TextPaint类。
// 上面的TextPaint类只是为了演示如何可能扩展Paint类以支持文本绘制。
在这个示例中,我们创建了一个CustomDrawing
小部件,它使用MiniCanvas
来绘制一些基本的图形,包括一个矩形、一条直线和一些文本。请注意,TextPaint
类是一个假设的类,用于演示如何可能扩展Paint
类以支持文本绘制。实际使用时,你应该根据mini_canvas
插件提供的API进行相应的调整。
如果mini_canvas
插件提供了不同的绘图API或者需要不同的配置,请参考该插件的官方文档进行调整。