10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flutterでテキストの一部を簡単に装飾できるパッケージを作成した

Posted at

はじめに

こんにちは.AndroidとiOSの両アプリを同じコードで作れるFlutterに惹かれて,ここ1ヶ月くらい色々触ってみました.
レイアウトもDartファイル内に記述できてめちゃくちゃ書きやすいですが,気になる点もいくつかありました.特に不便に感じたのが,以下のようなテキストの一部を装飾することです.

  • テキスト内のURLやメールをリンクにする
  • テキストの一部をタップした時になにか動作させる(画面遷移させるとか)
  • テキストの一部のスタイルを変える(色とか)

Flutterでは,これらのようなテキストの一部に変化をもたせたい場合は,以下のような感じでRichTextInlineSpanで書いていく必要があります.

RichText(
  text: TextSpan(
    text: 'Hello ',
    style: DefaultTextStyle.of(context).style,
    children: <TextSpan>[
      TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
      TextSpan(text: ' world!'),
    ],
  ),
)

簡単なテキストなら良いですが,複雑になってくると結構大変です.

そこで,テキストの一部の装飾を簡単にできるパッケージを作成し,公開したのでその紹介です.

つくったもの

decoratable_text
テキストから任意のパターンにマッチした部分を装飾(タップアクションを追加したり,スタイルを変えたり)します.

使い方

URL部分のスタイルを変えてリンク可能にする

const DecoratableText(
  text: "url: https://flutter.dev/",
  decorations: [
    DecorationOption(
      pattern: TextPattern.url,
      style: TextStyle(color: Colors.blue),
      tapAction: TapAction.launchUrl,
      showRipple: true,
    ),
  ],
),

DecorationOptiondisplayTextを指定することで,URL部分の表示を変更させることも可能です.

DecorationOption(
  pattern: TextPattern.url,
  displayText: "Tap hare",
  style: TextStyle(color: Colors.blue),
  tapAction: TapAction.launchUrl,
  showRipple: true,
),
displayText指定なし displayText指定あり

メール部分のスタイルを変えてリンク可能にする

const DecoratableText(
  text: "mail: hogehoge@foomail.com",
  decorations: [
    DecorationOption(
      pattern: TextPattern.mail,
      style: TextStyle(color: Colors.blue),
      tapAction: TapAction.launchMail,
      showRipple: true,
    ),
  ],
),

任意のタップアクションを追加する

DecoratableText(
  text: "You can set custom tap actions. #SnackBar",
  decorations: [
    DecorationOption(
      pattern: r"#[a-zA-Z0-9_]+",
      style: TextStyle(color: Colors.teal),
      onTap: () => Scaffold.of(context).showSnackBar(
        const SnackBar(
          content: Text("Tapped #SnackBar"),
        ),
      ),
      showRipple: true,
    ),
  ],
),

複数箇所装飾する

const DecoratableText(
  text:
      "You can set multiple decoration options. \nFlutter: https://flutter.dev/ #flutter \nDart: https://dart.dev/ #dart",
  decorations: [
    DecorationOption(
      pattern: r"#[a-zA-Z0-9_]+",
      style: TextStyle(color: Colors.teal),
    ),
    DecorationOption(
      pattern: TextPattern.url,
      style: TextStyle(color: Colors.blue),
      tapAction: TapAction.launchUrl,
      showRipple: true,
    ),
  ],
),

その他,詳しい使い方はexample/lib/main.dartを参照してください.

さいごに

正規表現とループで処理させているので,decorationsが増えるとパフォーマンスが低下したり,改善点は多そうですが,一応簡単にテキストの一部を装飾したいという目的は達成できた気がします.
PRなど大歓迎です.

Package: https://pub.dev/packages/decoratable_text
Repository: https://github.com/saccho/decoratable_text

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?