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

如何将SearchField容器置于RefreshIndicator组件上方?Flutter/Dart

解决方案

方案1:搜索框固定在顶部(不随列表滚动)

将搜索框与RefreshIndicator放入Column容器,同时用Expanded包裹RefreshIndicator让其占据剩余空间。这种方式下搜索框会固定在界面顶部,下拉刷新仅作用于下方的列表区域。

完整代码示例:

Column(
  children: [
    // 你的搜索框Container
    Container(
      height: widget.appController.queryData.size.height/12,
      width: widget.appController.queryData.size.width * (9/10),
      margin: EdgeInsets.all(5.0),
      decoration: BoxDecoration(
          color: widget.appController.themeController.appWhiteLightColor,
          boxShadow: [
            BoxShadow(
              color: widget.appController.themeController.appGreyLightColor.withOpacity(0.6),
              spreadRadius: 1,
              blurRadius: 1,
              offset: Offset(0, 2), // changes position of shadow
            ),
          ],
          shape: BoxShape.rectangle,
          border: Border.all(
            color: Colors.transparent,
          ),
          borderRadius: BorderRadius.all(Radius.circular(10))
      ),
      child:Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children:[
            Container(
              width: widget.appController.queryData.size.width * (7/10),
              child: searchTextField,
            ),
            Container(
              child: IconButton(
                color: widget.appController.themeController.appBlackDeepColor,
                tooltip: 'Search',
                icon: const Icon(Icons.search),
                iconSize: 32 * this.unitHeightValue,
                onPressed: () {
                  this.evseSearchField = myController.text;
                  showEvsePanels();
                },
              ),
            ),
          ]
      ),
    ),
    // 包裹Expanded的RefreshIndicator
    Expanded(
      child: RefreshIndicator(
        onRefresh: refresh,
        child: ListView.separated(
            separatorBuilder: (context, index) => Divider(),
            controller: controller,
            padding: const EdgeInsets.all(8),
            itemCount: evsePanels.length + 1,
            itemBuilder: (context, index) {
              if (index < evsePanels.length) {
                return evsePanels[index];
              } else {
                return  Padding(
                  padding: const EdgeInsets.symmetric(vertical: 32),
                  child: Center(
                    child: hasMore
                        ? const CircularProgressIndicator()
                        : const Text('No more data to load'),
                  ),
                );
              }
            }
        ),
      ),
    ),
  ],
)

方案2:搜索框随列表滚动(下拉刷新覆盖整个区域)

如果希望下拉刷新时搜索框也跟随列表滚动,可将搜索框作为ListView.separated的第一个列表项,让整个列表(包含搜索框)都处于RefreshIndicator的作用范围内。

修改后的代码示例:

RefreshIndicator(
  onRefresh: refresh,
  child: ListView.separated(
      separatorBuilder: (context, index) => Divider(),
      controller: controller,
      padding: const EdgeInsets.all(8),
      // 列表数量+2(原列表项+搜索框+底部加载提示)
      itemCount: evsePanels.length + 2,
      itemBuilder: (context, index) {
        // 第一个item显示搜索框
        if (index == 0) {
          return Container(
            height: widget.appController.queryData.size.height/12,
            width: widget.appController.queryData.size.width * (9/10),
            margin: EdgeInsets.all(5.0),
            decoration: BoxDecoration(
                color: widget.appController.themeController.appWhiteLightColor,
                boxShadow: [
                  BoxShadow(
                    color: widget.appController.themeController.appGreyLightColor.withOpacity(0.6),
                    spreadRadius: 1,
                    blurRadius: 1,
                    offset: Offset(0, 2), // changes position of shadow
                  ),
                ],
                shape: BoxShape.rectangle,
                border: Border.all(
                  color: Colors.transparent,
                ),
                borderRadius: BorderRadius.all(Radius.circular(10))
            ),
            child:Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children:[
                  Container(
                    width: widget.appController.queryData.size.width * (7/10),
                    child: searchTextField,
                  ),
                  Container(
                    child: IconButton(
                      color: widget.appController.themeController.appBlackDeepColor,
                      tooltip: 'Search',
                      icon: const Icon(Icons.search),
                      iconSize: 32 * this.unitHeightValue,
                      onPressed: () {
                        this.evseSearchField = myController.text;
                        showEvsePanels();
                      },
                    ),
                  ),
                ]
            ),
          );
        }
        // 原列表项索引需减1
        if (index - 1 < evsePanels.length) {
          return evsePanels[index - 1];
        } else {
          return  Padding(
            padding: const EdgeInsets.symmetric(vertical: 32),
            child: Center(
              child: hasMore
                  ? const CircularProgressIndicator()
                  : const Text('No more data to load'),
            ),
          );
        }
      }
  ),
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:27:39