티스토리 뷰
Flutter에서 텍스트 필드의 변화에 따라 특정 동작을 실행하는 것은 매우 유용한 기능입니다. 특히, 검색 화면에서 입력 중 자동 완성 기능을 구현하거나, 입력 값에 따라 실시간으로 결과를 업데이트할 때 필수적인 요소입니다. 이 글에서는 onChanged
콜백과 TextEditingController
를 통해 Flutter에서 텍스트 필드의 변화를 감지하는 방법을 알아봅니다.
참고. Handle changes to a text field
Flutter 텍스트 필드 변경 사항을 감지하는 두 가지 방법
1. onChanged
콜백 사용하기
onChanged
콜백은 가장 간단한 방법으로, 사용자가 텍스트 필드에 입력을 할 때마다 즉시 호출됩니다. 이 콜백은 TextField
나 TextFormField
위젯에 직접 추가할 수 있습니다.
TextField(
onChanged: (text) {
print('현재 텍스트: $text (길이: ${text.characters.length})');
},
),
위 코드처럼 onChanged
콜백에 함수를 전달하면, 사용자가 입력할 때마다 해당 함수가 호출됩니다. 예를 들어, 입력된 텍스트를 실시간으로 확인할 수 있어 자동 완성 기능이나 필터링 기능을 구현할 때 유용합니다.
onChanged
콜백의 장점
- 간단하고 빠름: 구현이 매우 간단하고 텍스트 입력과 동시에 즉각적으로 콜백이 실행됩니다.
- 초기 설정 불필요: 추가적인 컨트롤러나 리스너 설정 없이도 바로 사용할 수 있습니다.
onChanged
콜백의 단점
- 제어 범위 한정: 입력된 텍스트 외의 복잡한 상태 변화를 감지하기 어려우며, 고급 기능이 필요한 경우에는 다소 한정적입니다.
2. TextEditingController
사용하기
좀 더 정교한 제어가 필요할 때는 TextEditingController
를 사용합니다. TextEditingController
는 텍스트 필드의 상태를 지속적으로 추적할 수 있어, 텍스트 변화를 감지하고 다른 로직을 실행하기에 적합합니다. 다음과 같은 단계로 설정할 수 있습니다.
단계 1: TextEditingController
생성
TextEditingController
를 생성하고 이를 상태로 관리합니다.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
State<MyCustomForm> createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
final myController = TextEditingController();
@override
void dispose() {
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
controller: myController,
);
}
}
주의:
TextEditingController
는 상태가 사라질 때 반드시dispose()
메서드를 호출하여 정리해야 합니다. 이를 통해 메모리 누수를 방지할 수 있습니다.
단계 2: TextEditingController
를 텍스트 필드에 연결하기
이제 생성된 TextEditingController
를 TextField
의 controller
속성에 연결합니다. 이를 통해 텍스트 필드의 내용을 추적하고 조작할 수 있습니다.
TextField(
controller: myController,
),
단계 3: 변경 사항을 감지하고 함수 실행하기
텍스트 변경 시 호출될 함수를 정의하고, TextEditingController
의 addListener()
메서드를 사용해 이 함수를 연결합니다.
void _printLatestValue() {
print('변경된 텍스트: ${myController.text} (길이: ${myController.text.characters.length})');
}
@override
void initState() {
super.initState();
myController.addListener(_printLatestValue);
}
이제 사용자가 텍스트 필드에 입력할 때마다 _printLatestValue
함수가 호출되어 최신 텍스트와 그 길이를 출력하게 됩니다.
TextEditingController
의 장점
- 강력한 제어: 텍스트 필드의 변화를 정교하게 추적하고 필요한 로직을 실행할 수 있습니다.
- 유연한 기능 구현: 텍스트 필드의 상태를 쉽게 가져와 다른 로직에 활용할 수 있습니다.
TextEditingController
의 단점
- 설정의 복잡성:
onChanged
콜백에 비해 설정이 다소 복잡합니다. - 메모리 관리 필요: 컨트롤러를 명시적으로 해제하지 않으면 메모리 누수가 발생할 수 있습니다.
Flutter에서 텍스트 필드 변경 감지의 활용 예시
검색 기능과 자동 완성
onChanged
콜백이나 TextEditingController
를 사용하여 검색어가 입력될 때마다 필터링된 결과를 실시간으로 보여줄 수 있습니다. 사용자 입력에 맞춰 검색 결과를 업데이트하는 UX는 검색 기능에서 유용하게 적용됩니다.
입력 필터링과 유효성 검사
실시간으로 입력된 텍스트를 감지하여 조건에 맞지 않는 입력을 필터링하거나, 잘못된 입력이 있을 때 경고 메시지를 표시할 수 있습니다. 예를 들어, 이메일 형식이 올바른지 확인하거나 특정 문자열이 포함되었는지 감지할 때 유용합니다.
입력 제한 기능
사용자가 입력한 텍스트의 길이를 제한하거나 특정 조건을 만족하지 않으면 알림을 표시할 수 있습니다. 이를 통해 불필요한 입력 오류를 방지하고, 사용자에게 유효한 입력을 유도할 수 있습니다.
결론
Flutter에서 텍스트 필드 변경 사항을 감지하는 것은 앱의 동적 기능을 구현하는 데 필수적인 요소입니다. onChanged
콜백과 TextEditingController
는 각각 장단점이 있어, 간단한 경우에는 onChanged
를, 더 정교한 제어가 필요한 경우에는 TextEditingController
를 선택하여 활용하는 것이 좋습니다. 실시간으로 반응하는 UI를 통해 사용자에게 향상된 경험을 제공하세요.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
State<MyCustomForm> createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the Form.
class _MyCustomFormState extends State<MyCustomForm> {
// Create a text controller and use it to retrieve the current value
// of the TextField.
final myController = TextEditingController();
@override
void initState() {
super.initState();
// Start listening to changes.
myController.addListener(_printLatestValue);
}
@override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
void _printLatestValue() {
final text = myController.text;
print('Second text field: $text (${text.characters.length})');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
TextField(
onChanged: (text) {
print('First text field: $text (${text.characters.length})');
},
),
TextField(
controller: myController,
),
],
),
),
);
}
}
'Flutter Cookbook' 카테고리의 다른 글
플러터로 게임 리더보드와 업적 시스템 구축하기 (0) | 2024.11.07 |
---|---|
Flutter에서 텍스트 필드 입력값 가져오기: TextEditingController 활용법 (2) | 2024.11.07 |
Flutter에서 텍스트 필드 포커스 관리하기: 효과적인 사용자 경험 만들기 (2) | 2024.11.05 |
Flutter에서 텍스트 입력 필드 구현 및 스타일링 방법 (1) | 2024.11.04 |
Flutter 폼 유효성 검증: 쉽게 구현하는 방법 (1) | 2024.11.03 |