SelectableText class
단일 스타일을 적용한 선택 가능한 텍스트입니다.
대신 SelectionArea 또는 SelectableRegion을 사용하는 것을 고려해 보세요. 이는 텍스트 위젯을 포함하되 이에 국한되지 않는 위젯 하위 트리에서 선택을 가능하게 합니다.
SelectableText 위젯은 단일 스타일로 텍스트 문자열을 표시합니다. 레이아웃 제약 조건에 따라 문자열은 여러 줄에 걸쳐 표시되거나 모두 한 줄에 표시될 수 있습니다.
공식 문서 코드
폰에서 뉴스 기사나 그런 것을 볼 때 간혹 그 텍스트를 복사하려고 할 때가 생긴다. 그럴 때에는 텍스트를 꾹- 하고 누르면 선택이 되면서 복사할 수 있는 콘텍스트 메뉴(Context menu) 가 나오게 되는데 기본적으로 Flutter 에서 많이 사용하는 텍스트는 Text 위젯을 사용하여 추가 처리를 하지 않는 이상 상호작용이 불가능하다. 여기서 그러한 텍스트가 선택이 될 수 있도록 도와주는 위젯이 있는데 바로 SelectableText 이다.
이 SelectableText 위젯은 사용자가 텍스트를 선택(드래그)할 수 있도록 해주는 위젯이다. 기본적인 Text 위젯과 다르게 SelectableText 는 텍스트 복사 기능을 지원한다. 한번 알아보자.
하위 속성
| 속성명 | 타입 | 기본값 | 설명 |
| data | String? | – | 표시할 텍스트 내용 |
| textSpan | TextSpan? | – | 텍스트를 스타일링하여 표시할 때 사용하는 TextSpan 객체 |
| focusNode | FocusNode? | – | 이 위젯의 포커스를 제어하는 노드 |
| style | TextStyle? | – | 텍스트에 적용할 스타일 |
| strutStyle | StrutStyle? | – | 텍스트 줄 높이를 설정하는 스타일 |
| textAlign | TextAlign? | – | 텍스트의 정렬 방식 |
| textDirection | TextDirection? | – | 텍스트의 방향 |
| textScaler | TextScaler? | – | 텍스트 크기를 조정하는 객체 |
| showCursor | bool | false | 커서를 표시할지 여부 |
| autofocus | bool | false | 위젯이 자동으로 포커스를 받을지 여부 |
| minLines | int? | – | 표시할 최소 줄 수 |
| maxLines | int? | – | 표시할 최대 줄 수 |
| cursorWidth | double | 2.0 | 커서의 너비 |
| cursorHeight | double? | – | 커서의 높이 |
| cursorRadius | Radius? | – | 커서의 모서리 반경 |
| cursorColor | Color? | – | 커서의 색상 |
| selectionHeightStyle | ui.BoxHeightStyle | tight | 선택 영역의 높이 스타일 |
| selectionWidthStyle | ui.BoxWidthStyle | tight | 선택 영역의 너비 스타일 |
| enableInteractiveSelection | bool | true | 사용자가 텍스트를 상호작용적으로 선택할 수 있는지 여부 |
| selectionControls | TextSelectionControls? | – | 선택 도구 컨트롤 설정 |
| dragStartBehavior | DragStartBehavior | start | 드래그 시작 동작 방식 |
| onTap | GestureTapCallback? | – | 텍스트가 탭되었을 때 호출되는 콜백 |
| scrollPhysics | ScrollPhysics? | – | 스크롤 물리 속성 |
| scrollBehavior | ScrollBehavior? | – | 스크롤 동작 정의 |
| semanticsLabel | String? | – | 접근성용 설명 텍스트 |
| textHeightBehavior | TextHeightBehavior? | – | 텍스트 높이 동작 정의 |
| textWidthBasis | TextWidthBasis? | – | 텍스트 너비 기준 |
| onSelectionChanged | SelectionChangedCallback? | – | 텍스트 선택 상태가 변경될 때 호출되는 콜백 |
| contextMenuBuilder | EditableTextContextMenuBuilder? | _defaultContextMenuBuilder | 컨텍스트 메뉴를 빌드하는 함수 |
| magnifierConfiguration | TextMagnifierConfiguration? | – | 텍스트 선택 시 확대경 설정 |
하위 속성이 꽤 많다만 걱정할 필요 없다. 막상 사용하는 건 별로 없으니까
사용하는 방법은 Text 위젯과 거의 90퍼센트(기능적인 부분) 똑같다고 보면 된다.
SelectableText(
'Hello! How are you?',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold),
)
자 일단 이게 끝인데 그냥 위젯 이름을 Text 로 바꿔도 아무 문제없을 것이다.
그래서 이 부분에 대해서는 굳이 설명할 필요는 없다고 생각하고 넘기겠다.
그렇다면 주목해야 할 부분은 어디에 있는가?
바로 선택 시 뜨게 되는 Context menu 에 있다고 할 수 있겠다.

