LoginSignup
3
2

More than 3 years have passed since last update.

Flutter で流行りの Riverpod を使ってみた

Last updated at Posted at 2020-09-10

Riverpod とは

FLutter 界隈で最近流行りの状態管理ライブラリ。
Provider よりいい感じに状態管理が行える。
詳しいことはあんまりわかってない

今回作るもの

Flutter でアプリケーションを作ると出てくることでおなじみの、カウントアップアプリ。
右下の「+」をクリック or タップすると、中央の数字が増えていく。

image.png

最終形はここに。
https://github.com/tktcorporation/Flutter-StateManagement/tree/v1

構成

image.png

  • Domain は状態管理だったりのことを考えない純粋なオブジェクト
  • Controller は Domain に依存し、ChangeNotifier を継承することで、状態管理を担当する

App の特定のスコープ内で Riverpod の ChangeNotifierProvider に Controller を渡し、それを用いて状態を管理する。
というような方法をとっている。

有用な構成なのかはわかっていない

実装

Domain

状態管理だったりのことを考えない純粋なオブジェクト

class Counter {
  int _value = 0;

  int get value => _value;

  void increment() {
    _value++;
  }
}

Controller

Domain に依存し、ChangeNotifier を継承することで、状態管理を担当する

import 'package:flutter/material.dart';
import 'package:stateManagement/domain/counter.dart';

class CounterController extends ChangeNotifier {
  CounterController(Counter counter) : this._counter = counter;
  Counter _counter;

  void increment() {
    this._counter.increment();
    notifyListeners();
  }

  int getCount() {
    return this._counter.value;
  }
}

Component

CountText

カウントを表示する

class CountText extends StatelessWidget {
  const CountText(this._count);
  final int _count;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'You have pushed the button this many times:',
          ),
          Text(
            _count.toString(),
            style: Theme.of(context).textTheme.headline4,
          ),
        ],
      ),
    );
  }
}

IncrementButton

押すとカウントが増えるボタン

typedef void Increment();

class IncrementButton extends StatelessWidget {
  const IncrementButton(this._increment);

  final Increment _increment;

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: this._increment,
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }
}

Page

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// import counter.dart
// import counter_controller.dart
// import count_text.dart
// import increment_button.dart

class CounterPage extends StatelessWidget {
  CounterPage(this._title);
  final String _title;
  final counterProvider = ChangeNotifierProvider<CounterController>(
      (_) => CounterController(Counter()));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(this._title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Consumer(
                builder: (_, watch, __) =>
                    CountText(watch(counterProvider).getCount()),
              )
            ],
          ),
        ),
        floatingActionButton: IncrementButton(context.read(counterProvider).increment));
  }
}

App

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

class RiverpodTestApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ProviderScope(
      child: MaterialApp(
        title: 'CounterApp',
        theme: ThemeData(
          // This is the theme of your application.
          primarySwatch: Colors.orange,
          // This makes the visual density adapt to the platform that you run
          // the app on. For desktop platforms, the controls will be smaller and
          // closer together (more dense) than on mobile platforms.
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: CounterPage('Counter'),
      ),
    );
  }
}

Main

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

void main() {
  runApp(RiverpodTestApp());
}

ここまで書いて起動してあげれば、カウントアプリは正常に動作するはず。

まとめ

自分が行っているような形での状態管理を行っている記事は見当たらなかったので、一つの形として残してみる。
実践運用した構成ではないので、後日、実際に使ってみた感想を追記する予定。

「そのやり方はここがよろしくないよー」等あれば、コメントお願いしたいです。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2