Share
Sign In
공부 내용
Flutter의 상태 관리 - Controller (Provider)
Y
yeji Kim
👍
참고 자료
Controller
컨트롤러는 사용자 입력을 처리하고 모델을 업데이트함.
Provider
Key concepts
ChangeNotifier - listener에게 변화에 대해 알림.
import 'package:flutter/foundation.dart'; class Counter with ChangeNotifier { int _count = 0; int get count => _count; void increment() { _count++; notifyListeners(); } }
Provider - widget tree에서 inject, access
ChangeNotifierProvider
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'counter.dart'; void main() { runApp( ChangeNotifierProvider( create: (context) => Counter(), child: MyApp(), ), ); }
ChangeNotifier가 변하면 dependents를 rebuild함.
Consumer - object가 변하면 스스로를 rebuild함.
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'counter.dart'; class CounterScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Provider Counter Example'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('You have pushed the button this many times:'), Consumer<Counter>( builder: (context, counter, child) { return Text( '${counter.count}', style: Theme.of(context).textTheme.headline4, ); }, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: () { Provider.of<Counter>(context, listen: false).increment(); }, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
사용 목적
위와 같이 동일 상태 (데이터)를 전역적으로 다른 위젯과 공유하기 위해
최상단 위젯에 Provider 제공
void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => Counts()), ], child: MyApp(), ), ); }
class Home extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Provider'), ), body: ChangeNotifierProvider( create: (BuildContext context) => Counts(), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Counter(), Buttons(), ], ), ), ), ); } }
Provider를 사용하는 위젯
class Counter extends StatelessWidget { @override Widget build(BuildContext context) { print('Counter'); return Text( context.watch<Counts>().count.toString(), style: TextStyle( fontSize: 20, ), ); } }
class Buttons extends StatelessWidget { @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { context.read<Counts>().add(); }, child: Icon(Icons.add)), SizedBox( width: 40, ), ElevatedButton( onPressed: () { context.read<Counts>().remove(); }, child: Icon(Icons.remove)) ], ); } }
Provider의 함수
read - 상태 값을 읽음. 감시하진 않음. Provider의 값을 변경하는 함수에 많이 쓰임.
watch - 상태 값의 변화를 감시함. 상태 값을 사용할 때.
select - 상태 값의 특정 부분 만을 감시함.
변경된 상태 값을 표시하기 위한 rebuild에 많은 비용이 드는데, 이 때 select를 이용하여 특정 값만의 변경을 감시하여 최적화할 수 있음.
Provider 선언하기
단일 Provider
MaterialApp( title: 'Flutter Provider Demo', home: ChangeNotifierProvider( create: (BuildContext context) => CounterProvider(), child: Home(), ), );
다중 Provider
MaterialApp( title: 'Flutter Provider Demo', home: MultiProvider( providers: [ ChangeNotifierProvider( create: (BuildContext context) => CounterProvider(), ), ChangeNotifierProvider( create: (BuildContext context) => TodoProvider(), ), ], child: Home(), ), );
Provider 사용하기
Provider.of
@override Widget build(BuildContext context) { CounterProvider counter = Provider.of<CounterProvider>(context); return Center( child: Text( counter.count.toString(), ), ); }
Provider에 직접 접근해서 받아오기.
현 위젯 전체가 리로드된다.
Consumer
return Center( child: Consumer<CounterProvider>( builder: (context, provider, child) { return Text( provider.count.toString(), ); }, ), );
Consumer를 사용한 해당 부분만 re build됨.
Subscribe to '아무튼-작업일지'
Welcome to '아무튼-작업일지'!
By subscribing to my site, you'll be the first to receive notifications and emails about the latest updates, including new posts.
Join SlashPage and subscribe to '아무튼-작업일지'!
Subscribe
👍
Other posts in '공부 내용'See all
yeji Kim
flutter FutureBuilder
참고 자료 https://eory96study.tistory.com/21 Future 서버에서 데이터를 모두 받아오기 전에 대략적으로 잠재적인 값을 결정하고 어떤 걸 보여줄지 선택하기 위해. FutureBuilder FutureBuilder - 데이터를 다 받기 전에 데이터 없이 그릴 수 있는 부분을 먼저 그리기 위해.
yeji Kim
Flutter 위젯 - 달력, 시간, 선택 등 (Card)
참고 자료 Card Chip CupertinoPicker CupertinoTimerPicker showDatePicker function
yeji Kim
Flutter의 Service (Sqflite)
참고 자료