You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter FutureBuilder逻辑优化:加载时空白,无数据时显示AnyNotification

解决方案:调整FutureBuilder逻辑实现加载时无内容、空数据时显示占位组件

修改后的代码如下:

child: FutureBuilder(
  future: fetchNotifications(widget.usuarioId),
  builder: (context, snapshot) {
    // 加载过程中返回空组件,不显示任何内容
    if (snapshot.connectionState == ConnectionState.waiting) {
      return SizedBox.shrink();
    }

    // 处理数据加载成功的情况
    if (snapshot.hasData) {
      List<dynamic>? filteredList = snapshot.data as List;
      
      // 数据为空时显示AnyNotification
      if (filteredList.isEmpty) {
        return AnyNotification();
      }

      // 数据存在时渲染通知列表
      return ListView.separated(
        separatorBuilder: (BuildContext context, int index) =>
            new Divider(
          color: Colors.black26,
          thickness: 0.5,
        ),
        itemCount: filteredList.length,
        shrinkWrap: true,
        itemBuilder: (BuildContext context, index) {
          NotificationModelo notificacion = filteredList[index];
          var textoNot = notificacion.texto;

          print("texto ${notificacion.texto}");
          if (notificacion.texto == "New files available for you" &&
              _fr) {
            textoNot = "Nouveaux fichiers disponibles pour vous";
          }

          return GestureDetector(
            onTap: () {},
            child: Container(
              height: 50,
              width: MediaQuery.of(context).size.width,
              color: Colors.white,
              child: GestureDetector(
                onTap: () {
                  if (notificacion.categoria == "Travel Document") {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =>
                                BDTravelDocumentsNuevo()));
                  }
                  if (notificacion.categoria == "Itinerary") {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) => BDItineraryNuevo()));
                  }
                  if (notificacion.categoria == "Experience") {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =>
                                BDExperiencesNuevo()));
                  }
                  if (notificacion.categoria == "News and Promos") {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =>
                                PrivateAreaNuevoDos()));
                  }
                },
                child: Padding(
                  padding: const EdgeInsets.only(left: 8.0, right: 8.0),
                  child: Card(
                      elevation: 0,
                      child: Padding(
                        padding: const EdgeInsets.all(2.0),
                        child: Container(
                          width: MediaQuery.of(context).size.width,
                          child: Center(
                            child: new Row(
                              mainAxisAlignment:
                                  MainAxisAlignment.start,
                              children: [
                                SizedBox(
                                  width: 10,
                                ),
                                notificacion.categoria ==
                                        "Travel Document"
                                    ? CircleAvatar(
                                        radius: 20.0,
                                        backgroundImage: AssetImage(
                                            "assets/item2.png"),
                                        backgroundColor:
                                            Colors.transparent,
                                      )
                                    : notificacion.categoria ==
                                            "Itinerary"
                                        ? CircleAvatar(
                                            radius: 20.0,
                                            backgroundImage: AssetImage(
                                                "assets/item3.png"),
                                            backgroundColor:
                                                Colors.transparent,
                                          )
                                        : notificacion.categoria ==
                                                "Experience"
                                            ? CircleAvatar(
                                                radius: 20.0,
                                                backgroundImage: AssetImage(
                                                    "assets/item4.png"),
                                                backgroundColor:
                                                    Colors.transparent,
                                              )
                                            : CircleAvatar(
                                                radius: 20.0,
                                                backgroundImage: AssetImage(
                                                    "assets/logolc.png"),
                                                backgroundColor:
                                                    Colors.transparent,
                                              ),
                                SizedBox(
                                  width: 15,
                                ),
                                Row(
                                  mainAxisAlignment:
                                      MainAxisAlignment.start,
                                  crossAxisAlignment:
                                      CrossAxisAlignment.center,
                                  children: [
                                    Container(
                                      width: 199,
                                      height: 40,
                                      child: Column(
                                        mainAxisAlignment:
                                            MainAxisAlignment.center,
                                        crossAxisAlignment:
                                            CrossAxisAlignment.start,
                                        children: [
                                          Text(
                                            "${textoNot}",
                                            textAlign: TextAlign.start,
                                            maxLines: 1,
                                            overflow:
                                                TextOverflow.ellipsis,
                                            style: TextStyle(
                                                fontSize: 15,
                                                fontWeight:
                                                    FontWeight.bold),
                                          ),
                                        ],
                                      ),
                                    ),
                                  ],
                                ),
                                Spacer(),
                                GestureDetector(
                                  onTap: () {},
                                  child: notificacion.categoria ==
                                          "Push"
                                      ? Container()
                                      : IconButton(
                                          onPressed: () {
                                            if (notificacion
                                                    .categoria ==
                                                "Travel Document") {
                                              Navigator.push(
                                                  context,
                                                  MaterialPageRoute(
                                                      builder: (context) =>
                                                          BDTravelDocumentsNuevo()));
                                            }
                                            if (notificacion
                                                    .categoria ==
                                                "Itinerary") {
                                              Navigator.push(
                                                  context,
                                                  MaterialPageRoute(
                                                      builder: (context) =>
                                                          BDItineraryNuevo()));
                                            }
                                            if (notificacion
                                                    .categoria ==
                                                "Experience") {
                                              Navigator.push(
                                                  context,
                                                  MaterialPageRoute(
                                                      builder: (context) =>
                                                          BDExperiencesNuevo()));
                                            }
                                            if (notificacion
                                                    .categoria ==
                                                "News and Promos") {
                                              Navigator.push(
                                                  context,
                                                  MaterialPageRoute(
                                                      builder: (context) =>
                                                          PrivateAreaNuevoDos()));
                                            }
                                          },
                                          icon: Icon(
                                            Icons.arrow_forward_ios,
                                          )),
                                )
                              ],
                            ),
                          ),
                        ),
                      )),
                ),
              ),
            ),
          );
        },
      );
    }

    // 处理加载错误的情况(可选,可根据需求替换为错误提示组件)
    return SizedBox.shrink();
  }),

关键修改说明:

  1. 加载状态处理:新增if (snapshot.connectionState == ConnectionState.waiting)判断,返回SizedBox.shrink()(完全不占空间的空组件),实现加载过程中无任何内容显示。
  2. 空数据判断:在获取到数据后,先检查列表是否为空,为空则返回AnyNotification(),满足空数据时显示占位组件的需求。
  3. 错误状态兜底:最后增加了默认返回空组件的逻辑,避免数据加载失败时出现异常显示,也可根据需求替换为错误提示组件。

内容的提问来源于stack exchange,提问作者mvasco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:42:26