
UI에 반영되는 변경되는 데이터
class MyWidget extends StatefulWidget {
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// 상태 변수
int counter = 0;
// UI 로직
void _increment() {
// setState에 익명함수 넘겨주면 해당 함수 호출하고
// build 메서드 재호출됨 -> 화면에 반영
setState(() {
counter++;
});
}
Widget build(BuildContext context) {
return Text('Count: $counter');
}
}

| 메서드 이름 | 호출 시점 및 조건 | 주요 역할 |
|---|---|---|
| createState() | StatefulWidget이 처음 생성될 때 | State 객체를 생성하여 연결 |
| ⭐️initState() | State가 처음 초기화될 때 1회 호출 | 초기 상태 설정, 리스너 등록 |
| didChangeDependencies() | initState() 이후 또는 InheritedWidget이 변경되었을 때 | 의존성 관련 값 접근 가능 |
| ⭐️build() | 위젯이 처음 그려질 때, 또는 setState()/didUpdateWidget() 호출 후 | UI 구성 |
| didUpdateWidget() | 부모가 위젯을 새 인스턴스로 다시 그릴 때 (State는 유지) | 새 파라미터 반영. 이후 자동으로 build() |
| setState() | 상태 변경 발생 시 호출 | 상태 변경 → build() 트리거 |
| deactivate() | 위젯이 트리에서 제거되기 직전 | 위젯이 제거될 준비 단계 |
| ⭐️dispose() | 위젯이 완전히 트리에서 제거될 때 | 리소스 해제, 컨트롤러/리스너 정리 |
사용자의 글자 입력을 받을 수 있는 위젯
| 타입명 | 키보드 버튼에 표시되는 텍스트 | 용도/설명 |
|---|---|---|
| ⭐️ TextInputAction.done | Done | 입력 완료 시 사용 (폼 제출, 입력 종료) |
| TextInputAction.next | Next | 다음 입력 필드로 이동 |
| TextInputAction.previous | Previous | 이전 입력 필드로 이동 (드물게 사용됨) |
| ⭐️ TextInputAction.search | Search | 검색 창 등에서 검색 트리거 |
| TextInputAction.send | Send | 채팅/메시지 등에서 전송 기능 |
| ⭐️ TextInputAction.go | Go | URL 이동, 진행 버튼 등에 사용 |
| TextInputAction.continueAction | Continue | 다음 단계로 계속 진행할 때 (iOS에서 주로 사용) |
| TextInputAction.join | Join | 가입이나 참여 관련 입력창 |
| TextInputAction.route | Route | 경로 탐색, 내비게이션 목적의 입력 |
| TextInputAction.emergencyCall | Emergency | 긴급 전화 관련 UI |
| ⭐️ TextInputAction.newline | Enter / 줄 바꿈 | 멀티라인 입력 시 줄 바꿈 기능 (채팅/메모장 등에서 자주 사용) |
| TextInputAction.unspecified | 플랫폼 기본값 사용 | 특별히 지정하지 않음 (기본 동작 사용) |
class HomePage extends StatefulWidget {
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController controller = TextEditingController();
void dispose() {
controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Test")),
body: Column(
children: [
TextField(controller: controller),
ElevatedButton(
onPressed: () {
controller.clear();
},
child: Text("초기화"),
),
ElevatedButton(
onPressed: () {
print(controller.text);
},
child: Text("현재값"),
),
],
),
);
}
}
Style 관련 속성
| 속성명 | 설명 |
|---|---|
| labelText | 입력창 위에 항상 표시되는 라벨 텍스트 |
| hintText | 입력 전, 입력창 안에 흐릿하게 보이는 힌트 |
| prefixIcon / suffixIcon | 입력창 안쪽에 표시할 아이콘 |
| prefix / suffix | 아이콘 외에 텍스트/위젯도 가능 |
| filled | 배경을 채울지 여부 (true 설정 시 fillColor 필요) |
| fillColor | 배경색 설정 |
| border | 기본 상태 테두리 |
| enabledBorder | 포커스되지 않은 상태의 테두리 |
| focusedBorder | 포커스된 상태의 테두리 |
| contentPadding | 내부 여백 (입력값과 테두리 사이 간격) |
TextField(
decoration: InputDecoration(
labelText: '이메일',
hintText: 'example@domain.com',
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
filled: true,
fillColor: Colors.grey[100],
),
style: TextStyle(fontSize: 16, color: Colors.black87),
cursorColor: Colors.blueAccent,
)
스크롤 가능한 위젯 리스트를 만들 때 사용
children 내 리스트에 위젯들 배치
ListView(
children: [
Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("1", style: TextStyle(fontSize: 100)),
),
Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("2", style: TextStyle(fontSize: 100)),
),
Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("3", style: TextStyle(fontSize: 100)),
),
Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("4", style: TextStyle(fontSize: 100)),
),
Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("5", style: TextStyle(fontSize: 100)),
),
],
)
for문처럼 인덱스를 기반으로 위젯을 하나씩 만들어줌
반복적으로 동일한 위젯 그릴 때 유용!
ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
// 반복문처럼 작동하나
// 화면에 보이는 갯수만 build
return Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("${index + 1}", style: TextStyle(fontSize: 100)),
);
},
)
ListView.builder와 거의 동일하지만, 아이템 사이에 위젯(구분자)을 삽입 가능
ListView.separated(
itemCount: 10,
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 5,
color: Colors.blue,
);
},
itemBuilder: (context, index) {
return Container(
width: double.infinity,
color: Colors.amber,
margin: EdgeInsets.all(10),
child: Text("${index + 1}", style: TextStyle(fontSize: 100)),
);
},
)
위젯 심화 강의를 시작했는데 난이도는 아직 비슷비슷한 것 같다
이 위젯들을 어떻게 사용해서 어플을 구성할지는 아직 감이 잡히진 않지만 재미는 있다룡