我想听一些关于流事件的更改。现在,我使用提供程序的StreamProvider.value()来完成此操作。这是一个API调用。现在,我想要的是,如果流的事件进入加载状态,我要显示正在加载,如果有任何失败,我想调用失败方法。如果成功,那么我想调用成功方法。
我创建了一个单独的窗口小部件按钮,它是Consumer,可以根据流的事件进行更改。我已经在消费者的builder方法内添加了SchedulerBinding.instance.addPostFrameCallback(),但是随着小部件的重建它被调用了很多次,并触发了最后一个事件,这是不希望的。
所以我的问题是流的事件更改,如何调用这些方法或显示Toast并更新UI?
ConsumerButtonWithProgress
class ConsumerButtonWithProgress<T> extends StatelessWidget {
final void Function(BuildContext context) onTap;
final void Function(T result) onSuccess;
final void Function() onError;
final void Function() onNoInternet;
ConsumerButtonWithProgress(
this.onTap,
this.onSuccess, {
this.onError,
this.onNoInternet,
}) : assert(T != dynamic);
@override
Widget build(BuildContext context) {
return Consumer<APIResult<T>>(
builder: (BuildContext context, APIResult<T> value, Widget child) {
SchedulerBinding.instance.addPostFrameCallback((_) {
if (value != null) {
if (value.apiResultType == APIResultType.NO_INTERNET) {
showSnackBar(context, value.message);
if (onNoInternet != null) Function.apply(onNoInternet, []);
} else if (value.apiResultType == APIResultType.FAILURE) {
showSnackBar(context, value.message);
if (onError != null) Function.apply(onError, []);
} else if (value.apiResultType == APIResultType.SUCCESS) {
showSnackBar(context, value.message);
Function.apply(onSuccess, [value.data]);
}
}
});
return Container(
width: MediaQuery.of(context).size.width,
height: Dimensions.h50,
child: OutlineButton(
color: LocalColors.PRIMARY_COLOR,
textColor: LocalColors.PRIMARY_COLOR,
disabledBorderColor: LocalColors.PRIMARY_COLOR,
highlightedBorderColor: LocalColors.PRIMARY_COLOR,
borderSide: BorderSide(color: LocalColors.PRIMARY_COLOR),
child: APIResult.isLoading(value)
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: Dimensions.h25,
height: Dimensions.h25,
child: CircularProgressIndicator(
strokeWidth: 3,
)),
],
)
: Text(
"Button",
style: TextStyle(
fontSize: Dimensions.sp15,
fontWeight: FontAsset.DEMI_BOLD,
),
),
onPressed: () {
if (onTap != null &&
(value == null ||
value.apiResultType != APIResultType.LOADING))
Function.apply(onTap, [context]);
}),
);
},
);
}
}
这就是我在小部件中使用该按钮的方式
class ForgotPasswordScreen extends StatefulWidget {
@override
_ForgotPasswordScreenState createState() => _ForgotPasswordScreenState();
}
class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
ForgotPasswordProvider _forgotPasswordProvider;
@override
void initState() {
super.initState();
_forgotPasswordProvider = ForgotPasswordProvider();
}
@override
Widget build(BuildContext mainContext) {
return Scaffold(body: Builder(builder: (BuildContext context) {
return StreamProvider.value(
lazy: true,
value: _forgotPasswordProvider.forgotPasswordStream,
child: ConsumerButtonWithProgress<SignInResponseEntity>(
_onSendLinkClick,
(result) {},
),
);
}));
}
void _onSendLinkClick(BuildContext context) {
if (_isDataValid(context)) {
_forgotPasswordProvider.callForgotPasswordAPI();
}
}
}
那么,在流的事件更新后以及在更新UI后,有什么方法可以调用方法并从通用小部件中显示吐司?就像在SchedulerBinding.instance.addPostFrameCallback()块中执行代码一样。