0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめてのアドベントカレンダーAdvent Calendar 2023

Day 11

[Riverpod] StateNotifier Class 内で別のStateProviderを呼び出す。Flutter で変数内で別の変数を呼び出す

Last updated at Posted at 2023-11-19

riverpods でグローバル変数を定義している場合、変数が変わった場合、別の変数も変更する必要があったので、解決策を以下に示しておきます。

背景

30秒広告を一度見たら、「24時間広告が表示されなくなる」という機能を作る場合、
StateNotifer Class 内で別のStateProviderを呼び出す必要が出てきました。もっとわかりやすく説明すると、riverpod でグローバル変数を定義している場合、変数が変わった場合、別の変数も変更する必要が出てきたわけです。

解決策

例えば、以下の二つの変数があり、片方がもう片方に依存している関係にあるとします。

  1. 「アプリ内に広告を表示するかどうか」のフラグ(showAds)
  2. 「24時間広告を表示しないため」の時刻の変数(noAdsUntilDateTime)

上記の場合、1が2に依存しているわけです。

この場合、Dart コードは以下のようになります。


// whether showing ads or not 
final showAdsProvider = StateProvider((ref) => true);

// don't show ads if user has watched rewarded ad in last 24 hours
final noAdsUntilDateTimeProvider =
    StateNotifierProvider<NoAdsUntilDateTimeController, DateTime>(
        (ref) => NoAdsUntilDateTimeController(ref));

class NoAdsUntilDateTimeController extends StateNotifier<DateTime> {
  final StateNotifierProviderRef ref;
  NoAdsUntilDateTimeController(this.ref) : super(DateTime(0)) {
    init();
  }

  // initialize
  Future<void> init() async {

    // get the date that stops the ads until its time.
    state = await PreferenceKeyUtil().getDateTime(
        PreferenceKey.NO_ADS_UNTIL_DATE_TIME,
        defaultVal: DateTime(0));

    // if the no-ads time bonus is valid.
    if (state.isAfter(DateTime.now())) {
      // set showAds = false
      ref.read(showAdsProvider.notifier).state = false;
    }
  }

  // update no-ads date and set the current date.
  void updateDateTime(DateTime dateTime) async {
    state = dateTime;
    PreferenceKeyUtil()
        .setDateTime(PreferenceKey.NO_ADS_UNTIL_DATE_TIME, dateTime);

    // set showAds = false
    ref.read(showAdsProvider.notifier).state = false;
  }
}

こんな感じ。もっとわかりやすく一般化すると↓

わかりやすく

aaa_StateProvider が、 BBB_StateNotifierClass に依存している場合。
(aaa_StateProvider を BBB_StateNotifierClass 内で呼び出す場合)


final aaa_Provider = StateProvider((ref) => true);


final BBB_Provider =
    StateNotifierProvider<BBB_Controller, DateTime>(
        (ref) => BBB_Controller(ref));

class BBB_Controller extends StateNotifier<DateTime> {
  final StateNotifierProviderRef ref;
  BBB_Controller(this.ref) : super(DateTime(0)) {
    init();
  }

  Future<void> init() async {
     state = dateTime;
  }

  void change_aaa_Provider() async {
    ref.read(aaa_Provider.notifier).state = false;
  }
}

みたいな感じ

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?