본문 바로가기
개발(Development)/Flutter

Flutter 위젯 시리즈 003 – `Text` 위젯 완전 이해하기

by GeekCode 2025. 7. 8.
반응형

 

Flutter 위젯 시리즈 003 – Text 위젯 완전 이해하기

🗂️ Widget Catalog Index

├ Basics  
│   └ ✅ Text ← 현재 문서  
├ Layout  
├ Input  
├ Text  
│   └ ✅ Text ← 현재 문서  
...
└ Accessibility  

※ 이 위젯은 공식적으로는 Text 카테고리에 속해있지만, 워낙 기본적인 위젯이라 Basics 섹션에도 함께 포함되어 있어요.


Widget Catalog에는

누락된 위젯들도 간혹 있어서,

 

향후 정리하면서

기준을 더 잡아갈 예정입니다.

 


지난 글에서 CenterColumn을 통해

 

Flutter 레이아웃의 기본기를 익혀봤습니다.

 


이번엔

그 안에 들어가는

가장 중요한 구성 요소 중 하나,

 

바로 텍스트(Text) 위젯을 파헤쳐볼 차례예요.

 

앱 화면을 만들다 보면

어느새 화면 가득 텍스트가

채워져 있는 걸 보게 돼요.

 


버튼, 라벨, 안내 메시지,

심지어 로딩 중 문구까지

모두 텍스트죠.

 


"그냥 글자 하나 넣는 거 아냐?"

 

라고 생각하기 쉽지만,

 

그 텍스트가 어디에 어떻게 배치되는지가 사용자 경험을 좌우하곤 해요.

 

 

Text 위젯, 왜 중요한가요?

 

 

Text는 너무 기본적이어서

 

놓치기 쉬운 위젯인데요,

 


한 줄의 글자를 띄우는 걸 넘어

다양한 스타일

줄 수 제어

선택 가능성

상호작용 처리까지 —

 

의외로 다룰 수 있는 영역이 꽤 넓습니다.

 

 

사실 Text 하나만 제대로 이해해도

 

UI 구성의 80%는

해결된다고 해도 과언이 아닙니다.

 

 

 

특히 디자이너가 전달한 시안에 있는

‘폰트 굵기’, ‘색상 강조’, ‘중앙 정렬’ 같은

스타일을 실제로 구현하려면

Text 위젯의 속성을

이해하고 있어야 당황하지 않아요.

 

 

이 글에서는 Text 위젯의 핵심 속성과

다양한 예제를 통해


실제 앱에서

어떤 식으로 활용할 수 있는지

자연스럽게 익혀볼 거예요.

 

⚙️ 어떻게 동작할까?

  • Text('문자열') 형태로 간단하게 쓸 수 있어요.
  • 별도로 style을 지정하지 않으면, 상위 위젯에서 제공하는 DefaultTextStyle을 따라갑니다.
  • 줄 수 제한, 넘침 처리, 줄바꿈 등은 maxLines, overflow, softWrap으로 제어할 수 있어요.
  • 다양한 스타일을 한 문장에 혼합하고 싶다면 Text.rich() 생성자를 사용해야 합니다.
  • 선택은 기본적으로 불가능하지만, SelectableText 또는 SelectionArea로 감싸면 가능해져요.

 

 

 


생성자 종류 – 기본 vs rich

텍스트가 한 가지 스타일이라면

 

기본 생성자로 충분하지만,

 

 


같은 문장 안에서

 

특정 단어만 굵게, 기울임 등

 

스타일을 다르게 줘야 할 땐

 

어떻게 해야 할까요?

 


바로 이럴 때 Text.rich()를 사용합니다.

 

 

✅ 기본 생성자

Text(
  'Hello World',
  style: TextStyle(fontSize: 16, color: Colors.black),
  textAlign: TextAlign.center,
  maxLines: 2,
  overflow: TextOverflow.ellipsis,
)

 

 

 

✅ 스타일 혼합이 필요할 땐 Text.rich

Text.rich(
  TextSpan(
    text: 'Hello',
    children: [
      TextSpan(
        text: ' beautiful ',
        style: TextStyle(fontStyle: FontStyle.italic),
      ),
      TextSpan(
        text: 'world',
        style: TextStyle(fontWeight: FontWeight.bold),
      ),
    ],
  ),
)

 

 

Text.rich()는 내부적으로

 

