【问题标题】:Dialog state not updating when notifyListeners() is called调用 notifyListeners() 时对话框状态未更新
【发布时间】:2019-11-21 09:03:42
【问题描述】:

我正在使用providers 来管理我的颤振应用程序中的状态。我有一个对话,最初应该显示一个 CircularProgressBar,然后是一些内容。当我需要 CircularProgressBar 更改为内容时,我正在调用 notifyListeners(),但这似乎没有任何作用。这是我的一些代码,如果您需要再看,请告诉我。

显示对话框调用的方法:

displayDialog() {
  return showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return ChangeNotifierProvider<CreateAccountProvider>(
        builder: (_) => CreateAccountProvider(),
        child: CreateNewUserDialog(),
      );
    },
  );
}

final createAccountButton = Material(
  elevation: 5.0,
  color: Colors.lightGreen,
  child: MaterialButton(
    minWidth: MediaQuery.of(context).size.width,
    padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
    onPressed: () {
      createAccountProvider.createAccountClicked(context);
      displayDialog();
    },
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Icon(
          Icons.play_arrow,
          color: Colors.white,
        ),
        SizedBox(
          width: 5,
        ),
        Text(
          "Create an account",
          textAlign: TextAlign.center,
          style: TextStyle(color: Colors.white),
        ),
      ],
    ),
  ),
);

提供者中的相关代码:

// initial values for loading and loadingMessage
bool loading = false;
String loadingMessage;

void createAccountClicked(BuildContext context) {
  print("Create account clicked");
  validateAllFields();

  if (name != null &&
      email != null &&
      password != null &&
      confirmPassword != null) {

    loading = true;
    loadingMessage = "Creating new user";
    notifyListeners(); // <- nothing happens when this is called :(

    RestEndpoints.createNewUser(name, email, password, confirmPassword, "on")
        .then(createUserSuccess, onError: createUserError);
  }
}

void createUserSuccess(response) {
  print(response.data);
  if (response.data["status"] == "OK") {
    loading = false;
    notifyListeners();
  }
}

void createUserError(error) {
  loading = false;
  print("Error creating new user: ${error.toString()}");
  notifyListeners();
}

对话框的相关位:

@override
Widget build(BuildContext context) {
  final createAccountProvider = Provider.of<CreateAccountProvider>(context);

  // ...

  return AlertDialog(
    content: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Visibility(
          visible: createAccountProvider.loading, //<-- this is never visible
          child: Loading(createAccountProvider.loadingMessage),
        ),
        Visibility(
          visible: !createAccountProvider.loading, //<-- this is always visible
          child: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                SizedBox(height: 30),
                title,
                SizedBox(height: 30),
                subText,
                SizedBox(height: 30),
                confirmCodeTextField,
                SizedBox(height: 50),
                infoBox,
                newVerificationCode,
                continueButton
              ],
            ),
          ),
        ),
      ],
    ),
  );
}

问题:如何在调用 notifyListeners() 时更新我的​​对话?

【问题讨论】:

  • 您的 [Provider.of()] 方法在哪里,您的 [Provider] 在哪里(例如,ChangeNotifierProvider、StreamProvider 等)
  • ChangeNotifierProvider 在 displayDialog 方法中。我已将 Provider.of 部分代码添加到对话框中。
  • [ChangeNotifierProvider] 提供者一个 CreateAccountDialogProvider,[Provider.of()] 尝试获取 CreateAccountProvider,所以我想,也许你应该调用CreateAccountProvider 类中的 notifyListeners() 方法,而不是 CreateAccountDialogProvider
  • 对不起,我的错。没有 CreateAccountDialogProvider。只有 CreateAccountProvider。我已经更新了我的代码。
  • displayDialog() { return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return StatefulBuilder(builder: (context, state) { return ChangeNotifierProvider&lt;CreateAccountProvider&gt;( builder: (_) =&gt; CreateAccountProvider(), child: CreateNewUserDialog(), ); }); }); } //尝试在 //method 和 via state(() 中都传递状态{//尝试停止加载方法}

标签: flutter dart flutter-provider


【解决方案1】:

在这一行之后:

notifyListeners(); // <- nothing happens when this is called :(

您的线路可能会立即在此处调用loading = false;

RestEndpoints.createNewUser(name, email, password, confirmPassword, "on")
        .then(createUserSuccess, onError: createUserError);

可能你有某种错误,所以createUserError 可能会被立即调用,这会在此处设置loading = false;

void createUserError(error) {
  loading = false;
  print("Error creating new user: ${error.toString()}");
  notifyListeners();
}

尝试在没有此行的情况下运行您的代码:

RestEndpoints.createNewUser(name, email, password, confirmPassword, "on")
        .then(createUserSuccess, onError: createUserError);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-30
    • 2021-12-23
    • 2013-03-10
    • 2012-11-23
    • 2020-11-19
    • 1970-01-01
    • 2019-12-07
    • 2019-10-10
    相关资源
    最近更新 更多