英文:
Solved - flutter - setState does not update UI in the first time
问题
在我的应用程序中,当点击对话框的提交按钮时,会触发setState方法。
TextButton(
  child: Text("提交"),
  onPressed: () async {
    if (comment != null || rating != null) {
      setState(() {
        editReview();
      });
    } else {
      setState(() {
        submitReview();
      });
    }
  },
),
调用了编辑评论和提交评论的函数:
submitReview() async {
  final user = Provider.of<UsersProvider>(context, listen: false).user;
  final restaurant = Provider.of<RestaurantProvider>(context, listen: false).restaurant1;
  final comment = commentText.text;
  final rating = ratingValue;
  bool response = await Provider.of<RestaurantReviewProvider>(context, listen: false)
      .addReview(restaurant.id!, user.id!, rating, comment);
  if (response) {
    dx.showSuccessMsg(context, "已完成", "感谢您的反馈");
  } else {
    dx.errorAlert(context, "已提交反馈");
  }
}
editReview() async {
  final review = Provider.of<RestaurantReviewProvider>(context, listen: false).review;
  final user = Provider.of<UsersProvider>(context, listen: false).user;
  final restaurant = Provider.of<RestaurantProvider>(context, listen: false).restaurant1;
  final comment = commentText.text;
  final rating = ratingValue;
  bool response = await Provider.of<RestaurantReviewProvider>(context, listen: false)
      .updateReview(review.id!, restaurant.id!, user.id!, rating, comment);
  if (response) {
    dx.showSuccessMsg(
        context, "更新成功", "您的反馈已更新!");
  } else {
    dx.errorAlert(context, "无效");
  }
}
这是我想要显示数据的UI:
Widget showComment(BuildContext context, List<dynamic> data) {
  return SizedBox(
      child: ListView.builder(
          itemCount: data.length,
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              margin: EdgeInsets.only(top: 10.h),
              padding: EdgeInsets.all(10.h),
              width: MediaQuery.of(context).size.width,
              height: 80.h,
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(10),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Text(
                        "${data[index].userFullName}",
                        style: TextStyle(
                          fontSize: 12.h,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Spacer(),
                      RatingBar(
                        ignoreGestures: true,
                        initialRating: data[index].rating,
                        allowHalfRating: false,
                        direction: Axis.horizontal,
                        itemCount: 5,
                        itemSize: 15,
                        ratingWidget: RatingWidget(
                          full: Icon(Icons.star_rounded, color: Colors.yellow),
                          half: Icon(Icons.star_half_rounded, color: Colors.yellow),
                          empty: Icon(Icons.star_border_rounded, color: Colors.black),
                        ),
                        onRatingUpdate: (rating) {},
                      ),
                    ],
                  ),
                  SizedBox(height: 4.h),
                  Text(
                    DateFormat('dd/MM/yyyy').format(data[index].createdDate),
                    style: TextStyle(fontSize: 8.h, color: Colors.grey),
                  ),
                  SizedBox(height: 10.h),
                  Text(
                    "${data[index].comment}",
                    style: TextStyle(
                      fontSize: 10.h,
                    ),
                  ),
                ],
              ),
            );
          }));
}
只有当我点击提交按钮两次时,UI才会更新,而submitReview和editReview函数会正常调用和评估。
英文:
The setState method in my app is triggered when a submit button to a dialog is clicked
            TextButton(
              child: Text("SUBMIT"),
              onPressed: () async {
                if (comment != null || rating != null) {
                  setState(() {
                    editReview();
                  });
                } else {
                  setState(() {
                    submitReview();
                  });
                }
              },
            ),
The edit review and submit review function is called:
  submitReview() async {
    final user = Provider.of<UsersProvider>(context, listen: false).user;
    final restaurant =
        Provider.of<RestaurantProvider>(context, listen: false).restaurant1;
    final comment = commentText.text;
    final rating = ratingValue;
    bool response =
        await Provider.of<RestaurantReviewProvider>(context, listen: false)
            .addReview(restaurant.id!, user.id!, rating, comment);
    if (response) {
      dx.showSuccessMsg(context, "Completed", "Thanks for your feedback");
    } else {
      dx.errorAlert(context, "Already submit the feedback.");
    }
  }
  editReview() async {
    final review =
        Provider.of<RestaurantReviewProvider>(context, listen: false).review;
    final user = Provider.of<UsersProvider>(context, listen: false).user;
    final restaurant =
        Provider.of<RestaurantProvider>(context, listen: false).restaurant1;
    final comment = commentText.text;
    final rating = ratingValue;
    bool response = await Provider.of<RestaurantReviewProvider>(context,
            listen: false)
        .updateReview(review.id!, restaurant.id!, user.id!, rating, comment);
    if (response) {
      dx.showSuccessMsg(
          context, "Update Successfull", "Your feedback has been updated!");
    } else {
      dx.errorAlert(context, "Invalid");
    }
  }
This is the UI I want to show the data:
  Widget showComment(BuildContext context, List<dynamic> data) {
    return SizedBox(
        child: ListView.builder(
            itemCount: data.length,
            shrinkWrap: true,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                margin: EdgeInsets.only(top: 10.h),
                padding: EdgeInsets.all(10.h),
                width: MediaQuery.of(context).size.width,
                height: 80.h,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        Text(
                          "${data[index].userFullName}",
                          style: TextStyle(
                            fontSize: 12.h,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        Spacer(),
                        RatingBar(
                          ignoreGestures: true,
                          initialRating: data[index].rating,
                          allowHalfRating: false,
                          direction: Axis.horizontal,
                          itemCount: 5,
                          itemSize: 15,
                          ratingWidget: RatingWidget(
                            full:
                                Icon(Icons.star_rounded, color: Colors.yellow),
                            half: Icon(Icons.star_half_rounded,
                                color: Colors.yellow),
                            empty: Icon(Icons.star_border_rounded,
                                color: Colors.black),
                          ),
                          onRatingUpdate: (rating) {},
                        ),
                      ],
                    ),
                    SizedBox(height: 4.h),
                    Text(
                      DateFormat('dd/MM/yyyy').format(data[index].createdDate),
                      style: TextStyle(fontSize: 8.h, color: Colors.grey),
                    ),
                    SizedBox(height: 10.h),
                    Text(
                      "${data[index].comment}",
                      style: TextStyle(
                        fontSize: 10.h,
                      ),
                    ),
                  ],
                ),
              );
            }));
  }
The UI updates only if I click the submit button two times, while the submitReview and editReview function is called and evaluated normally.
答案1
得分: 0
我认为你应该在调用setState之前等待函数的调用位置,你可以尝试以下代码。
TextButton(
  child: Text("提交"),
  onPressed: () async {
    if (comment != null || rating != null) {
      await editReview();
      setState(() {});
    } else {
      await submitReview();
      setState(() {});
    }
  },
),
希望这有所帮助。
英文:
i think you should await where you call your functions before calling setState, you can try the code below.
 TextButton(
              child: Text("SUBMIT"),
              onPressed: () async {
                if (comment != null || rating != null) {
                 
                   await editReview();
                 setState(() {
                  });
                } else {
                  
                   await submitReview();
                   setState(() {
                  });
                }
              },
            ),
i hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论