「Flutter Riverpod」の版間の差分
ナビゲーションに移動
検索に移動
(→基本) |
|||
61行目: | 61行目: | ||
---- | ---- | ||
[[FlutterFire]] | [[FlutterFire]] | ||
+ | ====pubspec.yaml===== | ||
+ | <pre> | ||
+ | flutter: | ||
+ | sdk: flutter | ||
+ | flutter_riverpod: ^0.14.0+3 | ||
+ | firebase_core: ^1.7.0 | ||
+ | firebase_auth: ^3.1.3 | ||
+ | json_annotation: ^4.0.1 | ||
+ | |||
+ | dev_dependencies: | ||
+ | flutter_test: | ||
+ | sdk: flutter | ||
+ | json_serializable: ^4.1.3 | ||
+ | build_runner: ^2.1.1 | ||
+ | </pre> | ||
+ | ====Main==== | ||
+ | *main.dart | ||
<pre> | <pre> | ||
− | |||
import 'package:firebase_core/firebase_core.dart'; | import 'package:firebase_core/firebase_core.dart'; | ||
import 'package:flutter_riverpod/flutter_riverpod.dart'; | import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
+ | import 'package:flutter/material.dart'; | ||
+ | import 'package:repbuilder/provider/providers.dart'; | ||
+ | import 'package:repbuilder/widget/widgets.dart'; | ||
+ | import 'package:repbuilder/screen/sign_in/sigin_in.dart'; | ||
+ | import 'package:repbuilder/screen/person_list/person_list.dart'; | ||
void main() async { | void main() async { | ||
71行目: | 92行目: | ||
// Firebaseの初期化(非同期)を待つ | // Firebaseの初期化(非同期)を待つ | ||
await Firebase.initializeApp(); | await Firebase.initializeApp(); | ||
− | + | ||
− | + | runApp(ProviderScope(child: RepBuilder())); | |
− | runApp(ProviderScope(child: | ||
} | } | ||
− | class | + | class RepBuilder extends StatelessWidget { |
// This widget is the root of your application. | // This widget is the root of your application. | ||
@override | @override | ||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||
return MaterialApp( | return MaterialApp( | ||
− | title: ' | + | title: 'Report Builder', |
theme: ThemeData( | theme: ThemeData( | ||
− | + | primarySwatch: Colors.blue, | |
), | ), | ||
− | home: Consumer( | + | home: Consumer( |
− | builder: (context, watch, child) { | + | builder: (context, watch, child) { |
− | return | + | final user = watch(userProvider); |
+ | return user.when( | ||
+ | data: (user) => (user == null) ? SignInScreen() : PersonLIst(), | ||
+ | loading: () => loadingWidget(), | ||
+ | error: (e, stackTrace) => errorWidget(context, e, stackTrace), | ||
+ | ); | ||
}, | }, | ||
) | ) | ||
93行目: | 118行目: | ||
} | } | ||
} | } | ||
+ | </pre> | ||
+ | |||
+ | ====Model==== | ||
+ | <pre> | ||
+ | import 'package:json_annotation/json_annotation.dart'; | ||
+ | part 'person.g.dart'; | ||
+ | |||
+ | @JsonSerializable() | ||
+ | class Person { | ||
+ | String? id; | ||
+ | String? name; | ||
+ | DateTime? createdAt; | ||
+ | |||
+ | Person({this.id, this.name}); | ||
+ | |||
+ | factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json); | ||
+ | Map<String, dynamic> toJson() => _$PersonToJson(this); | ||
+ | }</pre> | ||
+ | *json_annotation | ||
+ | <pre> | ||
+ | $ flutter pub run build_runner build | ||
+ | </pre> | ||
+ | |||
+ | ====Repository==== | ||
+ | <pre> | ||
+ | import 'package:firebase_auth/firebase_auth.dart'; | ||
+ | import 'package:repbuilder/model/person.dart'; | ||
+ | |||
+ | class PersonRepository { | ||
+ | final User user; | ||
+ | PersonRepository(this.user); | ||
+ | |||
+ | List<Person> getPersonList() { | ||
+ | // DUMMY | ||
+ | return new List.of([new Person(id:"id1",name:this.user.email), new Person(id:"id2",name:this.user.email)]); | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ====Provider==== | ||
+ | <pre> | ||
+ | import 'package:firebase_auth/firebase_auth.dart'; | ||
+ | import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
+ | import 'package:repbuilder/repository/repositories.dart'; | ||
+ | |||
+ | final userProvider = StreamProvider.autoDispose((ref) { | ||
+ | return FirebaseAuth.instance.authStateChanges(); | ||
+ | }); | ||
+ | |||
+ | final personRepositoryProvider = Provider.autoDispose((ref) { | ||
+ | final User? user = ref.watch(userProvider).data?.value; | ||
+ | return user == null ? null : PersonRepository(user); | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | ====Consumer==== | ||
+ | <pre> | ||
+ | import 'package:flutter/material.dart'; | ||
+ | import 'package:repbuilder/provider/providers.dart'; | ||
+ | import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
+ | |||
+ | class PersonLIst extends StatefulWidget { | ||
+ | @override | ||
+ | _PersonLIstState createState() => _PersonLIstState(); | ||
+ | } | ||
+ | |||
+ | class _PersonLIstState extends State<PersonLIst> { | ||
+ | @override | ||
+ | Widget build(BuildContext context) { | ||
+ | return Consumer( | ||
+ | builder: (context, watch, child) { | ||
+ | final personRep = watch(personRepositoryProvider); | ||
+ | var persons = personRep?.getPersonList(); | ||
+ | return Text(persons?.elementAt(0).name ?? 'null'); | ||
+ | }, | ||
+ | ); | ||
+ | } | ||
+ | } | ||
+ | |||
</pre> | </pre> |
2021年10月30日 (土) 02:36時点における版
| Flutter | Dart | ブログカテゴリ(Flutter) | Android Studio | Flutter macos | FlutterFire | Flutter 手順 |
目次
Flutter Riverpod
基本
データの受け渡し
Providerをグローバルに定義し、データを受け渡す
データを渡す
種類 | 目的 |
---|---|
Provider | 任意のデータを渡す |
FutureProvider | Futureから取得する任意のデータを渡す |
Stream Provider | Streamから取得する任意のデータを渡す |
StateProvider | 変更可能な任意のデータを渡す |
StateNotifireProvider | StateNotifireProviderから取得する任意のデータを渡す |
ScopedProvider | 場所に応じて異なる任意のデータを渡す |
データを受け取る
種類 | 目的 |
---|---|
ConsumerWidget | 継承することでデータを受け取れるWidget |
Consumer | コールバック内でデータを受け取れるWidget |
useProvider() | flutter_hooksを利用し、HookWidgetを継承したWidgetでデータを受け取れる関数 |
context.read() | BuildContextからデータを受け取れる関数(ただしデータの変更通知は受け取れない) |
ProviderContainer | Flutterに依存しない形でデータを受け取れる |
基本
pubspec.yaml=
flutter: sdk: flutter flutter_riverpod: ^0.14.0+3 firebase_core: ^1.7.0 firebase_auth: ^3.1.3 json_annotation: ^4.0.1 dev_dependencies: flutter_test: sdk: flutter json_serializable: ^4.1.3 build_runner: ^2.1.1
Main
- main.dart
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter/material.dart'; import 'package:repbuilder/provider/providers.dart'; import 'package:repbuilder/widget/widgets.dart'; import 'package:repbuilder/screen/sign_in/sigin_in.dart'; import 'package:repbuilder/screen/person_list/person_list.dart'; void main() async { // Flutter の初期化処理を待つ WidgetsFlutterBinding.ensureInitialized(); // Firebaseの初期化(非同期)を待つ await Firebase.initializeApp(); runApp(ProviderScope(child: RepBuilder())); } class RepBuilder extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Report Builder', theme: ThemeData( primarySwatch: Colors.blue, ), home: Consumer( builder: (context, watch, child) { final user = watch(userProvider); return user.when( data: (user) => (user == null) ? SignInScreen() : PersonLIst(), loading: () => loadingWidget(), error: (e, stackTrace) => errorWidget(context, e, stackTrace), ); }, ) ); } }
Model
import 'package:json_annotation/json_annotation.dart'; part 'person.g.dart'; @JsonSerializable() class Person { String? id; String? name; DateTime? createdAt; Person({this.id, this.name}); factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json); Map<String, dynamic> toJson() => _$PersonToJson(this); }
- json_annotation
$ flutter pub run build_runner build
Repository
import 'package:firebase_auth/firebase_auth.dart'; import 'package:repbuilder/model/person.dart'; class PersonRepository { final User user; PersonRepository(this.user); List<Person> getPersonList() { // DUMMY return new List.of([new Person(id:"id1",name:this.user.email), new Person(id:"id2",name:this.user.email)]); } }
Provider
import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:repbuilder/repository/repositories.dart'; final userProvider = StreamProvider.autoDispose((ref) { return FirebaseAuth.instance.authStateChanges(); }); final personRepositoryProvider = Provider.autoDispose((ref) { final User? user = ref.watch(userProvider).data?.value; return user == null ? null : PersonRepository(user); });
Consumer
import 'package:flutter/material.dart'; import 'package:repbuilder/provider/providers.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class PersonLIst extends StatefulWidget { @override _PersonLIstState createState() => _PersonLIstState(); } class _PersonLIstState extends State<PersonLIst> { @override Widget build(BuildContext context) { return Consumer( builder: (context, watch, child) { final personRep = watch(personRepositoryProvider); var persons = personRep?.getPersonList(); return Text(persons?.elementAt(0).name ?? 'null'); }, ); } }
© 2006 矢木浩人