오늘은 ProxyProvider 에 대해서 알아보겠습니다. Provider 에서 사용하는 변수가 다른 Provider 에 영향을 미치는 경우 , 또는 외부의 변수가 Provider 에 영향을 미치는 경우 사용한다.
개발환경 : 윈도우11, 안드로이드 스튜디오(Arctic Fox 2020.3.1 Patch 4), flutter 2.10
소스코드 - Release 22_ProxyProvider · mike-bskim/provider_overview (github.com)
이번에는 내부 변수를 Provider 에 전달하는 예시입니다
- proxyprov_proxyprov.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Translations {
const Translations(this._value);
final int _value;
String get title => 'You clicked $_value times';
}
class ProxyProvProxyProv extends StatefulWidget {
const ProxyProvProxyProv({Key? key}) : super(key: key);
@override
_ProxyProvProxyProvState createState() => _ProxyProvProxyProvState();
}
class _ProxyProvProxyProvState extends State<ProxyProvProxyProv> {
int counter = 0;
void increment() {
setState(() {
counter++;
debugPrint('counter: $counter');
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ProxyProvider ProxyProvider'),
),
body: Center(
child: MultiProvider(
providers: [
// 내부 변수를 ProxyProvider0 전달
ProxyProvider0<int>(
update: (_, __) => counter,
),
// counter 값을 Translations 전달(counter > int > value).
// 인스턴스 생성과 동시에 변수설정이 가능하여 update 로 처리
ProxyProvider<int, Translations>(
update: (_, value, __) => Translations(value),
),
],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const ShowTranslations(),
const SizedBox(height: 20.0),
IncreaseButton(increment: increment),
],
),
),
),
);
}
}
class ShowTranslations extends StatelessWidget {
const ShowTranslations({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final title = context.watch<Translations>().title;
return Text(
title,
style: const TextStyle(fontSize: 28.0),
);
}
}
class IncreaseButton extends StatelessWidget {
final VoidCallback increment;
const IncreaseButton({
Key? key,
required this.increment,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: increment,
child: const Text(
'INCREASE',
style: TextStyle(fontSize: 20.0),
),
);
}
}
이번에는 Provider 값을 다른 Provider 에게 전달하는 예시입니다. 둘다 ChangeNotifier 사용하는 경우.
- chgnotiprov_chgnotiproxyprov.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Counter with ChangeNotifier {
int counter = 0;
void increment() {
counter++;
notifyListeners();
}
}
class Translations with ChangeNotifier {
late int _value;
void update(Counter counter) {
_value = counter.counter;
notifyListeners();
}
String get title => 'You clicked $_value times';
}
class ChgNotiProvChgNotiProxyProv extends StatefulWidget {
const ChgNotiProvChgNotiProxyProv({Key? key}) : super(key: key);
@override
_ChgNotiProvChgNotiProxyProvState createState() =>
_ChgNotiProvChgNotiProxyProvState();
}
class _ChgNotiProvChgNotiProxyProvState
extends State<ChgNotiProvChgNotiProxyProv> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ChangeNotifierProvider ChagneNotifierProxyProvider'),
),
body: Center(
child: MultiProvider(
providers: [
// 인스턴스 생성
ChangeNotifierProvider<Counter>(
create: (_) => Counter(),
),
// 인스턴스 생성, 인스턴스 생성과 동시에 변수설정이 불가
// update 에서 값 및 리턴할 인스턴스 정보 입력
ChangeNotifierProxyProvider<Counter, Translations>(
create: (_) => Translations(), // context 전달하지 말 것
update: (
BuildContext _, // context 전달하지 말 것
Counter counter, // 전달할 값(provider 로 생성된 인스턴스)
Translations? translations, // 리턴할 인스턴스
) {
translations!.update(counter);
return translations;
},
),
],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
ShowTranslations(),
SizedBox(height: 20.0),
IncreaseButton(),
],
),
),
),
);
}
}
class ShowTranslations extends StatelessWidget {
const ShowTranslations({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final title = context.watch<Translations>().title;
return Text(
title,
style: const TextStyle(fontSize: 28.0),
);
}
}
class IncreaseButton extends StatelessWidget {
const IncreaseButton({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => context.read<Counter>().increment(),
child: const Text(
'INCREASE',
style: TextStyle(fontSize: 20.0),
),
);
}
}
이번에는 Provider 값을 다른 Provider 에게 전달하는 예시입니다. 값을 주는쪽만 ChangeNotifier 사용하는 경우.
- chgnotiprov_proxyprov.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Counter with ChangeNotifier {
int counter = 0;
void increment() {
counter++;
notifyListeners();
}
}
class Translations {
const Translations(this._value);
final int _value;
String get title => 'You clicked $_value times';
}
class ChgNotiProvProxyProv extends StatefulWidget {
const ChgNotiProvProxyProv({Key? key}) : super(key: key);
@override
_ChgNotiProvProxyProvState createState() => _ChgNotiProvProxyProvState();
}
class _ChgNotiProvProxyProvState extends State<ChgNotiProvProxyProv> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ChangeNotifierProvider ProxyProvider'),
),
body: Center(
child: MultiProvider(
providers: [
// 인스턴스 생성
ChangeNotifierProvider<Counter>(
create: (_) => Counter(),
),
// update 에서 값 정보 입력, 제넥릭에서 타입을 지정해서 타입생략가능
ProxyProvider<Counter, Translations>(
update: (_, counter, __) => Translations(counter.counter),
),
],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
ShowTranslations(),
SizedBox(height: 20.0),
IncreaseButton(),
],
),
),
),
);
}
}
class ShowTranslations extends StatelessWidget {
const ShowTranslations({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final title = context.watch<Translations>().title;
return Text(
title,
style: const TextStyle(fontSize: 28.0),
);
}
}
class IncreaseButton extends StatelessWidget {
const IncreaseButton({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => context.read<Counter>().increment(),
child: const Text(
'INCREASE',
style: TextStyle(fontSize: 20.0),
),
);
}
}
'Flutter > 07 State - Provider' 카테고리의 다른 글
[Flutter] Provider - errors(provider with Dialog) (0) | 2022.05.08 |
---|---|
[Flutter] Provider - errors(provider with StatefulWidget) (0) | 2022.05.08 |
[Flutter] ProxyProvider - create, update (0) | 2022.05.06 |
[Flutter] ProxyProvider - update (0) | 2022.05.06 |
[Flutter] Provider Access - generated route (0) | 2022.05.06 |