🧑‍🎨

Flutterで付箋は作れるのか?

2023/06/27に公開

✅カスタムペイントを使えばできる

以前海外のソースコードを参考に付箋を作ろうとしたのですが、うまく行きませんでした😭
今回は、カスタムペイントを使ってみて、みた感じ付箋と同じ形をしたものを作れたので、メモとして記事にしようと思いました。

これを作った

📝付箋を作るにはどうする?

こちらの機能を使います。カッコいいUIを作ることができます。
https://api.flutter.dev/flutter/widgets/CustomPaint-class.html

🇺🇸翻訳

CustomPaintクラス
ペイントフェーズで描画するキャンバスを提供するウィジェット。

ペイントを要求されると、CustomPaintはまずペインターに現在のキャンバスにペイントするように要求し、次にその子をペイントし、その子をペイントした後、foregroundPainterにペイントするように要求します。キャンバスの座標系はCustomPaintオブジェクトの座標系と一致します。ペインターは、原点を始点とし、指定されたサイズの領域を含む矩形内にペイントすることが期待されています。(もしペインターがこれらの境界の外側にペイントすると、ペイントコマンドをラスタライズするのに十分なメモリが割り当てられず、結果として動作が未定義になる可能性があります)。この範囲内でのペイントを強制するには、この CustomPaint を ClipRect ウィジェットでラップすることを検討してください。

使い方

やること

  1. CustomPainterクラスを継承したクラスを作る
  2. Canvasを作るメソッドを定義する
  3. Paintクラスをインスタンス化する
  4. Paintクラスで色をつける
  5. Pathクラスをインスタンス化する
  6. 線を引いて付箋の形をしたオブジェクトを作る
  7. anvas.drawPath(path, paint); で描画する
// CustomPainterを継承したクラスを作成
class NotePainter extends CustomPainter {
  // 描画する色を受け取る
  final Color mycolor;
  // コンストラクタで色を受け取る
  NotePainter(this.mycolor);

  
  void paint(Canvas canvas, Size size) {
    var paint = Paint(); // Paintクラスをインスタンス化
    paint.color = mycolor; // ここに引数で受け取った色を指定
    paint.style = PaintingStyle.fill; // 塗りつぶしを指定

    var path = Path(); // Pathクラスをインスタンス化
    // path.lineToで線を引いていく
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height * 0.8);
    path.lineTo(size.width * 0.8, size.height);
    path.lineTo(0, size.height);
    path.close(); // 閉じる

    canvas.drawPath(path, paint); // 描画する
  }

  
  // shouldRepaintは再描画の条件を指定するメソッド
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

使いたい箇所で呼び出す

Columnウイジェットの中で、付箋のオブジェクトを呼び出します。次に、色を引数で指定できるコンストラクターを使っているので、自分の使いたい色を指定することができます。今回は、黄色、赤、青を指定してます。

📝全体のソースコード

こちらが完成品です。

main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PainterView(),
    );
  }
}

class PainterView extends StatelessWidget {
  const PainterView({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Container(
              width: 200,
              height: 200,
              child: CustomPaint(
                size: Size(200, 200),
                painter: NotePainter(Colors.yellow), // ここで色を指定
                child: Center(
                  child: Padding(
                    padding: const EdgeInsets.all(30.0),
                    child: Text(
                      "This is a custom note",
                      style: TextStyle(fontSize: 20),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 10,
            ),
            Container(
              width: 200,
              height: 200,
              child: CustomPaint(
                size: Size(200, 200),
                painter: NotePainter(Colors.red), // ここで色を指定
                child: Center(
                  child: Padding(
                    padding: const EdgeInsets.all(30.0),
                    child: Text(
                      "This is a custom note",
                      style: TextStyle(fontSize: 20),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 10,
            ),
            Container(
              width: 200,
              height: 200,
              child: CustomPaint(
                size: Size(200, 200),
                painter: NotePainter(Colors.blue), // ここで色を指定
                child: Center(
                  child: Padding(
                    padding: const EdgeInsets.all(30.0),
                    child: Text(
                      "This is a custom note",
                      style: TextStyle(fontSize: 20),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// CustomPainterを継承したクラスを作成
class NotePainter extends CustomPainter {
  // 描画する色を受け取る
  final Color mycolor;
  // コンストラクタで色を受け取る
  NotePainter(this.mycolor);

  
  void paint(Canvas canvas, Size size) {
    var paint = Paint(); // Paintクラスをインスタンス化
    paint.color = mycolor; // ここに引数で受け取った色を指定
    paint.style = PaintingStyle.fill; // 塗りつぶしを指定

    var path = Path(); // Pathクラスをインスタンス化
    // path.lineToで線を引いていく
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height * 0.8);
    path.lineTo(size.width * 0.8, size.height);
    path.lineTo(0, size.height);
    path.close(); // 閉じる

    canvas.drawPath(path, paint); // 描画する
  }

  
  // shouldRepaintは再描画の条件を指定するメソッド
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

最後に

ちょっと長くなりましたが、付箋を作る方法を解説してみました。カスタムペイントを使えばFlutterでお絵描きができます。

Discussion