👌
Flutter まとまったテキストのURLだけを装飾してタップできるようにする
結構使いそうなパターンだと思ったんですけど
あんまり記事がなかったのでネタにしました。
どういうパターンか
初めからテキストが固まっているなら手動でバラして
適当にRichTextで色付けすればいいと思うんですけど、
APIレスポンスでStringを受け取って
その中にあるURLだけ色付けして欲しい
みたいな要件ってよくあると思うんですよね
'This is a sample URL: https://hogehoge.com nextPogePoge https://pogepoge.com';
こういうやつ
実装
const String textWithUrl =
'This is a sample URL: https://hogehoge.com nextPogePoge https://pogepoge.com';
RichText buildRichTextWithUrl(String textWithUrl) {
List<TextSpan> textSpans = [];
final RegExp regex = RegExp(r'https?://\S+');
final List<RegExpMatch> matches = regex.allMatches(textWithUrl).toList();
int lastMatchEnd = 0;
for (RegExpMatch match in matches) {
if (match.start > lastMatchEnd) {
textSpans.add(TextSpan(
text: textWithUrl.substring(lastMatchEnd, match.start),
style: const TextStyle(color: Colors.black)));
}
textSpans.add(TextSpan(
text: match.group(0),
style: const TextStyle(
color: Colors.blue, decoration: TextDecoration.underline),
recognizer: TapGestureRecognizer()
..onTap = () {
// Handle URL click action here
print('URL clicked: ${match.group(0)}');
},
));
lastMatchEnd = match.end;
}
if (lastMatchEnd < textWithUrl.length) {
textSpans.add(TextSpan(
text: textWithUrl.substring(lastMatchEnd),
style: const TextStyle(color: Colors.black)));
}
return RichText(
text: TextSpan(children: textSpans),
);
}
解説
まぁ普通に正規表現でhttp判定をし、
文字列炙り出してその文字列に対して装飾してるって感じですね
以下ChatGPTくんの正規表現解説です。
正規表現
RegExp(r'https?://\S+');
は、文字列のパターンマッチング(文字列のパターン検索)に使用される正規表現です。以下に各部分の意味を解説します:
r
プレフィックス:
r
プレフィックスは、生の文字列リテラルを表します。バックスラッシュ\
をエスケープシーケンスとして扱わないようにします。
https?
:
https
という文字列にマッチします。s
は0回または1回の出現を示す正規表現メタ文字?
と組み合わされています。つまり、s
は0回または1回の出現という意味です。これにより、http
またはhttps
のいずれかにマッチします。
://
:
://
という文字列にマッチします。これは URL の標準的なプロトコルのセパレータです。
\S+
:
\S
は非空白文字にマッチする正規表現メタ文字です。+
は直前のパターンが1回以上繰り返されることを示します。つまり、非空白文字が1回以上連続して出現するパターンにマッチします。
したがって、この正規表現は、
http
またはhttps
で始まり、それに続く://
の後に非空白文字が1回以上連続する文字列にマッチします。これは、URL の一般的な構造を表現しています。
あとは各々やりたいように色付けしたり分岐増やしたりするといいと思います。
Discussion