1. Provider
- 하나의 데이터를 여러 페이지에 공유 가능
- 한 클래스는 하나의 역할만 갖도록 분리 가능
- 코드의 간결함
1-1. Provider 데이터 생산
Provider<int>.value(
value: 5,
child: MaterialApp(
home: SimplePage(),
),
)
- Provider의 child에서 값 공유 가능
- Provider에서 제공하는 값(value)은 5
1-2. Provider 데이터 소비
var data = Provider.of<int>(context);
- Provider.of(context) 또는 Consumer() 위젯 사용하여 소비
2. ChangeNotifierProvider 사용 - 변하는 값 처리
- setState()와 ChangeNotifier는 같은 일을 할 수 있음.
- ㅊChangeNotifier를 mixin한 클래스는 notifyListeners() 함수 호출 가능 → UI 업데이트 가능
2-1. Counter
class Counter with ChangeNotifier {
int _counter;
Counter(this._counter);
getCounter() => _counter;
setCounter(int counter) => _counter = counter;
void increment() {
_counter++;
notifyListeners();
}
void decrement() {
_counter--;
notifyListeners();
}
}
- ChangeNotifier를 mixin 했기에 ChangeNotifierProvider 사용해줘야함.
- notifyListeners() : 값이 변할 때마다 flutter framework에 알려줌
2-2. CounterApp
class CounterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Counter>(
// Counter 타입 사용. Counter 클래스의 데이터가 변하는지 보고 있다가 변하면 알려줍니다.
create: (_) => Counter(0),
child: MaterialApp(
title: 'Flutter Value',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
),
);
}
}
- MaterialApp을 ChangeNotifierProvider로 감싸고 있음
- create 속성에서 초기값 정하고 child에 정의된 자식 위젯들에서 사용
2-3. ChangeNotifierProvider 값 사용하기
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
final counter = Provider.of<Counter>(context);
return Scaffold(
appBar: AppBar(
title: Text("Provider demo"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'${counter.getCounter()}',
style: Theme.of(context).textTheme.display1,
),
RaisedButton(
onPressed: openFirstPage,
child: Text('first page'),
),
RaisedButton(
onPressed: openSecondPage,
child: Text('second page'),
),
],
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: counter.increment,
tooltip: 'Increment',
child: Icon(Icons.add),
heroTag: null,
),
SizedBox(
height: 10,
),
FloatingActionButton(
onPressed: counter.decrement,
tooltip: 'Decrement',
child: Icon(Icons.remove),
heroTag: null,
)
],
),
);
}
Future openFirstPage() {
return Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),
);
}
Future openSecondPage() {
return Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
}
}
- Provider.of<Counter>(context)로 Counter 타입의 데이터를 가져옴
- onPressed: counter.increment, coutner.decrement에서 값이 증가하거나 감소함.
▶ Counter 클래스의 increment(), decrement()에서 notifyListeners() 호출되기에 UI 갱신됨
- Navigator.push 로 화면 이동해도 Counter의 값은 동일함
2-4. FirstPage 에서도 값이 동일한지 확인
class FirstPage extends StatefulWidget {
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
@override
Widget build(BuildContext context) {
final counter = Provider.of<Counter>(context);
return Scaffold(
appBar: AppBar(
title: Text('first page'),
),
body: Center(
child: Container(
child: Text('first page counter ${counter.getCounter()}'),
),
),
);
}
}
- Provider.of<Counter>(context)로 값을 가져옴
2-5. 결과
참고 : software-creator.tistory.com/26
'프로그래밍 > Flutter-Dart' 카테고리의 다른 글
[Flutter] Bluetooth (0) | 2021.03.24 |
---|---|
[Flutter] Provider (2) (0) | 2021.03.24 |
[Flutter] Login App (2) (0) | 2021.03.24 |
[Flutter] Vlc Player & Circular Percent Indicator (0) | 2021.03.24 |
[Flutter] Custom Horizontal Number Picker (0) | 2021.03.23 |
댓글