일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Linux
- 벤자민플랭클린
- 명언모음
- 이모지
- 공부집중
- jetpack compose
- Flutter
- 넷플릭스
- kotlin
- 좋은글필사하기
- ASMR
- bash
- Streaming
- 이모지메모
- 코틀린
- Android
- 파이썬
- 오픈소스
- Coroutine
- 명심보감
- FSM
- Freesound
- 1인개발자
- Firebase
- androidx
- DART
- recyclerview
- 소울칼리버6
- 장자명언
- 공자명언
- Today
- Total
Vintage appMaker의 Tech Blog
[flutter] RichText 활용 본문
위의 화면에서 "내 연락처에서" 까지는 회색, "불러오기"는 검정색으로 표기해야 할 경우가 많다. 그리고 불러오기를 누르면 반응을 하며 코드를 실행해야 한다. 이럴경우, 대부분 Row(children[...])안에 Text(), SizedBox(), Spacer()를 이용하여 위의 화면을 표기한다.
그러나 좀 더 복잡하게 문자열의 색상, 폰트, 크기 등등을 설정한 문자열을 표기해야 한다면 RichText를 사용해야 한다. 특히 크기에 따라 Wrap이 되어야 한다면 RichText외에는 대안이 없다.
RichText는 크게 2가지 장점이 있는데 ,
1. 화면크기에 따른 Wrap
2. 문자열과 함께 각종 Widget을 같이 사용할 수 있음
이다
RichText(
text: TextSpan(
text: "문자열"
children: [ TextSpan(), ... ],
),
RichText에 text 파라메터로 TextSpan()을 넘겨주면 된다. 그리고 TextSpan()은 text만 처리할 수도 있지만 InlineSpan 형으로 정의된 위젯들을 children에 넘겨주어 여러 개의 자식 위젯으로 표현이 가능하다. 그 때에 넘겨지는 값 중에는 TextSpan()이 아닌 WidgetSpan()도 가능한데 이 값의 child에 일반 Widget을 구현할 수 있다. TextSpan()에는 rerecognizer 필드가 있다. 이 필드는 TapGestureRecognizer()..onTap = (){} 와 같은 코드를 구현하여 문자열을 클릭 시 , 이벤트를 처리할 수 있다.
다음은 예제소스이다. 아래 예제는 GoogleFonts를 사용했다. GoogleFonts 설치 및 예제는 다음과 같다.
[전체소스]
// 소스내에 잘못된 Expanded 사용으로
// 릴리즈로 빌드했을 경우, 화면에 아무것도 나오지 않았다.
// Expanded 삭제 후 , 릴리즈함.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.grey,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isLight = true;
Color plainTextColor = Colors.black;
@override
void initState() {
super.initState();
}
void showSnack(String s) {
var snck = SnackBar(content: Text('$s'));
ScaffoldMessenger.of(context).showSnackBar(snck);
}
@override
Widget build(BuildContext context) {
// richText 예제
List<InlineSpan> buildTextExample() {
return <InlineSpan>[
TextSpan(
text: "RichText 예제입니다. ",
style: GoogleFonts.doHyeon(color: plainTextColor, fontSize: 18),
),
WidgetSpan(
child: GestureDetector(
onTap: () {
showSnack("알람아이콘");
},
child: Icon(
Icons.access_alarm,
size: 20,
color: Colors.red,
)),
),
WidgetSpan(
child: Column(
children: [
Divider(
height: 0.5,
color: Colors.black,
),
SizedBox(
height: 25,
)
],
)),
TextSpan(
text: "TextSpan 위젯 외에도 ",
style: GoogleFonts.notoSans(color: plainTextColor, fontSize: 15),
),
WidgetSpan(
child: Image.network(
"https://media3.giphy.com/media/G35aZL8nwsBfkhjzQk/giphy.gif",
width: 30,
height: 30,
)),
TextSpan(
text: "이나 ",
style: GoogleFonts.notoSans(color: plainTextColor, fontSize: 15),
),
WidgetSpan(
child: SizedBox(
width: 20,
height: 20,
child: Checkbox(
onChanged: (value) {},
value: true,
),
)),
TextSpan(
text: "같은 TextSpan 위젯 외의 다른위젯들을 사용할 수 있습니다\n",
style: GoogleFonts.notoSans(color: plainTextColor, fontSize: 15),
),
TextSpan(
text: "테스트입니다. 1234567, abdjflksfjk +3 🎈",
style: GoogleFonts.poorStory(color: Colors.grey, fontSize: 20),
),
TextSpan(
text: "여기는",
style: GoogleFonts.poorStory(color: Colors.grey, fontSize: 20),
),
TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
showSnack("배경변경");
setState(() {
isLight = !isLight;
if (isLight) {
plainTextColor = Colors.black;
} else {
plainTextColor = Colors.white;
}
});
},
text: "클릭😀(배경변경)",
style: GoogleFonts.poorStory(color: Colors.red, fontSize: 20),
),
TextSpan(
text: "하면 반응합니다.",
style: GoogleFonts.poorStory(color: Colors.grey, fontSize: 20),
),
];
}
return Scaffold(
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'RichText Test',
),
SizedBox(
height: 10,
),
buildRichText(buildTextExample()),
SizedBox(height: 20),
Image.network(
"https://cdn2.unrealengine.com/egs-godofwar-santamonicastudio-ic1-400x400-5819bbf696c5.png?h=270&resize=1&w=480")
],
),
),
),
);
}
Widget buildRichText(List<InlineSpan> richSpan) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(5),
color: isLight ? Color(0xffF0F0F0) : Color(0xff808080),
child: Column(
children: [
RichText(
text: TextSpan(
children: richSpan,
),
),
],
));
}
}
'Source code or Tip > Flutter & Dart' 카테고리의 다른 글
[중요에러] Incorrect use of ParentDataWidget Error in Flutter (0) | 2022.10.26 |
---|---|
[flutter] Column의 children에 배열추가하기 (0) | 2022.10.24 |
[Flutter] Flutter에서 GoogleFonts 사용하기 (0) | 2022.10.19 |
[Flutter] 부분갱신을 위한 Stateful과 GlobalKey (0) | 2022.10.14 |
[Flutter] custom Dialog에서 Dialog 호출시 주의점. - ShowModalBottomSheet (0) | 2022.10.02 |