1

我有一个 LoginButtonProvider 类,该类有两个目的。

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

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

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

这是 LoginButtonProvider 类。

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();
    }
  }
}
4

1 回答 1

0

我相信问题是这个方法永远不会被调用,因为onPressed处理程序在ChangeNotifier. 这是完全错误的方法。不要在你的内部传递 Widget 逻辑的实例,而是在FocusNode按钮的处理程序中进行所有验证,然后使用 Notifier 调用方法。contextvalidatorChangeNotifieronPressedProvider

...
  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();
    }

确保您有ChangeNotifierProvider<LoginButtonProvider>上述内容MaterialApp 可以通过Provider.

于 2020-10-10T04:34:21.833 回答