我非常熟悉提供程序包,并将其与ChangeNotifier相结合。
假设我有3个具有不同函数的getter和方法:
使用ChangeNotifer
import 'package:flutter/foundation.dart';
class GlobalChangeNotifier extends ChangeNotifier {
bool _isLoading = false;
bool _isImageLoading = false;
bool _isObsecurePassword = false;
bool get isLoading => _isLoading;
bool get isImageLoading => _isImageLoading;
bool get isObsecurePassword => _isObsecurePassword;
void setLoading(bool value) {
_isLoading = value;
notifyListeners();
}
void setImageLoading(bool value) {
_isImageLoading = value;
notifyListeners();
}
void setObsecurePassword(bool value) {
_isObsecurePassword = !value;
notifyListeners();
}
}
final globalChangeNotifier = GlobalChangeNotifier();如果我使用的是ChangeNotifier,我只需要创建一个文件,只需调用像globalChangeNotifier.METHOD()这样的方法或像globalChangeNotifier.value这样的值。
但是现在,我已经了解了河荚包,在文档中,它使用的是StateNotifier。
我想将以前的代码从ChangeNotifier迁移到StateNotifier。但据我理解,StateNotifier只能保存1种类型的数据,所以如果我想迁移上面的代码,我应该创建3个文件,比方说:
provider_isloading.dart,provider_isimageloading.dart和provider_obsecurepassword.dart。使用StateNotifier
// provider_isloading.dart
class IsImageLoading extends StateNotifier<bool> {
IsImageLoading() : super(false);
void toggleImageLoading(bool value) {
state = value;
}
}
final isImageLoadingProvider = StateNotifierProvider((ref) => IsImageLoading());
// provider_isimageloading.dart
class IsLoading extends StateNotifier<bool> {
IsLoading() : super(false);
void toggleLoading(bool value) => state = value;
}
final isLoadingProvider = StateNotifierProvider((ref) => IsLoading());
// provider_obsecurepassword.dart
class IsObsecurePassword extends StateNotifier<bool> {
IsObsecurePassword() : super(false);
void toggleObsecurePassword(bool value) {
state = !value;
}
}
final isObsecurePasswordProvider = StateNotifierProvider((ref) => IsObsecurePassword());我还需要创建一个文件来导出所有这些文件:
GlobalStateNotifer.dart
export './provider_loading.dart';
export './provider_imageloading.dart';
export './provider_obsecurepassword.dart';我的问题是,正如我前面所解释的那样,这是最好的做法吗?
我的文件夹结构

发布于 2020-07-21 14:49:13
在使用Riverpod时,在它们提供的类上创建静态提供者是非常有意义的。从您的示例中,您可以重构为:
class IsImageLoading extends StateNotifier<bool> {
IsImageLoading() : super(false);
static final provider = StateNotifierProvider((ref) => IsImageLoading());
void toggleImageLoading(bool value) {
state = value;
}
}您还应该考虑是否需要您的提供程序在实际使用的类之外可用。有一点告诉我,你可能不会在任何地方使用你的密码提供者,但你的登录页面。考虑在该类中创建私有提供程序。
但是,如果您希望保持当前的方法,则可以创建一个包含3个bool值的类A和一个扩展StateNotifier<A>的类。
例如:
enum LoadingType { A, B, C }
class LoadingToggles {
bool A, B, C;
LoadingToggles({this.A = false, this.B = false, this.C = false});
static final provider = StateNotifierProvider.autoDispose((ref) => LoadingState(LoadingToggles()));
}
class LoadingState extends StateNotifier<LoadingToggles> {
LoadingState(LoadingToggles state) : super(state ?? LoadingToggles());
void toggle(LoadingType type) {
switch (type) {
case LoadingType.A:
state.A = !state.A;
break;
case LoadingType.B:
state.B = !state.B;
break;
case LoadingType.C:
state.C = !state.C;
break;
default:
// Handle error state
}
}
}最后,我只想补充一下,可能有一种更好的方法来处理总体加载。考虑是否可以在Riverpod的AsyncValue中使用FutureProvider/StreamProvider,而不是手动切换加载状态。
发布于 2021-02-05 17:34:39
我认为您应该使用不可变的类,如下面的代码
@immutable
abstract class GlobalState {
const GlobalState();
}
class IsImageLoading extends GlobalState {
const IsImageLoading();
}
class IsLoading extends GlobalState {
const IsLoading();
}
class IsObsecurePassword extends GlobalState {
const IsObsecurePassword();
}您的StateNotifier将如下所示
class GlobalStateNotifier extends StateNotifier<GlobalState> {
GlobalStateNotifier(GlobalState state) : super(state);
void changeState(GlobalState newState) {
state = newState;
}
}发布于 2021-07-01 05:22:16
非常晚的响应,但我现在搜索的是相同的东西,我没有找到一种正确的方式来使用riverpod或StateNotifier,但是您可能应该像使用ChangeNotifier那样使用,或者对于flutter_bloc用户应该使用像flutter_bloc逻辑一样的.或者两者都是。
在本例中,根据我所读到的,我将只使用一个dart文件来放置所有这些代码,比如您的changenotifier类,并为IsImageLoading, isLoading, isObscurePassword创建简单的状态提供程序
在另一个MyViewProvider类中,您可以更改这些statesProvider的状态,或者不创建这些状态并在视图中直接更改状态。
final isImageLoadingProvider = StateProvider((ref) => false);
final isLoadingProvider = StateProvider((ref) => false);
final isObscurePasswordProvider = StateProvider((ref) => false);
final myViewProvider = Provider<MyViewProvider>((ref) {
return MyViewProvider(ref.read);
});
class MyViewProvider {
MyViewProvider(this._read);
final Reader _read;
void setLoading(bool value) {
_read(isLoadingProvider).state = value;
}
void setImageLoading(bool value) {
_read(isImageLoadingProvider).state = value;
}
void setObscurePassword() {
final isObscure = _read(isLoadingProvider).state;
_read(isObscurePasswordProvider).state = !isObscure;
}
}如有任何意见或改进,我将不胜感激。
https://stackoverflow.com/questions/62946841
复制相似问题