RichText를 wrapping한 형태입니다.


한 문장 내에서

여러 스타일을 섞고 싶다면

이 방법이 가장 자연스럽습니다.

 

 

 

 

 


🧩 주요 속성 간단 정리

속성 설명
style 텍스트 스타일 (색상, 크기 등)
textAlign 텍스트 정렬 방식
maxLines 최대 줄 수 제한
overflow 넘칠 경우 처리 방식 (ellipsis, fade 등)
softWrap 줄바꿈 허용 여부
textScaler 텍스트 크기 조절 방식 (textScaleFactor는 deprecated)

maxLines: 0으로 설정하면 아무 텍스트도 표시되지 않는다.
줄 수 제한이 없게 하려면 maxLines를 생략하거나 null로 설정해야 한다.

텍스트가 컨테이너보다 넘칠 경우 overflow 속성 없이 기본 상태라면
다음 줄로 줄바꿈(wrapping) 된다. 하지만 maxLines가 설정되어 있고 넘친다면,
overflow 속성에 따라 ellipsis(...), fade, clip 등의 방식으로 처리된다.

 

 

 

 


🧪 Sample Code

 

 

예제 1: 기본 텍스트 출력

Text('Hello Flutter!')

→ 별도 스타일 지정이 없으면 DefaultTextStyle을 따라갑니다.


보통은 MaterialApp, Scaffold에서 설정된 스타일이에요.

 

 

 

 


예제 2: 스타일 지정 (style)

Text(
  'Styled Text',
  style: TextStyle(
    color: Colors.blue,
    fontSize: 20,
    fontWeight: FontWeight.bold,
  ),
)

→ 텍스트 색상, 크기, 굵기 등을 세밀하게 설정 가능

 

 

 


예제 3: 정렬 방식 지정 (textAlign)

Text(
  'Aligned Text',
  textAlign: TextAlign.center,
)

left, right, center, justify 등 다양한 정렬 제공

 

 

 

 


예제 4: 줄 수 제한 + 넘침 처리 (maxLines, overflow)

Text(
  'Hello $_name, how are you?',
  maxLines: 1,
  overflow: TextOverflow.ellipsis,
)

→ 텍스트가 길어질 경우 생략(...) 처리

 

 

 


예제 5: 줄바꿈 비허용 (softWrap: false)

Text(
  'This text will not wrap to the next line.',
  softWrap: false,
  overflow: TextOverflow.fade,
)

→ 줄바꿈 없이 한 줄에 유지하면서 fade로 처리

 

 

 

 


예제 6: 스타일 혼합 (Text.rich)

Text.rich(
  TextSpan(
    text: 'Hello',
    children: [
      TextSpan(
        text: ' beautiful ',
        style: TextStyle(fontStyle: FontStyle.italic),
      ),
      TextSpan(
        text: 'world',
        style: TextStyle(fontWeight: FontWeight.bold),
      ),
    ],
  ),
)

→ 하나의 문장 안에서 다양한 스타일을 표현할 때 유용

 

 

 

 


텍스트 비교

아래 예제는

여러 종류의 텍스트 속성을

한 화면에서 비교하기 위한 구성입니다.


특히 줄 수 제한

생략(overflow)

줄바꿈(softWrap) 여부를

 

시각적으로 확인할 수 있도록 구성해봤어요.

