Flutterのリッチテキストエディタ「flutter_quill」を使ってみる

## 10.5.17のflutter_quillを使ってみたメモ

新しいflutter_quillを使った記事がなかったので自分用のメモとして作成しました。

10.5.17ではこれまでの書き方とは若干違っているので以下のコードで画像のような
画面を作成することができました。
[公式ドキュメント](https://pub.dev/packages/flutter_quill)に書かれていたものをそのまま書いたので全ての機能を一通り試すことができます。

![スクリーンショット 2024-09-14 0.29.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844347/05d36541-a99b-da9e-ef87-bc5d33f10f35.png)

```ruby:main.dart
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late FocusNode _focusNode;
  final QuillController _controller = QuillController.basic();

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      FocusScope.of(context).requestFocus(_focusNode);
    });
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue,
        title: Text(widget.title),
      ),
      backgroundColor: Colors.lightBlue.shade50,
      body: Center(
        child: Column(children: [
          const SizedBox(
            height: 40,
          ),
          Container(
            width: 400,
            height: 240,
            decoration: BoxDecoration(
              border: Border.all(
                color: const Color.fromARGB(255, 198, 198, 198),
                width: 3,
              ),
              borderRadius: BorderRadius.circular(5),
            ),
            child: Column(
              children: [
                QuillSimpleToolbar( // 全ての機能を使う
                  controller: _controller,
                  configurations: const QuillSimpleToolbarConfigurations(),
                ),
                Expanded( // テキストフィールド部分
                  child: Container(
                    decoration: BoxDecoration(
                      border: Border.all(
                        color: Colors.black, 
                        width: 2, 
                      ),
                      borderRadius: BorderRadius.circular(5), 
                    ),
                    child: QuillEditor.basic(
                      controller: _controller,
                      configurations: const QuillEditorConfigurations(),
                    ),
                  ),
                )
              ],
            ),
          ),
        ]),
      ),
    );
  }
}

```

もう少し使える機能を制限したいので不要だと思う修飾ボタンを非表示にしました。

![スクリーンショット 2024-09-14 0.34.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844347/ed0996ec-40fe-0652-199b-8a4440798fa7.png)

以下が実装したコードです。
```ruby:main.dart
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late FocusNode _focusNode;
  final QuillController _controller = QuillController.basic();

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      FocusScope.of(context).requestFocus(_focusNode);
    });
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue,
        title: Text(widget.title),
      ),
      backgroundColor: Colors.lightBlue.shade50,
      body: Center(
        child: Column(children: [
          const SizedBox(
            height: 40,
          ),
          Container(
            width: 400,
            height: 240,
            decoration: BoxDecoration(
              border: Border.all(
                color: const Color.fromARGB(255, 198, 198, 198),
                width: 3,
              ),
              borderRadius: BorderRadius.circular(5),
            ),
            child: Column(
              children: [
                QuillSimpleToolbar(
                  controller: _controller,
                  configurations: const QuillSimpleToolbarConfigurations(
                    showItalicButton: false,
                    showHeaderStyle: false,
                    showUnderLineButton: false,
                    showListCheck: false,
                    showListNumbers: false,
                    showListBullets: false,
                    showIndent: false,
                    showRedo: false,
                    showUndo: false,
                    showSubscript: false,
                    showSearchButton: false,
                    showSuperscript: false,
                    showStrikeThrough: false,
                    showInlineCode: false,
                    showFontFamily: false,
                    showClearFormat: false,
                    showCodeBlock: false,
                    showQuote: false,
                    showBackgroundColorButton: false,
                  ),
                ),
                Expanded(
                  child: Container(
                    decoration: BoxDecoration(
                      border: Border.all(
                        color: Colors.black,
                        width: 2,
                      ),
                      borderRadius: BorderRadius.circular(5),
                    ),
                    child: QuillEditor.basic(
                      controller: _controller,
                      configurations: const QuillEditorConfigurations(),
                    ),
                  ),
                )
              ],
            ),
          ),
        ]),
      ),
    );
  }
}

```

###### 参考にさせていただいたサイト
https://note.com/sho425/n/n0c9635143760