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

ListView.separated存在多余空白,搜索时条目显示异常如何修复?

问题修复方案

问题根源

你的代码出现空白间隙和搜索结果错位的核心原因:

  • 搜索时ListView.separated的itemCount依然使用原列表pressures的长度,不符合搜索条件的条目返回空Container(),这些空容器会占据列表位置,导致空白间隔。
  • 列表的separatorBuilder会在每个条目(包括空容器)之间生成15px的间距,进一步加剧多余空白。

具体修复步骤

1. 维护过滤后的可观察列表

因为你使用了GetX的Obx,所以创建一个响应式的过滤后列表,用来存储符合搜索条件的血压数据:

// 在你的ViewModel/State中添加
final filteredPressures = <PressureModel>[].obs;

2. 监听搜索输入,实时过滤数据

在初始化或页面创建时,先初始化过滤列表,并监听搜索输入的变化,动态更新过滤结果:

// 初始化时加载全部数据
filteredPressures.assignAll(pressures);

// 监听搜索输入框的变化(使用GetX的ever方法)
ever(textInput, (value) {
  if (value.isEmpty) {
    // 输入为空时显示全部数据
    filteredPressures.assignAll(pressures);
  } else {
    // 过滤符合条件的数据
    filteredPressures.assignAll(
      pressures.where((item) => 
        item.pressure.contains(value) || 
        item.date.toString().contains(value)
      ).toList(),
    );
  }
});

3. 修改条目构建方法,直接接收数据对象

把原来依赖索引的pressureItem方法改成接收PressureModel对象,避免索引错误:

Widget pressureItem(PressureModel pressure) {
  return Padding(
    padding: const EdgeInsets.only(left: 15.0, right: 15.0),
    child: Material(
      clipBehavior: Clip.antiAlias,
      borderRadius: BorderRadius.circular(15.0),
      color: const Color.fromARGB(255, 28, 28, 31),
      child: InkWell(
        onTap: () {},
        child: Padding(
          padding: const EdgeInsets.all(15.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    pressure.pressure,
                    style: GoogleFonts.roboto(
                      fontSize: 23,
                      color: Colors.white.withOpacity(0.9),
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                  Container(
                    width: 15.0,
                    height: 15.0,
                    decoration: BoxDecoration(
                        boxShadow: [
                          BoxShadow(
                              color: getPressureColor(
                                  double.parse(pressure.pressure.split('/')[0]),
                                  double.parse(pressure.pressure.split('/')[1].split('-')[0])),
                              blurRadius: 5.0)
                        ],
                        borderRadius: BorderRadius.circular(100.0),
                        color: getPressureColor(
                            double.parse(pressure.pressure.split('/')[0]),
                            double.parse(pressure.pressure.split('/')[1].split('-')[0]))),
                  ),
                ],
              ),
              const SizedBox(height: 5.0),
              Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  pressure.action.isEmpty
                      ? Container()
                      : Text(
                          pressure.action,
                          style: GoogleFonts.roboto(
                            fontSize: 16,
                            color: Colors.white.withOpacity(0.7),
                            fontWeight: FontWeight.w700,
                          ),
                        ),
                  Text(
                    '${DateFormat.MMMd('en_US').format(pressure.date)} в ${DateFormat.jm('en_US').format(pressure.date)}',
                    style: GoogleFonts.roboto(
                      fontSize: 12,
                      color: Colors.white.withOpacity(0.4),
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    ),
  );
}

4. 更新ListView.separated配置

将列表的数据源改为过滤后的列表,确保只渲染符合条件的条目:

body: Padding(
  padding: const EdgeInsets.only(bottom: 15.0),
  child: Obx(
    () => ListView.separated(
      itemCount: filteredPressures.length,
      itemBuilder: (context, index) {
        return pressureItem(filteredPressures[index]);
      },
      separatorBuilder: (context, index) => const SizedBox(height: 15.0),
    ),
  ),
),

修复效果

  • 搜索时只会渲染符合条件的条目,不再有空容器占据位置,空白间隙完全消失。
  • 搜索结果从列表开头开始显示,不会有错位问题。
  • 列表的分隔符只会出现在有效条目之间,布局更整洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:05:25