Flutter 정규식을 사용하여 링크 텍스트 만들기
그래서! 그 처리를 어디서나 이용할 수 있는 StatefulWidget을 작성해 보았습니다.
사용한 패키지
link_text_atoms.dart
import 'package:flutter/gestures.dart';
import 'package:url_launcher/url_launcher.dart';
class LinkTextAtoms extends StatefulWidget {
LinkTextAtoms(this.text, {this.linkStyle, this.textStyle});
final String text;
final TextStyle linkStyle;
final TextStyle textStyle;
@override
createState() => LinkTextAtomsState();
}
class LinkTextAtomsState extends State<LinkTextAtoms> {
List<GestureRecognizer> recList = List<GestureRecognizer>();
@override
Widget build(BuildContext context) {
// 通常のテキストデフォルトスタイル
var text = Theme.of(context).textTheme.bodyText1.merge(widget.textStyle);
// リンク時のテキストデフォルトスタイル
var link = Theme.of(context)
.textTheme
.bodyText1
.merge(TextStyle(
inherit: true,
color: Colors.blue,
decoration: TextDecoration.underline))
.merge(widget.linkStyle);
List children = List<TextSpan>();
List matches = RegExp(r'https?://[a-zA-Z0-9\-%_/=&?.]+')
.allMatches(widget.text)
.toList();
var links = matches.map<TextSpan>((m) {
var rec = TapGestureRecognizer()
..onTap = () async {
// URL を処理できるアプリケーションが存在しない可能性があるためcanLaunchメソッドで処理可能かどうかチェックし、OK の場合のみlaunch()メソッドを呼ぶようにする
if (await canLaunch(m.group(0))) {
await launch(m.group(0), forceSafariVC: false);
}
};
recList.add(rec);
return TextSpan(text: m.group(0), style: link, recognizer: rec);
}).toList();
if (matches.length > 0) {
for (var i = 0; i < matches.length; i++) {
if (i == 0) {
if (matches[i].start != 0) {
children.add(TextSpan(
text: widget.text.substring(0, matches[i].start), style: text));
}
children.add(links[i]);
continue;
}
children.add(TextSpan(
text: widget.text.substring(matches[i - 1].end, matches[i].start),
style: text));
children.add(links[i]);
}
if (matches.last.end != widget.text.length) {
children.add(TextSpan(
text: widget.text.substring(matches.last.end), style: text));
}
} else {
children.add(TextSpan(text: widget.text, style: text));
}
return RichText(text: TextSpan(children: children));
}
@override
dispose() {
for (var i = recList.length - 1; i >= 0; i--) {
recList.removeAt(i);
}
super.dispose();
}
}
텍스트의 일부의 색을 바꾸고 싶은, 링크로 하고 싶은, 이벤트 발화시키고 싶기 때문에, TextSpan 위젯을 이용해, 통상 텍스트의 디폴트 스타일과 링크 텍스트였을 경우의 텍스트 스타일을 나누고 있습니다.
링크 텍스트였을 경우는 텍스트의 문자를 파랗게 해, 언더 라인을 그립니다. 여기의 스타일은 취향에 맞게 변경해 버릴 수 있습니다.
TextSpan의 recognizer 속성에서 탭을 감지할 수 있도록 설정하고 url_launcher 패키지에서 외부 브라우저를 시작합니다.
...코드량 길고 역기감을 느끼지 못한다.
이용방법
// ↑上で作成したファイルをimportする
import 'package:<プロジェクト名>/widgets/components/atoms/link_text_atoms.dart';
class SampleClass extends StatelessWidget {
SampleClass({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: LinkTextAtoms(
'このテキストはリンクですhttps://www.google.com/このテキストはリンクです')));
}
}
상관없지만 provider의 작가가 hooks 패키지 내고 있었던 최근 깨달았습니다. .
htps : // 기주 b. 코 m / 뻔뻔 l t / f
새로운 상태 관리 패키지의 Riverpod와 병용해 잘 사용할 수 있으면 좋겠습니다
빨리 이 근처의 베스트 프랙티스가 정해져 주면 기쁘다고 생각하는 오늘 요즘입니다
가끔 Flutter(Dart) 관계에 대해 중얼거리고 있거나 하기 때문에, @amitatantan를 팔로우해 주면 기쁩니다.
참고로 한 문서
Reference
이 문제에 관하여(Flutter 정규식을 사용하여 링크 텍스트 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/amita/items/0bc92bc87deb2187b061텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)