기본적으로 선택 시 우리가 흔히 보는 그 디자인의 그 창이 나오게 된다.
근데 놀랍게도 이 콘텍스트 메뉴를 마음대로 조물딱 할 수 있다는 것인데 바로 contextMenuBuilder 를 사용하면 그것이 가능해지게 된다. 한번 공식 예제를 봐보자. (데스크탑일 시 그냥 우클릭으로 하면 바로 나온다.)
놀랍게도 커스텀으로 제작이 가능하다.
자신의 앱의 콘셉트를 맞추고 싶다거나 할 때 굉장히 유용하게 사용될 듯싶은데 위의 예제는 contextMenuBuilder 자체의 예제라 SelectableText 를 사용하지 않고 있다. 한번 이 위젯과 커스텀 위젯을 결합시켜 보도록 하겠다.
좀 하자가 있게 코드를 짜서 테스트크탑에서 잘 안 되는 것 같긴 한데 모바일에서는 잘 되니 넘어가주길 바란다.

자 암튼 이렇게 직접 커스텀으로 아이템을 넣어줄 수가 있는데 한번 사용법을 알아보자면
contextMenuBuilder: (BuildContext context, EditableTextState editableTextState) {
final List<ContextMenuButtonItem> buttonItems = editableTextState.contextMenuButtonItems;
return AdaptiveTextSelectionToolbar.buttonItems(
anchors: editableTextState.contextMenuAnchors,
buttonItems: [
...buttonItems,
ContextMenuButtonItem(
label: '커스텀 액션',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('커스텀 액션이 실행되었습니다!')),
);
},
),
],
);
},
현재 이 코드에서 먼저 contextMenuBuilder 를 먼저 봐보자.
contextMenuBuilder: (BuildContext context, EditableTextState editableTextState) {
당연하겠지만 contextMenuBuilder 는 사용자가 텍스트를 선택했을 때 호출이 되는 형식이다.
여기서 editableTextState 라는 인자값을 주는데 이걸로 메뉴 생성에 필요한 텍스트 상태 관리가 가능해지게 된다.
final List<ContextMenuButtonItem> buttonItems = editableTextState.contextMenuButtonItems;
buttonItems 라는 이름으로 무언갈 가져오고 있는데 바로 기본으로 제공되는 ContextMenu 버튼 아이템들을 가져오고 있는 것이다. 이것으로 복사, 잘라내기, 붙여 넣기 같은 아이템을 불러왔다.
이제 빌더함수니까 return 을 해줘야 하는데 AdaptiveTextSelectionToolbar 로 해줬다.
return AdaptiveTextSelectionToolbar.buttonItems(
이 AdaptiveTextSelectionToolbar 위젯은 플랫폼에 맞게 context menu toolbar 를 그려주는 위젯이 되겠다.
이 위젯의 필수 속성인 anchors 를 사용해야 하는데
anchors: editableTextState.contextMenuAnchors,
그냥 editableTextState.contextMenuAnchors 를 사용해 줘서 툴 바가 어디에 표시될지 결정해 줬다.
이제 아래에는 마찬기로 필수 속성인 buttonItems 를 사용하여 툴바에 넣을 아이템들을 표시해 줬다.
buttonItems: [
...buttonItems, // 위에서 만든 변수
ContextMenuButtonItem( // 새 아이템
label: '커스텀 액션',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('커스텀 액션이 실행되었습니다!')),
);
},
),
],
일단 기본적인 디자인을 따르도록 완전한 커스텀이 아닌 ContextMenuButtonItem 을 사용하여서 쉽고 간편하게 아이템을 하나 더 추가해 주었다.
이렇게 SelectableText 위젯에 대해서 알아보았다마는 중간에 살짝 길이 새버린 것 같긴 하다. 하지만 뭐 애초에 선택되는 게 끝인 위젯인데 뭐가 더 있겠는가 암튼 도움이 되었길 바라며 마치겠다.