Flutter 如何将notifyListeners方法传递给onPressed按钮函数?
我有一个LoginButtonProvider类,该类有两个用途 第一:一旦用户输入了两个文本表单字段,它应该为我的LoginButton小部件提供一个onPressed方法。一旦将onPressed函数分配给按钮,该类将调用notifyListeners()方法 第二:一旦用户按下该按钮并调用onPressed方法,它应该在该按钮内创建一个旋转圈。一旦用户按下按钮,它还应该调用notifyListeners(),以便将布尔标志_isLoading设置为true 问题是,我不知道如何实现onPressed方法,以便在用户触发onPressed方法后,消费者小部件能够重建自身。我认为,一旦用户按下按钮,就不会调用notifyListeners,因此按钮上不会出现旋转圈,但它应该会出现强> 我还尝试将引用发送到notifyListeners方法。在onPressed函数中调用notifyListeners()时,小部件不会重新构建自身。为什么呢? 非常感谢你的帮助 这是LoginButtonProvider类Flutter 如何将notifyListeners方法传递给onPressed按钮函数?,flutter,dart,button,provider,flutter-onpressed,Flutter,Dart,Button,Provider,Flutter Onpressed,我有一个LoginButtonProvider类,该类有两个用途 第一:一旦用户输入了两个文本表单字段,它应该为我的LoginButton小部件提供一个onPressed方法。一旦将onPressed函数分配给按钮,该类将调用notifyListeners()方法 第二:一旦用户按下该按钮并调用onPressed方法,它应该在该按钮内创建一个旋转圈。一旦用户按下按钮,它还应该调用notifyListeners(),以便将布尔标志_isLoading设置为true 问题是,我不知道如何实现onPr
class LoginButtonProvider with ChangeNotifier {
TokenViewModel _tokenViewModel = new TokenViewModel();
Function _onPressed;
bool _isLoading = false;
get onPressed => _onPressed;
get isLoading => _isLoading;
void updateButton(BuildContext context, FocusNode focusNode, Validator validator) {
if (!validator.areFieldsEmpty()) {
_onPressed = () {
if (validator.validateFields()) {
_isLoading = true;
notifyListeners();
_tokenViewModel.getToken(validator.email, validator.password, context, focusNode);
_isLoading = false;
notifyListeners();
} else {
SimpleShowDialog.createSimpleShowDialog(
title: "Invalid Input",
buttonText: "OK",
context: context,
message: validator.errorMessage,
focusNode: focusNode,
);
validator.reset();
}
};
notifyListeners();
} else {
_onPressed = null;
notifyListeners();
}
}
}
我认为问题在于,从未调用此方法,因为
onPressed
处理程序位于ChangeNotifier
中。
这完全是错误的做法。不要在ChangeNotifier
中传递小部件逻辑实例,如FocusNode
、context
、validator
,而是在按钮的onPressed
处理程序中执行所有验证,然后使用提供程序调用通知程序中的方法
...
Widget build(BuildContext context){
final login = Provider.of<LoginButtonProvider>(context);
return login.isLoading?
Center(child: CircularProgressIndicator()):
Flatbutton(
child: Text('Login')
onPressed :
validator.areFieldsEmpty()) ? /// Now the button should not be clickbale, till the field is filled.
null:
() {
// do all your validation here
if (!validator.areFieldsEmpty()) {
login.updateButton(validator.email, validator.password);
} else {
SimpleShowDialog.createSimpleShowDialog(
title: "Invalid Input",
buttonText: "OK",
context: context,
message: validator.errorMessage,
focusNode: focusNode,
);
validator.reset();
}
);
}
确保您的MaterialApp
上方有ChangeNotifierProvider
可通过提供者访问。我的结论是,一旦传入notifyListeners()方法,就不会从LoginButton内部调用它。你能解释一下我是如何做到这一点的吗?也许我应该传递一个处理函数?但是在这种情况下怎么做呢?非常感谢你抽出时间来检查我的问题。我明白你在说什么。我在读关于MVVM代码体系结构的书。他们指出,所有业务逻辑都应该在小部件UI之外。我有带有这些参数的updateButton方法,因为我想在小部件UI之外分配onPressed方法。如果我把所有的东西都放在小部件中,代码看起来就会膨胀。我通过在getToken()方法中调用notifyListeners()使代码正常工作,我刚刚在表单字段中注册了一个新的侦听器。我也遵循MVVM,根据业务逻辑,它可能是API调用和状态管理,但我认为验证应该发生在UI层本身。您甚至可以在表单中找到验证器。因此,只有值必须传递到下一层,而不是小部件或类的实例。特别是在flatter的情况下,您正在将太多不必要的内容传递到ChnageNotifier
,比如上下文和焦点节点,它们的生命周期应该在小部件层中。所以我想说,我的解决方案是更好的方法,因为我已经遵循了一段时间了。它运行得非常好@Aleksavujisic我当然同意你的观点!在阅读了更多关于MVVM的内容后,我现在对它有了更好的理解。你回答的问题是,按钮总是具有ON按下功能。我希望在表单中的两个文本字段都有用户输入的文本之前,按钮不可单击。@AleksaVujisic,这不是问题,您可以添加三元运算符使按钮不可单击。让我编辑我的答案。使用provider
和ChangeNotifier
查看博客文章,深入了解MVVM,非常感谢!我改变了我使用MVVM的方式,我这样做了,它更有条理,整体上更好!我会接受你的回答!
...
Widget build(BuildContext context){
final login = Provider.of<LoginButtonProvider>(context);
return login.isLoading?
Center(child: CircularProgressIndicator()):
Flatbutton(
child: Text('Login')
onPressed :
validator.areFieldsEmpty()) ? /// Now the button should not be clickbale, till the field is filled.
null:
() {
// do all your validation here
if (!validator.areFieldsEmpty()) {
login.updateButton(validator.email, validator.password);
} else {
SimpleShowDialog.createSimpleShowDialog(
title: "Invalid Input",
buttonText: "OK",
context: context,
message: validator.errorMessage,
focusNode: focusNode,
);
validator.reset();
}
);
}