如何将 notifyListeners 方法传递给 onPressed 按钮函数?

How to pass a notifyListeners method to an onPressed button function?

我有一个 LoginButtonProvider class 并且 class 有两个用途。

首先:一旦用户在两个文本表单字段中都输入了内容,它应该向我的 LoginButton 小部件提供一个 onPressed 方法。一旦将 onPressed 函数分配给按钮,class 就会调用 notifyListeners() 方法。

第二:一旦用户按下该按钮并调用 onPressed 方法,它应该在该按钮内创建一个旋转的圆圈。一旦用户按下按钮,它还应该调用 notifyListeners() 以便将布尔标志 _isLoading 设置为 true。

问题是我不知道如何实现 onPressed 方法,以便在用户触发 onPressed 方法后,Consumer 小部件可以自行重建。我认为一旦用户按下按钮就永远不会调用 notifyListeners 因此旋转的圆圈永远不会出现在按钮上,但它应该! 我也试过发送对 notifyListeners 方法的引用。 当在 onPressed 函数中调用 notifyListeners() 时,小部件不会自行重建。这是为什么? 非常感谢您的帮助!

这是 LoginButtonProvider class。

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 中传递像 FocusNodecontextvalidator 这样的 Widget 逻辑实例,而是在按钮的 onPressed 处理程序中进行所有验证然后使用 Provider.

在 Notifier 中调用方法
...
  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();
        }
    );

  } 




LoginButtonProvider

class LoginButtonProvider with ChangeNotifier {

  TokenViewModel _tokenViewModel = new TokenViewModel();

  bool _isLoading = false;


  get isLoading => _isLoading;

  void updateButton(String email, String password)async {
          _isLoading = true; 
           notifyListeners();

           await _tokenViewModel.getToken(email ,password); /// not sure what this is, but if its an API call would not recommend passing in context and node again,

          _isLoading = false;
          notifyListeners();
    }

确保您的 MaterialApp 上方有 ChangeNotifierProvider<LoginButtonProvider> 以通过 Provider 访问。