如何在按钮单击 FLUTTER 上刷新列表小部件数据

Posted

技术标签:

【中文标题】如何在按钮单击 FLUTTER 上刷新列表小部件数据【英文标题】:How to refresh a list widget data on a button click FLUTTER 【发布时间】:2021-10-10 12:04:09 【问题描述】:

我的 Flutter 应用显示一个空间的预订情况,数据来自一个 rest api。

屏幕具有垂直和水平列表视图。

水平列表视图包含 14 个按钮,用户可以决定要在垂直列表视图上显示哪些天的预订。我遇到的问题是我无法通过单击按钮来刷新垂直列表视图状态以显示正确的日期。

这是我目前所在的位置:

垂直列表视图:

Widget bookingListView(List data, BuildContext context) 
    if (data.isNotEmpty) 
        return Container(
          key: UniqueKey(),
          child: Scrollbar(
            showTrackOnHover: true,
            isAlwaysShown: true,
            controller: _horizontalScrollController,
            radius: Radius.circular(32),
            thickness: 5.0,
            child: SingleChildScrollView(
              child: ListView.builder(
                  scrollDirection: Axis.vertical,
                  controller: _horizontalScrollController,
                  shrinkWrap: true,
                  physics: NeverScrollableScrollPhysics(),
                  padding: EdgeInsets.only(left: 8.0, right: 6.0),
                  itemCount: data.length,
                  itemBuilder: (context, int index) 
                    Bookings booking = data[index];
                    String fromDate = booking.from;
                    String toDate = booking.to;

                    DateFormat inputFormat = DateFormat('yyyy/MM/dd HH:mm:ss Z');

                    DateTime fromD = inputFormat.parse(fromDate)
                        .toUtc()
                        .add(new Duration(hours: 2));
                    DateTime toD = inputFormat.parse(toDate).toUtc().add(
                        new Duration(hours: 2));

                    final frmDt = fromD.toLocal();
                    final toDt = toD.toLocal();

                    String from = DateFormat('HH:mm').format(frmDt);
                    String to = DateFormat('HH:mm').format(toDt);

                    return Column(
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(left: 22),
                          child: ListTile(
                            title: Row(children: [
                              Text(
                                "$from",
                                style: TextStyle(
                                    fontWeight: FontWeight.w400,
                                    fontSize: 48.0,
                                    color: Color(0xfff2f2f2)),
                              ),
                              Padding(
                                padding: const EdgeInsets.only(
                                    left: 6.0, right: 6.0),
                                child: Text(
                                  "-",
                                  style: TextStyle(
                                      fontWeight: FontWeight.w400,
                                      fontSize: 48.0,
                                      color: Color(0xfff2f2f2)),
                                ),
                              ),
                              Text(
                                "$to",
                                style: TextStyle(
                                    fontWeight: FontWeight.w400,
                                    fontSize: 48.0,
                                    color: Color(0xfff2f2f2)),
                              ),
                            ]),
                            subtitle: Column(
                              crossAxisAlignment: CrossAxisAlignment
                                  .start,
                              children: [
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 6.0),
                                  child: Text(
                                    booking.membership.name == null
                                        ? ""
                                        : booking.membership.name,
                                    style: TextStyle(
                                        fontSize: booking.membership.name == null
                                            ? 0
                                            : 40.0,
                                        fontWeight: FontWeight.w300,
                                        color: Color(0xfff2f2f2)),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 6.0),
                                  child: Text(
                                    booking.title == null
                                        ? ""
                                        : booking.title ,
                                    style: TextStyle(
                                        fontSize:
                                        booking.title  == null
                                            ? 0
                                            : 40.0,
                                        fontWeight: FontWeight.w300,
                                        color: Color(0xfff2f2f2)),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                        Divider(
                          color: Colors.white,
                          indent: 10.0,
                          endIndent: 10.0,
                          thickness: 0.2,
                        )
                      ],
                    );
                  ),
            ),
          ),
        );
       else if (data.isEmpty) 
        return Container(
          child: Center(
            heightFactor: 7,
            child: Text(
              "noBooking".tr().toString(),
              style: TextStyle(
                  fontSize: 46.0,
                  fontWeight: FontWeight.w300,
                  color: Colors.white),
            ),
          ),
        );
      
      return Center(child: CircularProgressIndicator());
    

和水平列表视图:

Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FittedBox(
                                fit: BoxFit.fitHeight,
                                child: OutlinedButton(
                                  onPressed: () async 
                                    var from =
                                        "$formatFrom.format(DateTime.now())";
                                    var to =
                                        "$formatTo.format(DateTime.now()) 23:59";

                                    String fromDate = from.toString();
                                    String toDate = to.toString();

                                    final SharedPreferences
                                        sharedPreferences =
                                        await SharedPreferences.getInstance();
                                    sharedPreferences.setString(
                                        "from", fromDate);
                                    sharedPreferences.setString("to", toDate);

                                    setState(() 
                                      selectedIndex = 0;
                                      var format = new DateFormat('MM/dd');
                                      formattedDate =
                                          format.format(DateTime.now());
                                      print(selectedIndex);
                                      Network.getBookings();
                                    );

                                  ,
                                  style: OutlinedButton.styleFrom(
                                      padding: EdgeInsets.fromLTRB(
                                          26.0, 20.0, 26.0, 20.0),
                                      backgroundColor: selectedIndex == 0
                                          ? Color(0xfff78848)
                                          : Color(0x66404142),
                                      side: BorderSide(color: Colors.white)),
                                  child: FittedBox(
                                    fit: BoxFit.fitHeight,
                                    child: Text(dayOne.toString(),
                                        style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 22.0)),
                                  ),
                                ),
                              ),
                            ),

剩下的 13 个按钮与这个按钮的作用相同,只是日期时间值不同。

【问题讨论】:

【参考方案1】:

当您向列表中添加新项目时,您必须在本地将项目添加到您的列表中,例如 list.add(newItem),然后您必须调用 setState(),它将重建您的列表并在屏幕上呈现新项目

另一种解决方案:如果要刷新整个页面,则可以清除先前的列表并切换加载变量,然后调用 getDate() 以获取新添加的数据。

【讨论】:

我的数据来自api调用,我没有在本地添加数据到列表中 是的,您可以...您将所有 API 响应保存在某个局部变量中。所以现在你有了所有的数据,所以你可以用它做任何你想做的事情

以上是关于如何在按钮单击 FLUTTER 上刷新列表小部件数据的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:在 Navigation.pop 上刷新父小部件

如何根据 Flutter 中的按钮单击向上和向下移动一个小部件?

Flutter 小部件显示在所有屏幕上

在 Flutter 中按下按钮时将新的小部件作为列表插入

更新小部件列表视图

在Flutter中刷新小部件外的列表视图?