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

ListView滚动时内容被顶部组件遮挡的问题求助

ListView滚动时内容被顶部组件遮挡的问题求助

最近我在App里的几个ListView组件遇到了个奇怪的问题:当把ListView放在Column里,并且上面有个Container/SizedBox这类组件时,滚动ListView的时候,内容会跑到顶部组件的下面去。这个问题不管有没有用我自己写的ErrorAndDataHandlerScreen自定义组件都会出现,想问问这是我代码写的问题还是Flutter本身的bug?

先给大家看一下我的代码结构:

HomeScreen 核心代码

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key, required this.themeProvider});
  final ThemeProvider themeProvider;

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final DataState _dataState = DataState()..fetchData();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Data"),
        actions: [
          IconButton(
              onPressed: () {
                widget.themeProvider.toggleTheme();
              },
              icon: widget.themeProvider.isDarkTheme
                  ? Icon(Icons.light_mode_rounded)
                  : Icon(Icons.dark_mode_rounded)),
          IconButton(
              onPressed: () {},
              icon: Icon(Icons.add_circle_outline_rounded))
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListenableBuilder(
          listenable: _dataState,
          builder: (context, _) {
            return ErrorAndDataHandlerScreen(
              response: _dataState.response,
              isLoading: _dataState.isLoading,
              loading: Skeletonizer(
                child: Column(
                  children: List.generate(
                    8,
                    (_) => Padding(
                      padding: const EdgeInsets.only(bottom: 8.0),
                      child: SampleDataTile(),
                    ),
                  ),
                ),
              ),
              errorWidget: (value) {
                return Center(
                  child: Text(value.first.message),
                );
              },
              widgetBuilder: (value) {
                return Column(
                  children: [
                    // 这个就是会遮挡ListView的顶部容器
                    Container(
                      height: 80,
                      color: Theme.of(context).scaffoldBackgroundColor,
                      width: double.infinity,
                      child: Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 24),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          spacing: 8,
                          children: [
                            Container(
                              height: 50,
                              width: 250,
                              decoration: BoxDecoration(
                                color: Theme.of(context)
                                    .colorScheme
                                    .surfaceContainer,
                                borderRadius: BorderRadius.circular(10),
                                border: Border.all(
                                  color: Theme.of(context).brightness == Brightness.dark
                                      ? Colors.white
                                      : Colors.black,
                                )),
                            ),
                            IconButton(
                                onPressed: () {
                                  showModalBottomSheet(
                                    context: context,
                                    isScrollControlled: true,
                                    builder: (context) {
                                      return BottomModal(
                                        dataState: _dataState,
                                      );
                                    },
                                  );
                                },
                                icon: Icon(Icons.filter_list_rounded))
                          ],
                        ),
                      ),
                    ),
                    Expanded(
                      child: ListView.separated(
                        itemBuilder: (context, index) {
                          final currentData = _dataState.data[index];
                          return DataTile(
                            onTap: () => context
                                .push(DetailsScreen(data: currentData)),
                            data: currentData,
                          );
                        },
                        separatorBuilder: (context, index) => SizedBox(
                          height: 8,
                        ),
                        itemCount: _dataState.data.length,
                      ),
                    ),
                  ],
                );
              },
            );
          },
        ),
      ),
    );
  }
}

自定义状态处理组件 ErrorAndDataHandlerScreen

class ErrorAndDataHandlerScreen extends StatelessWidget {
  const ErrorAndDataHandlerScreen({
    super.key,
    required this.response,
    this.showWidget,
    this.errorWidget,
    this.loading,
    this.isLoading = false,
    required this.widgetBuilder,
  });

  final Widget? showWidget;
  /// 标记加载状态
  final bool isLoading;
  /// 错误状态时显示的组件
  final Widget Function(List<ErrorsResponse> value)? errorWidget;
  /// 加载中显示的组件
  final Widget? loading;
  final Widget Function(SuccessDataResponse? value) widgetBuilder;
  final StatusResponse? response;

  @override
  Widget build(BuildContext context) {
    return switch (isLoading) {
      false => switch (response?.errors) {
          null => widgetBuilder(response?.data as SuccessDataResponse?),
          _ => errorWidget?.call((response?.errors?..shuffle()) ?? []) ?? SizedBox(),
        },
      true => loading ?? Container(),
    };
  }
}

问题具象描述

当我滚动下方的ListView.separated时,列表项会向上滚动并被顶部那个高度80的Container完全遮挡住。我一开始怀疑是自定义状态组件的问题,但直接用Column嵌套Container+Expanded包裹ListView的最简结构测试,还是会出现同样的遮挡情况。

有没有大佬能帮我定位下问题根源?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:04:30