Flutter で独自の図形やテキストなどを描画したい場合、CustomPaint ウィジェットと CustomPainter クラスを使うことで、キャンバス(canvas)に様々な描画をすることができます。
独自のウィジェットを作成したい場合などに使えます。
CustomPaint ウィジェットの使い方
CustomPaint ウィジェットを使う場合は以下のように書きます。
CustomPaint(
size: Size(400,100), //child:や親ウィジェットがない場合はここでサイズを指定できる
painter: _MyPainter(),
),
独自の CustomPainter クラス(_MyPainter) を painter: プロパティに渡しています。
独自の CustomPainter クラスを定義
CustomPaint ウィジェットに渡している CustomPainter クラスを定義します。
class _MyPainter extends CustomPainter {
// ※ コンストラクタに引数を持たせたい場合はこんな感じで
//double value;
//_MyPainter(this.value);
// 実際の描画処理を行うメソッド
@override
void paint(Canvas canvas, Size size) {
// ここに描画の処理を書く
canvas.drawColor(Colors.blue, BlendMode.src); //例:青で塗りつぶし
}
// 再描画のタイミングで呼ばれるメソッド
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
shouldRepaint() は再描画のタイミングで呼ばれます。一旦描画した内容を変更する必要がない場合はここで false を返しておけばOKです。
アニメーションさせたり途中で描画内容が変わるような時は、ここで true を返せば再度 paint が実行されて描画内容が更新されます。
描画できるもの(メモ)
キャンバスには、線や図形、ベジェ曲線、画像、テキストなど様々なものが描画できます。ブラーをかけたりも出来ます。(自分が試したものだけですが幾つかメモっておきます)

単色のブレンド
単色を画面全体にブレンドします。色とブレンドモードを指定します。(ブレンドモードが沢山ある)
canvas.drawColor(Colors.blue, BlendMode.src); // このブレンドは単純なベタ塗り
四角形の描画
四角形の描画です。Paintのプロパティには色々設定があるので詳しくはリファンレンスを見てみてください。
RectのLTWHは、Left,Top,Width,Heightの頭文字です。この指定には幾つかバリエーションがありますが多分これの使用頻度が高いと思います。
final paint = Paint();
paint.color = Colors.blue;
canvas.drawRect(Rect.fromLTWH(0,0,50,50), paint);
丸の描画
丸の描画です。オフセット位置と半径(とPaintオブジェクト)を指定しています。
final paint = Paint();
paint.color = Colors.red;
canvas.drawCircle(Offset(100,35), 25, paint);
線の描画
線の描画です。開始位置と終了位置のオフセットを指定しています。
final paint = Paint();
paint.color = Colors.green;
paint.strokeWidth = 5;
canvas.drawLine(Offset(140,10), Offset(140,60), paint);
装飾ありのテキスト描画
テキスト描画を色々試していたので実質ここがメインだったりします。ここだけコード量多め。(^^;
// 基本のテキストスタイル
final textStyle = TextStyle(
color: Colors.black,
fontSize: 30,
);
// 装飾されたテキストの定義
Stirng _text = 'こんにちは、Hello World';
final textSpan = TextSpan(
style: textStyle,
children: <TextSpan>[
TextSpan(text: _text.substring(0,3)),
TextSpan(text: _text.substring(3,6),style: TextStyle(color: Colors.red)),
TextSpan(text: _text.substring(6,_text.length),style: TextStyle(color: Colors.blue)),
]
);
// テキスト描画用のペインター
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
);
textPainter.layout(
minWidth: 0,
maxWidth: size.width,
);
// テキストの描画
var offset = Offset(10, 60);
textPainter.paint(canvas, offset);
// ※ ちなみに任意の文字数目のキャレット用座標も取得できます(キャレットが描画できる)
var carretOffset = textPainter.getOffsetForCaret(TextPosition(offset: 10), null);
テキスト装飾は TextSpan の children で構成しています。
一旦ここまで。
コメント