반응형
게시물 작성시 해시태그를 적용하고 싶어서 기록 한다.
기존에는 그냥 Text 위젯을 사용하여 게시물의 내용을 표현하였다.
하지만 해시태그가 있을 때 이를 강조하기 위해서는 다른 방법이 필요했다.
Text위젯으로는 중간에 특정 부분만 style을 변경할 수 없기 때문이다.
1. TextSpan
- TextSpan
text에 여러 스타일을 적용하고 그것을 하나의 text 위젝으로 표시할 때 사용되는 클래스이다. - 주요속성
- text: 표시할 텍스트 문자열.
- style: 텍스트 스타일을 지정하는 TextStyle 객체. 폰트 크기, 색상, 굵기 등을 정의할 수 있습니다.
- children: 또 다른 TextSpan 리스트를 포함하여 중첩된 스타일링을 적용할 수 있습니다.
- recognizer: 터치 이벤트나 클릭과 같은 사용자 상호작용을 처리하는 GestureRecognizer를 지정할 수 있습니다.
2. 정규표현식
static final hashTagRegex = RegExp(r'(?<=^|\s)#[a-zA-Z0-9가-힣_]+(?:_[a-zA-Z0-9가-힣_]+)*(?=\s|$)');
해시 태그를 강조하기 위해서 해시태그 부분을 찾아야하는데, 필자는 정규표현식을 사용하였다.
아래와 같이 적용 될 수 있도록 정규표현식을 만들었다.
- ## 적용 되지 않는다.
- 해시태그(#) 뒤에 _ 이외에 특수문자는 적용되지 않는다.
- 해시태그(#) 앞에 공백이 없으면 적용되지 않는다.
- 그 외에 해시태그(#)적용
3. 코드 적용
List<TextSpan> buildTextSpans(
String text,
Function(String hashTag)? onHashTag,) {
final List<TextSpan> spans = [];
final matches = <RegExpMatch>[];
matches.addAll(RegexPatterns.hashTagRegex.allMatches(text));
int lastMatchEnd = 0;
for (final match in matches) {
if (match.start > lastMatchEnd) {
spans.add(
TextSpan(
text: text.substring(lastMatchEnd, match.start),
style: defaultStyle,
),
);
}
final matchedText = match.group(0)!;
if (matchedText.startsWith('#')) {
spans.add(
TextSpan(
text: matchedText,
style: hashTagStyle,
recognizer: onHashTag == null
? null
: (TapGestureRecognizer()..onTap = () => onHashTag(matchedText)),
),
);
}
lastMatchEnd = match.end;
}
if (lastMatchEnd < text.length) {
spans.add(
TextSpan(
text: text.substring(lastMatchEnd),
style: defaultStyle,
),
);
}
return spans;
}
- 함수매개 변수
- text: 입력받은 문자열입니다.
- onHashTag: 해시태그를 터치했을 때 실행될 콜백 함수. 해시태그를 감지하고 이 함수가 정의되어 있으면, 해당 해시태그에 클릭 이벤트 연결. 만약 null이면 상호작용이 없는 상태로 해시태그를 표시
- 동작 흐름
- 해시태그(#)를 찾기 위한 정규식 매칭 : matches.addAll(RegexPatterns.hashTagRegex.allMatches(text));을 사용하여 문자열에서 해시태그에 해당하는 부분을 탐지
- 매칭된 해시태그와 일반 텍스트 분리
- lastMatchEnd 를 사용하여 이전에 매칭된 텍스트 이후의 남은 텍스트를 추적
- 해시태그와 해시태그 사이에 있는 일반 텍스트는 따로 처리하여 TextSpan에 기본 스타일을 적용
- 일반 텍스트 스타일 추가
- 해시태그 스타일 추가
- 마지막 남은 텍스트 처리
- 마지막으로 매칭이 끝난 부분 이후에 남아있는 텍스트가 있다면, 해당 텍스트도 기본 스타일을 사용해 TextSpan으로 추가
4. 결과 화면
아래와 같이 해시태그(#)와 (_) 부분이 잘 분리되어 표현되고 있는 것을 볼 수 있다.
반응형
'프레임워크 > Flutter' 카테고리의 다른 글
[Flutter] webview_flutter를 활용한 webview 표현하기 (0) | 2024.09.02 |
---|---|
[Flutter] TextScale 고정하기, 텍스트크기 고정 (0) | 2024.06.22 |
[Flutter]flutter_screenutil 사용방법, 반응형 앱 만들기 (0) | 2024.06.08 |
[Flutter]반응형 앱, flutter_screenutil vs responsive_framework (1) | 2024.06.08 |
[Flutter] ios/Android AppStroe, PlayStore 이동하기 (1) | 2024.06.08 |
댓글