はじめに
こんにちは.AndroidとiOSの両アプリを同じコードで作れるFlutterに惹かれて,ここ1ヶ月くらい色々触ってみました.
レイアウトもDartファイル内に記述できてめちゃくちゃ書きやすいですが,気になる点もいくつかありました.特に不便に感じたのが,以下のようなテキストの一部を装飾することです.
- テキスト内のURLやメールをリンクにする
- テキストの一部をタップした時になにか動作させる(画面遷移させるとか)
- テキストの一部のスタイルを変える(色とか)
Flutterでは,これらのようなテキストの一部に変化をもたせたい場合は,以下のような感じでRichTextとInlineSpanで書いていく必要があります.
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,
),
],
),
DecorationOption
のdisplayText
を指定することで,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,
),
],
),
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F261100%2F8728289d-4b28-c5bf-bd78-5f60462ff7d8.gif?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a6af63427166c0f8feb6f17a7366775e)
任意のタップアクションを追加する
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,
),
],
),
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F261100%2Fc46dcb7c-8888-2304-38f4-a9dca72a8b4b.gif?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=9f639d5e8fd5bd8b2df558d481d4ff13)
複数箇所装飾する
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,
),
],
),
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F261100%2F03e672fa-a03b-c957-84d0-3dc26da46f59.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=771cc09a5bdd138513a467d1b8242027)
その他,詳しい使い方はexample/lib/main.dartを参照してください.
さいごに
正規表現とループで処理させているので,decorations
が増えるとパフォーマンスが低下したり,改善点は多そうですが,一応簡単にテキストの一部を装飾したいという目的は達成できた気がします.
PRなど大歓迎です.
Package: https://pub.dev/packages/decoratable_text
Repository: https://github.com/saccho/decoratable_text