【问题标题】:Flutter : How to use Riverpod with SharedPreference and List<String> Variable in multipage?Flutter:如何在多页中使用 Riverpod 和 SharedPreference 和 List<String> 变量?
【发布时间】:2021-04-21 10:30:19
【问题描述】:

我创建了List&lt;String&gt; favId = []; 变量来使用 SharedPreferences 存储项目的 ID,因此我重新启动应用程序后收藏的项目 ID 并没有丢失。这是我的 SharedPreferences 方法和最喜欢的 IconButton in detailDoaPage.dart :

...
static List<String> favId = [];

  getData() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    setState(() {
      favId = pref.getStringList("id") ?? [];
    });
  }

  void initState() {
    super.initState();
    getIds();
  }

  getIds() async {
    favId = getData();
  }

  void saveData() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    pref.setStringList("id", favId);
  }
...
IconButton(
                    icon: Icon(
                      favId.contains(doa.id.toString())
                          ? Icons.favorite
                          : Icons.favorite_border,
                      color: favId.contains(doa.id.toString())
                          ? Colors.red
                          : Colors.grey,
                    ),
                    onPressed: () => setState(() {
                      doa.fav = !doa.fav;
                      if (favId.contains(doa.id.toString())) {
                        favId.removeWhere(
                            (element) => element == doa.id.toString());
                      } else {
                        favId.add(doa.id.toString());
                      }
                      saveData();
                      favId.sort();
                    }),
                  )

除此之外,我还想在 favPage.dart(另一个页面)中使用 ListView.builder 显示收藏的项目。当然,我想从 detailDoaPage.dart 中获取 favId。如何在这 2 个页面上实现提供程序/riverpod?

这是我的应用程序的预览:

谢谢你:)

【问题讨论】:

  • 我可以尝试为您指明正确的方向。您想要做的与riverpod 文档中的todos example 非常相似。您可以像对待bool completed 一样对待您的bool isFavoriteDoa。只需查看两个代码文件,然后尝试在您的应用中实现相同的解决方案。
  • @ambiguous58 哇,非常感谢您的建议。是的,我会为此学习:)

标签: flutter dart provider riverpod


【解决方案1】:

我推荐的方法是创建一个 StateNotifier 来处理状态以及与 SharedPreferences 的交互。以下内容也简化了小部件中的逻辑。

final sharedPrefs =
    FutureProvider<SharedPreferences>((_) async => await SharedPreferences.getInstance());

class FavoriteIds extends StateNotifier<List<String>> {
  FavoriteIds(this.pref) : super(pref?.getStringList("id") ?? []);

  static final provider = StateNotifierProvider<FavoriteIds, List<String>>((ref) {
    final pref = ref.watch(sharedPrefs).maybeWhen(
          data: (value) => value,
          orElse: () => null,
        );
    return FavoriteIds(pref);
  });

  final SharedPreferences? pref;

  void toggle(String favoriteId) {
    if (state.contains(favoriteId)) {
      state = state.where((id) => id != favoriteId).toList();
    } else {
      state = [...state, favoriteId];
    }
    // Throw here since for some reason SharedPreferences could not be retrieved
    pref!.setStringList("id", state);
  }
}

用法:

class DoaWidget extends ConsumerWidget {
  const DoaWidget({Key? key, required this.doa}) : super(key: key);

  final Doa doa;

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final favoriteIds = watch(FavoriteIds.provider);

    return IconButton(
      icon: favoriteIds.contains('') ? Icon(Icons.favorite) : Icon(Icons.favorite_border),
      color: favoriteIds.contains('') ? Colors.red : Colors.grey,
      onPressed: () => context.read(FavoriteIds.provider.notifier).toggle(doa.id.toString()),
    );
  }
}

【讨论】:

  • 对不起,我还是有点糊涂。这是我的两页代码(detailDoaPage.dart & favPage.dart)replit.com/join/nlzhbikh-nabilrei。你想帮助我用你的代码修改我的代码吗?谢谢你:)
  • 很高兴为您提供帮助,很高兴我们能让您的解决方案发挥作用!也感谢您向我介绍 replit 工具。
  • 您好,您是否可以帮助解决我想使用 Riverpod 的问题。 – stackoverflow.com/questions/70980002/…
猜你喜欢
  • 2021-07-15
  • 2020-10-20
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
相关资源
最近更新 更多