「Flutter Riverpod」の版間の差分
ナビゲーションに移動
検索に移動
(→データを渡す) |
|||
| (同じ利用者による、間の13版が非表示) | |||
| 1行目: | 1行目: | ||
| [[Flutter]] | [[Dart]] | [https://www.typea.info/blog/index.php/category/flutter/ ブログカテゴリ(Flutter)] | [[Android Studio]] | [[Flutter macos]] | [[FlutterFire]] | [[Flutter 手順]] | | | [[Flutter]] | [[Dart]] | [https://www.typea.info/blog/index.php/category/flutter/ ブログカテゴリ(Flutter)] | [[Android Studio]] | [[Flutter macos]] | [[FlutterFire]] | [[Flutter 手順]] | | ||
==Flutter Riverpod== | ==Flutter Riverpod== | ||
| + | {{amazon|B09754L28H}} | ||
| + | *https://pub.dev/packages/flutter_riverpod | ||
| + | |||
| + | ==基本== | ||
| + | *[https://riverpod.dev/docs/getting_started はじめに] | ||
| + | *[https://pub.dev/documentation//flutter_riverpod/latest/flutter_riverpod/flutter_riverpod-library.html flutter_riverpod] | ||
| + | ===データの受け渡し=== | ||
| + | ---- | ||
| + | Providerをグローバルに定義し、データを受け渡す | ||
| + | ====データを渡す==== | ||
| + | ---- | ||
| + | {|class="wikitable" | ||
| + | !種類 | ||
| + | !目的 | ||
| + | |- | ||
| + | | Provider | ||
| + | | 任意のデータを渡す | ||
| + | |- | ||
| + | | [https://pub.dev/documentation/riverpod/latest/riverpod/FutureProvider-class.html FutureProvider] | ||
| + | | Futureから取得する任意のデータを渡す | ||
| + | |- | ||
| + | | Stream Provider | ||
| + | | Streamから取得する任意のデータを渡す | ||
| + | |- | ||
| + | | [https://pub.dev/documentation/riverpod/latest/riverpod/StateProvider-class.html StateProvider] | ||
| + | | 変更可能な任意のデータを渡す | ||
| + | |- | ||
| + | | StateNotifireProvider | ||
| + | | StateNotifireProviderから取得する任意のデータを渡す | ||
| + | |- | ||
| + | | ScopedProvider | ||
| + | | 場所に応じて異なる任意のデータを渡す | ||
| + | |- | ||
| + | |} | ||
| + | |||
| + | ====データを受け取る==== | ||
| + | ---- | ||
| + | {|class="wikitable" | ||
| + | !種類 | ||
| + | !目的 | ||
| + | |- | ||
| + | | [https://pub.dev/documentation//flutter_riverpod/latest/flutter_riverpod/ConsumerWidget-class.html ConsumerWidget] | ||
| + | | 継承することでデータを受け取れるWidget | ||
| + | |- | ||
| + | | [https://pub.dev/documentation//flutter_riverpod/latest/flutter_riverpod/Consumer-class.html Consumer] | ||
| + | | コールバック内でデータを受け取れるWidget | ||
| + | |- | ||
| + | | useProvider() | ||
| + | | flutter_hooksを利用し、HookWidgetを継承したWidgetでデータを受け取れる関数 | ||
| + | |- | ||
| + | | context.read() | ||
| + | | BuildContextからデータを受け取れる関数(ただしデータの変更通知は受け取れない) | ||
| + | |- | ||
| + | | ProviderContainer | ||
| + | | Flutterに依存しない形でデータを受け取れる | ||
| + | |- | ||
| + | |} | ||
| + | |||
| + | ===基本=== | ||
| + | ---- | ||
| + | [[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> | ||
| + | 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), | ||
| + | ); | ||
| + | }, | ||
| + | ) | ||
| + | ); | ||
| + | } | ||
| + | } | ||
| + | </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 PersonListPage extends StatelessWidget { | ||
| + | @override | ||
| + | Widget build(BuildContext context) { | ||
| + | return Scaffold( | ||
| + | appBar: AppBar( | ||
| + | title: Text('TODO APP TITLE'), | ||
| + | ), | ||
| + | body: _PersonListView() | ||
| + | ); | ||
| + | } | ||
| + | } | ||
| + | class _PersonListViewState extends ConsumerWidget { | ||
| + | @override | ||
| + | Widget build(BuildContext context, ScopedReader watch) { | ||
| + | final personRep = watch(personRepositoryProvider); | ||
| + | var persons = personRep?.getPersonList(); | ||
| + | return buildDataTable(persons!); | ||
| + | } | ||
| + | Widget buildDataTable(List<Person> persons) { | ||
| + | : | ||
| + | } | ||
| + | } | ||
| + | </pre> | ||
2021年11月1日 (月) 12:35時点における最新版
| 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 PersonListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO APP TITLE'),
),
body: _PersonListView()
);
}
}
class _PersonListViewState extends ConsumerWidget {
@override
Widget build(BuildContext context, ScopedReader watch) {
final personRep = watch(personRepositoryProvider);
var persons = personRep?.getPersonList();
return buildDataTable(persons!);
}
Widget buildDataTable(List<Person> persons) {
:
}
}
© 2006 矢木浩人