已解决 – Flutter – setState 在第一次不更新 UI。

huangapple go评论69阅读模式
英文:

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才会更新,而submitRevieweditReview函数会正常调用和评估。

英文:

The setState method in my app is triggered when a submit button to a dialog is clicked

            TextButton(
              child: Text(&quot;SUBMIT&quot;),
              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&lt;UsersProvider&gt;(context, listen: false).user;
    final restaurant =
        Provider.of&lt;RestaurantProvider&gt;(context, listen: false).restaurant1;
    final comment = commentText.text;
    final rating = ratingValue;

    bool response =
        await Provider.of&lt;RestaurantReviewProvider&gt;(context, listen: false)
            .addReview(restaurant.id!, user.id!, rating, comment);

    if (response) {
      dx.showSuccessMsg(context, &quot;Completed&quot;, &quot;Thanks for your feedback&quot;);
    } else {
      dx.errorAlert(context, &quot;Already submit the feedback.&quot;);
    }
  }

  editReview() async {
    final review =
        Provider.of&lt;RestaurantReviewProvider&gt;(context, listen: false).review;
    final user = Provider.of&lt;UsersProvider&gt;(context, listen: false).user;
    final restaurant =
        Provider.of&lt;RestaurantProvider&gt;(context, listen: false).restaurant1;
    final comment = commentText.text;
    final rating = ratingValue;

    bool response = await Provider.of&lt;RestaurantReviewProvider&gt;(context,
            listen: false)
        .updateReview(review.id!, restaurant.id!, user.id!, rating, comment);

    if (response) {
      dx.showSuccessMsg(
          context, &quot;Update Successfull&quot;, &quot;Your feedback has been updated!&quot;);
    } else {
      dx.errorAlert(context, &quot;Invalid&quot;);
    }
  }

This is the UI I want to show the data:

  Widget showComment(BuildContext context, List&lt;dynamic&gt; 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(
                          &quot;${data[index].userFullName}&quot;,
                          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(&#39;dd/MM/yyyy&#39;).format(data[index].createdDate),
                      style: TextStyle(fontSize: 8.h, color: Colors.grey),
                    ),
                    SizedBox(height: 10.h),
                    Text(
                      &quot;${data[index].comment}&quot;,
                      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(&quot;SUBMIT&quot;),
              onPressed: () async {
                if (comment != null || rating != null) {
                 
                   await editReview();
                 setState(() {
                  });
                } else {
                  
                   await submitReview();
                   setState(() {
                  });
                }
              },
            ),

i hope this helps.

huangapple
  • 本文由 发表于 2023年6月8日 09:50:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76428106.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定