Flutter에서 Controller는 다양한 위젯과 함께 사용되어 위젯의 상태나 동작을 제어하는 데 사용됩니다.
특히 스크롤, 페이지, 텍스트 입력 등을 다룰 때 유용합니다.
아래는 일반적으로 Controller가 사용되는 주요 위젯과 그 역할을 설명합니다.
1. ScrollController
사용 위젯: ListView, GridView, SingleChildScrollView 등
역할:
• 스크롤 위치를 제어하고 모니터링합니다.
• 특정 위치로 스크롤하거나, 사용자가 스크롤할 때 발생하는 이벤트를 처리할 수 있습니다.
예제:
ListView.builder(
controller: ScrollController(),
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
);
class _ScrollControllerExampleState extends State<ScrollControllerExample> {
final ScrollController _scrollController = ScrollController();
double _scrollPosition = 0;
@override
void initState() {
super.initState();
_scrollController.addListener(() {
setState(() {
_scrollPosition = _scrollController.position.pixels;
});
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scroll Position: $_scrollPosition'),
),
body: ListView.builder(
controller: _scrollController,
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
),
);
}
}
2. PageController
사용 위젯: PageView, TabBarView 등
역할:
• 페이지 뷰어의 현재 페이지를 제어하고 모니터링합니다.
• 특정 페이지로 이동하거나, 페이지 변화 이벤트를 처리할 수 있습니다.
예제:
PageView(
controller: PageController(initialPage: 0),
children: <Widget>[
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
],
);
class _PageControllerExampleState extends State<PageControllerExample> {
final PageController _pageController = PageController(initialPage: 0);
int _currentPage = 0;
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
void _onPageChanged(int page) {
setState(() {
_currentPage = page;
});
}
void _nextPage() {
_pageController.nextPage(duration: Duration(milliseconds: 300), curve: Curves.easeIn);
}
void _previousPage() {
_pageController.previousPage(duration: Duration(milliseconds: 300), curve: Curves.easeIn);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Page View Example')),
body: Column(
children: [
Expanded(
child: PageView(
controller: _pageController,
onPageChanged: _onPageChanged,
children: <Widget>[
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: _previousPage,
),
Text('Page $_currentPage'),
IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: _nextPage,
),
],
),
],
),
);
}
}
3. TextEditingController
사용 위젯: TextField, TextFormField
역할:
• 텍스트 입력 필드의 값을 제어하고 모니터링합니다.
• 초기 값을 설정하거나, 텍스트 변화 이벤트를 처리할 수 있습니다.
예제:
TextField(
controller: TextEditingController(),
decoration: InputDecoration(labelText: 'Enter text'),
);
class _TextEditingControllerExampleState extends State<TextEditingControllerExample> {
final TextEditingController _controller = TextEditingController();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _printLatestValue() {
print('Second text field: ${_controller.text}');
}
@override
void initState() {
super.initState();
_controller.addListener(_printLatestValue);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('TextEditingController Example')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(labelText: 'Enter text'),
),
ElevatedButton(
onPressed: () {
print('First text field: ${_controller.text}');
},
child: Text('Print Text'),
),
],
),
),
);
}
}
4. AnimationController
사용 위젯: 다양한 애니메이션 위젯
역할:
• 애니메이션을 제어하고 모니터링합니다.
• 애니메이션의 시작, 중지, 반복 등을 제어할 수 있습니다.
예제:
AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
class _AnimationControllerExampleState extends State<AnimationControllerExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('AnimationController Example')),
body: Center(
child: FadeTransition(
opacity: _controller,
child: FlutterLogo(size: 100.0),
),
),
);
}
}
5. TabController
사용 위젯: TabBar, TabBarView
역할:
• 탭 바의 현재 탭을 제어하고 모니터링합니다.
• 탭 변경을 제어하거나, 탭 변화 이벤트를 처리할 수 있습니다.
예제:
TabController(
length: 3,
vsync: this,
);
class _TabControllerExampleState extends State<TabControllerExample> with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TabController Example'),
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.directions_car), text: 'Car'),
Tab(icon: Icon(Icons.directions_transit), text: 'Transit'),
Tab(icon: Icon(Icons.directions_bike), text: 'Bike'),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
Center(child: Text('Car Tab')),
Center(child: Text('Transit Tab')),
Center(child: Text('Bike Tab')),
],
),
);
}
}
요약
• ScrollController: 스크롤 위치를 제어 (ListView, GridView 등)
• PageController: 페이지 뷰어의 현재 페이지를 제어 (PageView, TabBarView)
• TextEditingController: 텍스트 입력 필드의 값을 제어 (TextField, TextFormField)
• AnimationController: 애니메이션을 제어 (애니메이션 관련 위젯)
• TabController: 탭 바의 현재 탭을 제어 (TabBar, TabBarView)
참고 자료
• ScrollController 문서
• PageController 문서
• TextEditingController 문서
• AnimationController 문서
• TabController 문서