return  Scaffold(
  body: SafeArea(
    child: Center(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [

          Text('기본 텍스트'),
          SizedBox(height: 8),

          Text(
            '파란색 + 크기 20 + Bold',
            style: TextStyle(color: Colors.blue, fontSize: 20, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 8),

          Text(
            '한 줄만, 넘치면 말줄임표 (ellipsis 처리)',
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
          SizedBox(height: 8),

          Text(
            '줄바꿈 없이 fade 처리됨 - softWrap: false',
            softWrap: false,
            overflow: TextOverflow.fade,
          ),
          SizedBox(height: 8),

          Text.rich(
            TextSpan(
              text: 'Hello',
              children: [
                TextSpan(
                  text: ' beautiful ',
                  style: TextStyle(fontStyle: FontStyle.italic),
                ),
                TextSpan(
                  text: 'world!',
                  style: TextStyle(fontWeight:FontWeight.bold),
                ),
              ],
            ),
          ),
          SizedBox(height: 16),

          Divider(),

          Text(
            '✅ 줄바꿈 테스트 (기본)',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          Text(
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
          ),
          SizedBox(height: 12),

          Text(
            '✅ 줄 수 제한 + ellipsis\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(color: Colors.red),
          )
        ],
      ),
    )
  )
);

 

 

스크린샷

 

 

 

 

 


🖱️ 선택과 상호작용

 

우리가 앱을 쓰다가

텍스트를 길게 눌러 복사하거나,

어떤 문장을 눌렀을 때

동작하길 기대할 때가 있죠?

 

우리는 이제 경험상

"이럴 땐 이렇게 동작해야하는거 아니야?"

하는 생각이 든다는 거죠.. 

 

기본 Text 위젯은

이런 인터랙션이 없습니다.

 

단순히 텍스트를 누르면

반응하는 UI를 만들고 싶다면

GestureDetector 를 사용할 수 있어요.

 

아래 예시는 텍스트를 눌렀을 때 콘솔에 "Text tapped!" 라는 로그를 출력합니다.


단, 이 방식은 텍스트 선택 기능을 제공하진 않아요.

블록지정을 할 수 없다는 말이에요.

GestureDetector(
  onTap: () {
    print("Text tapped!");
  },
  child: Text('Tap Me'),
)

 

 

 

만약 선택 가능한 텍스트를 만들고 싶다면

 

다음과 같은 위젯을 사용할 수 있어요

  • SelectionArea: 여러 개의 텍스트 위젯을 감싸서 영역 전체를 선택할 수 있어요.
  • SelectableText: 단일 텍스트를 선택 가능하게 만들어주는 위젯.
    ⚠️ iOS에서는 SelectableText 단독 사용 시 시스템 context menu와 충돌로 인해 에러가 발생할 수 있으므로, 가능한 SelectionArea로 감싸는 방식이 더 안정적입니다.

 

 SelectableText는 사용하기가

 

굉장히 쉬운 초기 배포된 위젯인데요. 

 

`SelectableText('이렇게 쉬워요')`

 

 

 

 

iOS폰에서 절대절대 사용하지 않겠다면 모르겠지만 

 

 

만약 모르고 빌드한다음

여기에 손을 대고 있으면

빨간 에러 화면이 뜨니까...  

 

그냥 사용하지 않는게 좋겠죠???

텍스트를 눌렀는데

 

이런 화면이 나온다고 생각해보세요... ㅗㅜ

 

바로 앱 지울 거 같네요

 

 

그렇다고 대체가능한 SelectionArea가

 

사용하기 막 어려운 것도 아니에요.

 

Column 사용법과 동일합니다.

 

편의상 여러개를

한번에 나열하기 위해

Column  을 사용했어요.

 

SelectionArea(
  child: Column(
    children: [
      Text('이 텍스트는'),
      Text('모두 선택 가능!'),
    ],
  ),
)

// 혹은  
SelectionArea(
  child: Column(
    children: [
      Text('이 텍스트도 선택 가능'),
    ],
  ),
),

SelectionArea(
  child: Text('단일 텍스트'),
)

 

 

 


🧭 관련 위젯

  • RichText: 텍스트 스타일을 더 세밀하게 조절하고 싶을 때
  • SelectableText: 사용자가 텍스트를 드래그해 복사할 수 있도록
  • TextButton: 클릭 가능한 텍스트 버튼
  • DefaultTextStyle: 하위 Text에 기본 스타일을 지정
  • TextStyle: 스타일 지정의 핵심 클래스

 


🧾 마무리

이 글에서는 Flutter의 핵심 위젯인

 

Text에 대해 구조부터 속성, 예제까지 다뤄봤어요.

 

 

 


단순히 텍스트를 보여주는 걸 넘어,

 

다양한 상황에서

 

세밀하게 제어할 수 있는 위젯이라는 걸

 

알 수 있었죠.

 

 

 


작지만 강력한 Text 위젯을

 

자유자재로 다룰 수 있어야

 

Flutter UI 개발이 훨씬 수월해져요.

 

 


 

 

다음 글에서는

 

ElevatedButton 위젯을 다루며,

 

버튼의 기본 구조와 스타일링 방법까지

 

알아볼 예정입니다.

 


궁금한 점이나 다뤄줬으면 하는 예제가 있다면 댓글로 남겨주세요 :)

반응형