【Flutter】FutureProviderを使って非同期でUIを更新する【flutter_riverpod】

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Flutter】FutureProviderを使って非同期でUIを更新する【flutter_riverpod】

2024-4-4 | ,

FlutterのパッケージriverpodFutureProviderを使って非同期でUIを更新したい!

概要

今回の記事では、FlutterのパッケージriverpodFutureProviderを使って非同期でUIを更新する手順を掲載する。

非同期でAPIにアクセスして結果をUIを出力するとかそんな感じ。

Consumerというウィジェットを使う方法とConsumerWidgetというウィジェットを継承したクラスを使う方法を載せる。

仕様書

環境

  • Android Studio Giraffe | 2023.2.1 Patch 2
  • Flutter 3.19.6
  • flutter_riverpod: 2.5.1

手順書

インストール編とConsumer編とConsumerWidget編の3部構成です。

インストール編

ターミナルでコマンドを実行するか

flutter pub add flutter_riverpod

pubspec.yamldependencies:に下記のような感じで追加して

dependencies:
  flutter_riverpod: ^2.5.1

ターミナルでflutter pub getする。

flutter pub get

Consumer

Consumerというウィジェットを使う例。

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: const FutureProviderSample1()
      )
    )
  );
}

final futureProvider = FutureProvider<String>((ref) async {
  // 遅延処理(APIからデータを取得するとか)
  await Future.delayed(const Duration(seconds: 2));
  return 'FutureProvider!!!';
});

class FutureProviderSample1 extends StatelessWidget {
  const FutureProviderSample1({super.key});

  @override
  Widget build(BuildContext context) {
    return ProviderScope(
      child: SafeArea(
        child: Center(
          child: Consumer(
            builder: (BuildContext context, WidgetRef ref, Widget? child) {
              final asyncValue = ref.watch(futureProvider);
              return asyncValue.when(
              data: (data) => Text(
                data,
                style: const TextStyle(
                    color: Color(0xFF000000)
                  ),
                ),
              loading: () => const CircularProgressIndicator(),
              error: (error, stack) => Text(
                'Error: $error',
                style: const TextStyle(
                    color: Color(0xFFFF0000)
                  ),
                ),
              );
            }
          ),
        ),
      ),
    );
  }
}

Consumerのプロパティbuilderの中でデータの読み込み状況によって処理を切り替えてる。
data:はデータの読み取りが完了した時の処理、loading:はデータの読み取り中の処理(クルクルを表示してる)、error:はエラー発生時の処理。

ConsumerProviderScopeの中に含める必要がある。

ConsumerWidget

ConsumerWidgetを継承したクラスを使う例。

class FutureProviderSample2 extends ConsumerWidget {
  const FutureProviderSample2({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncValue = ref.watch(futureProvider);
    return SafeArea(
      child: Center(
        child: asyncValue.when(
          data: (data) => Text(
            data,
            style: const TextStyle(
                color: Color(0xFF000000)
              ),
            ),
          loading: () => const CircularProgressIndicator(),
          error: (error, stack) => Text(
            'Error: $error',
            style: const TextStyle(
                color: Color(0xFFFF0000)
            ),
          ),
        ),
      ),
    );
  }
}

生補填にはConsumerを使う場合と同じで処理を書くところが違う感じ。メソッドbuildに処理を書く。

こちらもConsumerと同様にProviderScopeの中にこのクラス自体を含める必要がある。

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context) {

    return const Scaffold(
      body: ProviderScope(
          child:FutureProviderSample2()
      ),
    );
  }
}

まとめ(感想文)

APIにアクセスするとかネットワークを使う場合に特に便利だ!

参考文献・引用

下記のサイトを参考にさせていただきました。ありがとうございました。