Nota Bene:我最终使用了ConsumerWidget
而不是HookConsumerWidget
,并且只使用了Riverpod 2.0类.
我很难理解为什么Riverpod和Hook的用户界面不刷新,特别是在使用HookConsumerWidget
和ProviderFamily
的时候,传递一个参数.
一些精确度:MediaThumbnail
由MediaThumbnailAPI
调用并设置了唯一键,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
是一个无符号整数.