Nota Bene:我最终使用了ConsumerWidget而不是HookConsumerWidget,并且只使用了Riverpod 2.0类.


我很难理解为什么Riverpod和Hook的用户界面不刷新,特别是在使用HookConsumerWidgetProviderFamily的时候,传递一个参数.

一些精确度:MediaThumbnailMediaThumbnailAPI调用并设置了唯一键,MediaThumbnailAPI位于网格视图构建器内(网格视图构建器内的项可以独立重建而不重建整个网格视图吗?我认为这是可能的).

我的理解是,bool isFavorite = ref.watch(favoriteFamilyProvider(id)).isMediaFavorite(id);不会在应该长按的时候触发setState(相当于Riverpod钩子),但我不知道我的语法中缺少了什么.

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../../../favorite_provider.dart';
import 'package:universal_io/io.dart' as universal_io;

class MediaThumbnail extends HookConsumerWidget {
  final String id;
  final String fileExtension;
  final universal_io.File imageFile;
  final String urlEndpoint;
  final String description;
  final double thumbnailRadius;
  final String mimeType;

  const MediaThumbnail(this.imageFile, this.urlEndpoint, this.id,
      this.fileExtension, this.description, this.thumbnailRadius, this.mimeType,
      {Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    bool isFavorite = ref.watch(favoriteFamilyProvider(id)).isMediaFavorite(id); // probably the problematic line of code.
    return GestureDetector(
        behavior: HitTestBehavior.translucent,
        onLongPress: () {

          ref.read(favoriteProvider.notifier)
              .toggleFav(id, fileExtension, description); // this one works successfully and change the content of imageMetadataBox 
          isFavorite = ref.read(favoriteFamilyProvider(id)).isMediaFavorite(id); // the isFavorite value is correctly updated
          print("is favorite: $isFavorite");
        },
       
        child: Stack(children: [
          Container(
              constraints: const BoxConstraints.expand(),
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: FileImage(imageFile), fit: BoxFit.cover),
              )),
          if (isFavorite) // this does not refresh
            Positioned(
              top: 5,
              left: 60,
              right: .0,
              child: Center(
                child: Stack(
                  children: [
                    _buildIcon(16, Colors.white),
                    _buildIcon(13, Colors.pinkAccent),
                  ],
                ),
              ),
            )
        ]));
  }
}

favorite_provider.dart

final favoriteFamilyProvider =
Provider.family<FavoriteFamilyNotifier, String>(
        (_, myId) => FavoriteFamilyNotifier(myId));

class FavoriteFamilyNotifier extends StateNotifier<bool> {
  FavoriteFamilyNotifier(String myId) : super(false) {}

  bool isMediaFavorite(String myId) {
    Store store = objectbox.store;

    Box<MediaMetadata> imageMetadataBox = store.box<MediaMetadata>();

    final qBuilder =
       imageMetadataBox.query(MediaMetadata_.myId.equals(myId));
    final query = qBuilder.build();
    var results = query.find();
    bool isFavorite = results.isNotEmpty;
    print("$myId is favorite? $isFavorite");
    return isFavorite;
  }

非常感谢那些对这个图书馆有经验的人.

注:我使用"myid"是因为ObjectBox为其内部数据库保留了"id"关键字,因此MediaMetadata_.myId就像一个32长的字符串,而MediaMetadata_.id是一个无符号整数.

推荐答案

您的问题似乎是您使用Provider来实现一个扩展StateNotifier的类.要解决此问题,请将Provider更改为StateNotifierProvider.

我还想指出,StateNotifier是一种不受欢迎的做法.使用Notifier来实现您的FavoriteFamilyNotifier.

isMediaFavorite()方法中使用myId字段似乎也更符合逻辑,您在创建FavoriteFamilyNotifier(myId)时将其作为字段传递.Orgo 掉.family,因为如果您创建了一个包含FavoriteFamilyNotifier(String myId)的类,然后根本不使用该字段,那么它所扮演的角色就完全不清楚了.

而且不太清楚您为什么使用HookConsumerWidget,在本例中小部件中没有使用它.

Flutter相关问答推荐

如何增加容器高度?

当MyChangeNotifier更改时如何计算函数,而无需在构建方法中进行不必要的调用- Flutter

为什么我需要等待重新访问Firestore数据库,即使它已经做了之前?

设置Flutter 中的ListView.Builder()的最小高度

Flutter-Riverpod:如何只从提供者读取一次值

播放特定持续时间Flutter 的音频

带按钮的 Riverpod future Provider

以编程方式在 flutter 中安装 apk 时解析错误

无法从一个页面导航到下一个页面 (Flutter)

来自服务器的数据未分配给变量

splash_screen 没有被推送到登录页面

如何从 Flutter 中的 App2 远程点击 App1 中的按钮

Elevated 和 Outlined 按钮之间的动画

Flutter - 根据从第一个 DropdownButtonForm 中 Select 的内容在第二个 DropdownButton 上显示选项

flutter 中 // 和 /// 有什么区别

flutter 创建一个带有 2 个图标的按钮

Flutter snapShot.hasData 为假但响应有数据

Flutter 错误:正文可能正常完成,导致返回null

如何在 flutter 中过滤 DateTime(intl)?

如何获得Flutter 的时差?