개요
Text는 스타일이 지정된 텍스트를 표시하는 기본 위젯입니다.
Text 위젯은 단일 스타일의 텍스트를 표시합니다. 문자열은 여러 줄에 걸쳐 표시되거나 레이아웃 제약에 따라 한 줄에 모두 표시될 수 있습니다. style 속성을 사용하여 텍스트의 모양을 사용자 정의할 수 있습니다. 여러 스타일을 사용해야 하는 경우 Text.rich 생성자를 사용하거나 RichText 위젯을 직접 사용할 수 있습니다.
언제 사용하나요?
- 화면에 텍스트를 표시할 때
- 제목, 본문, 레이블 등을 표시할 때
- 단일 스타일의 텍스트가 필요할 때
- 텍스트 오버플로우 처리가 필요할 때
- 텍스트 정렬이 필요할 때
기본 사용법
// 기본 텍스트
Text('안녕하세요, Flitter!')
// 스타일이 적용된 텍스트
Text('스타일 텍스트', {
style: TextStyle({
fontSize: 24,
fontWeight: 'bold',
color: 'blue'
})
})
// 여러 스타일을 가진 텍스트 (Text.rich)
Text.rich(
TextSpan({
text: '안녕하세요 ',
children: [
TextSpan({
text: 'Flitter',
style: TextStyle({ color: 'blue', fontWeight: 'bold' })
}),
TextSpan({ text: '!' })
]
})
)
생성자
Text(data, props?)
기본 생성자로 단일 스타일의 텍스트를 생성합니다.
Text('기본 텍스트')
Text('스타일 텍스트', { style: TextStyle({ fontSize: 18 }) })
Text.rich(textSpan, props?)
여러 스타일을 가진 텍스트를 생성합니다.
Text.rich(
TextSpan({
text: '기본 텍스트 ',
style: TextStyle({ fontSize: 16 }),
children: [
TextSpan({
text: '강조된 텍스트',
style: TextStyle({ fontWeight: 'bold', color: 'red' })
})
]
})
)
Props
style
값: TextStyle | undefined
텍스트의 스타일을 정의합니다. null인 경우 기본 텍스트 스타일이 사용됩니다.
Text('스타일 텍스트', {
style: TextStyle({
fontSize: 20,
fontWeight: 'bold',
color: '#333333'
})
})
textAlign
값: TextAlign | undefined
텍스트의 가로 정렬을 정의합니다.
사용 가능한 값:
TextAlign.left
: 왼쪽 정렬TextAlign.right
: 오른쪽 정렬TextAlign.center
: 가운데 정렬TextAlign.justify
: 양쪽 정렬TextAlign.start
: 시작 방향 정렬 (LTR에서는 왼쪽)TextAlign.end
: 끝 방향 정렬 (LTR에서는 오른쪽)
Text('가운데 정렬된 텍스트', {
textAlign: TextAlign.center
})
overflow
값: TextOverflow | undefined
텍스트가 공간을 초과할 때의 처리 방법입니다.
사용 가능한 값:
TextOverflow.clip
: 잘라냄 (기본값)TextOverflow.fade
: 페이드 아웃TextOverflow.ellipsis
: 말줄임표(…) 표시TextOverflow.visible
: 오버플로우 허용
Text('아주 긴 텍스트가 여기에 표시됩니다...', {
overflow: TextOverflow.ellipsis
})
softWrap
값: boolean | undefined (기본값: true)
텍스트가 줄바꿈될지 여부를 결정합니다.
Text('긴 텍스트는 자동으로 줄바꿈됩니다', {
softWrap: true // 줄바꿈 허용
})
Text('이 텍스트는 한 줄에만 표시됩니다', {
softWrap: false // 줄바꿈 금지
})
textDirection
값: TextDirection | undefined
텍스트의 방향을 지정합니다.
사용 가능한 값:
TextDirection.ltr
: 왼쪽에서 오른쪽TextDirection.rtl
: 오른쪽에서 왼쪽
Text('مرحبا بالعالم', {
textDirection: TextDirection.rtl
})
textWidthBasis
값: TextWidthBasis | undefined
텍스트 너비 계산 방식을 정의합니다.
사용 가능한 값:
TextWidthBasis.parent
: 부모 너비 기준 (기본값)TextWidthBasis.longestLine
: 가장 긴 줄 기준
Text('여러 줄의\n텍스트', {
textWidthBasis: TextWidthBasis.longestLine
})
TextStyle 속성
TextStyle은 텍스트의 시각적 속성을 정의합니다.
color
값: string | undefined
텍스트 색상입니다.
TextStyle({ color: 'blue' })
TextStyle({ color: '#FF5733' })
TextStyle({ color: 'rgba(255, 0, 0, 0.5)' })
fontSize
값: number | undefined
글꼴 크기입니다 (픽셀 단위).
TextStyle({ fontSize: 16 }) // 16px
TextStyle({ fontSize: 24 }) // 24px
fontWeight
값: string | undefined
글꼴 두께입니다.
사용 가능한 값:
'normal'
또는'400'
'bold'
또는'700'
'100'
~'900'
(100 단위)
TextStyle({ fontWeight: 'bold' })
TextStyle({ fontWeight: '600' })
fontStyle
값: FontStyle | undefined
글꼴 스타일입니다.
사용 가능한 값:
FontStyle.normal
: 일반FontStyle.italic
: 이탤릭
TextStyle({ fontStyle: FontStyle.italic })
fontFamily
값: string | undefined
사용할 글꼴 패밀리입니다.
TextStyle({ fontFamily: 'Roboto' })
TextStyle({ fontFamily: 'Arial, sans-serif' })
height
값: number | undefined
줄 높이를 글꼴 크기의 배수로 지정합니다.
TextStyle({
fontSize: 16,
height: 1.5 // 줄 높이는 24px (16 * 1.5)
})
inherit
값: boolean (기본값: true)
부모의 텍스트 스타일을 상속할지 여부입니다.
TextStyle({
inherit: false, // 부모 스타일 무시
fontSize: 20
})
실제 사용 예제
예제 1: 제목과 본문
const ArticleHeader = () => {
return Column({
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Flutter에서 Flitter로', {
style: TextStyle({
fontSize: 28,
fontWeight: 'bold',
color: '#1a1a1a'
})
}),
SizedBox({ height: 8 }),
Text('JavaScript로 Flutter 앱을 만드는 새로운 방법', {
style: TextStyle({
fontSize: 16,
color: '#666666',
height: 1.5
})
}),
SizedBox({ height: 4 }),
Text('2024년 1월 10일 • 5분 읽기', {
style: TextStyle({
fontSize: 14,
color: '#999999'
})
})
]
});
};
예제 2: 말줄임표가 있는 카드
const ProductCard = ({ title, description, price }) => {
return Container({
padding: EdgeInsets.all(16),
decoration: BoxDecoration({
color: 'white',
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow({
color: 'rgba(0, 0, 0, 0.1)',
blurRadius: 4,
offset: { x: 0, y: 2 }
})
]
}),
child: Column({
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, {
style: TextStyle({
fontSize: 18,
fontWeight: 'bold'
}),
overflow: TextOverflow.ellipsis
}),
SizedBox({ height: 8 }),
Text(description, {
style: TextStyle({
fontSize: 14,
color: '#666666',
height: 1.4
}),
overflow: TextOverflow.ellipsis,
softWrap: true
}),
SizedBox({ height: 12 }),
Text(`₩${price.toLocaleString()}`, {
style: TextStyle({
fontSize: 20,
fontWeight: 'bold',
color: '#FF5733'
})
})
]
})
});
};
예제 3: 스타일이 혼합된 텍스트
const TermsText = () => {
return Text.rich(
TextSpan({
text: '계속하시면 저희 ',
style: TextStyle({ fontSize: 14, color: '#666' }),
children: [
TextSpan({
text: '이용약관',
style: TextStyle({
color: 'blue',
fontWeight: 'bold'
})
}),
TextSpan({ text: ' 및 ' }),
TextSpan({
text: '개인정보 처리방침',
style: TextStyle({
color: 'blue',
fontWeight: 'bold'
})
}),
TextSpan({ text: '에 동의하는 것으로 간주됩니다.' })
]
})
);
};
예제 4: 채팅 메시지
const ChatMessage = ({ message, isMe, time }) => {
return Container({
margin: EdgeInsets.symmetric({ horizontal: 16, vertical: 4 }),
alignment: isMe ? Alignment.centerRight : Alignment.centerLeft,
child: Container({
padding: EdgeInsets.symmetric({ horizontal: 12, vertical: 8 }),
decoration: BoxDecoration({
color: isMe ? '#007AFF' : '#E5E5EA',
borderRadius: BorderRadius.circular(18)
}),
constraints: Constraints({ maxWidth: 250 }),
child: Column({
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(message, {
style: TextStyle({
fontSize: 16,
color: isMe ? 'white' : 'black'
})
}),
SizedBox({ height: 2 }),
Text(time, {
style: TextStyle({
fontSize: 12,
color: isMe ? 'rgba(255, 255, 255, 0.7)' : '#999999'
})
})
]
})
})
});
};
예제 5: 가격 표시
const PriceDisplay = ({ originalPrice, salePrice, discountRate }) => {
return Row({
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
if (originalPrice !== salePrice) ...[
Text(`₩${originalPrice.toLocaleString()}`, {
style: TextStyle({
fontSize: 14,
color: '#999999',
decoration: 'line-through'
})
}),
SizedBox({ width: 8 })
],
Text(`₩${salePrice.toLocaleString()}`, {
style: TextStyle({
fontSize: 24,
fontWeight: 'bold',
color: '#1a1a1a'
})
}),
if (discountRate > 0) ...[
SizedBox({ width: 8 }),
Text(`${discountRate}%`, {
style: TextStyle({
fontSize: 18,
fontWeight: 'bold',
color: '#FF5733'
})
})
]
]
});
};
주의사항
- overflow 속성은 softWrap이 false이거나 텍스트가 한 줄로 제한될 때 가장 효과적입니다.
- fontFamily를 사용할 때는 해당 폰트가 시스템에 설치되어 있거나 앱에 포함되어 있어야 합니다.
- height는 줄 간격을 조정하는 데 사용되며, fontSize의 배수로 작동합니다.
- Text.rich를 사용할 때 기본 style은 모든 TextSpan에 상속됩니다 (inherit가 true인 경우).
관련 위젯
- RichText: 더 복잡한 텍스트 스타일링이 필요한 경우
- TextField: 사용자 입력을 받을 때
- SelectableText: 선택 가능한 텍스트가 필요한 경우
- DefaultTextStyle: 하위 트리의 기본 텍스트 스타일을 정의할 때