WEBサイト制作・アプリ開発・システム開発・ブランディングデザイン制作に関するご相談はお気軽にご連絡ください。
構想段階からじっくりとヒアリングし、お客様の課題にあわせたアプローチ手法でお客様の“欲しかった”をカタチにしてご提案いたします。
Blog スタッフブログ
Flutter
システム開発
[Flutter]手書き対応Widgetのコードスニペット
こんにちは、株式会社MIXシステム開発担当のBloomです。
今回はFlutterで利用できるコードスニペットを紹介します。まずはこちらのクラスを定義しましょう。
import 'package:flutter/material.dart';
class FreeDrawCanvas extends StatefulWidget {
final Color strokeColor;
final double strokeWidth;
const FreeDrawCanvas({
super.key,
this.strokeColor = Colors.black,
this.strokeWidth = 4.0,
});
@override
State<FreeDrawCanvas> createState() => _FreeDrawCanvasState();
}
class _FreeDrawCanvasState extends State<FreeDrawCanvas> {
final List<Offset?> _points = [];
final GlobalKey _canvasKey = GlobalKey();
Offset _getLocalPosition(DragUpdateDetails details) {
final box = _canvasKey.currentContext?.findRenderObject() as RenderBox;
return box.globalToLocal(details.globalPosition);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanUpdate: (details) {
setState(() => _points.add(_getLocalPosition(details)));
},
onPanEnd: (_) => setState(() => _points.add(null)),
child: RepaintBoundary(
key: _canvasKey,
child: CustomPaint(
painter: _FreeDrawPainter(_points, widget.strokeColor, widget.strokeWidth),
size: Size.infinite,
),
),
);
}
}
class _FreeDrawPainter extends CustomPainter {
final List<Offset?> points;
final Color color;
final double width;
_FreeDrawPainter(this.points, this.color, this.width);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..strokeWidth = width
..strokeCap = StrokeCap.round;
for (int i = 0; i < points.length - 1; i++) {
if (points[i] != null && points[i + 1] != null) {
canvas.drawLine(points[i]!, points[i + 1]!, paint);
}
}
}
@override
bool shouldRepaint(_FreeDrawPainter oldDelegate) => true;
}
利用例はこちらのようになります。Widgetとして利用できますが、明確なサイズ指定を与えなければ警告が発生するので注意してください。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("手書き")),
body: FreeDrawCanvas(
strokeColor: Colors.blue,
strokeWidth: 3.0,
),
);
}
これだけでFlutterで手書き機能を実装することができました。良かったですね。