使 RefreshIndicator 在整个屏幕上工作(ListView)

问题描述 投票:0回答:3

在寻找解决方案时,我发现了一些相关讨论,但没有一个解决方案适用于我的案例。

我在我的应用程序中制作了一个“RefreshableScrollFrame”小部件,它为应该显示 StatusBar(加载指示器等)的页面提供了一个通用框架,并且应该提供一个下拉刷新。

可刷新滚动框架

return Center(
      child: Column(
        children: [
          SizedBox(
            height: 4,
            child: const MyStatusbarWidget(),
          ),
          RefreshIndicator(
            onRefresh: onRefresh,
            child: SingleChildScrollView(
              physics: const AlwaysScrollableScrollPhysics(),
              child: child,
            ),
          )
        ],
      ),
    );

子选项 - 列表视图:

ListView.builder(
            itemCount: items.length,
            physics: const NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            itemBuilder: (context, i) => Card(
              child: ListTile(
                 title: Text(items[i].name),
              ),
            ),
          );

子选项 - 包含

ListView
和静态项目的列:

Column(
          children: [
            ListView.builder(
                itemCount: items.length,
                physics: const NeverScrollableScrollPhysics(),
                shrinkWrap: true,
                itemBuilder: (context, i) => Card(
                  child: ListTile(
                    title: Text(items[i].name),
                  ),
                ),
              ),
            ...someStaticWidgets,
          ],
        );

到目前为止,一切都很好,除了一个重要的细节。 RefreshIndicator 仅在子窗口小部件覆盖的区域中触发。如果内容很小并且仅覆盖页面顶部,则仅在该区域检测到手势。 如果内容只是一个空的 ListView,我什至无法触发刷新。

我尝试了几种建议的解决方案,以便将子项“扩展”到整个屏幕,但在尝试摆脱shrinkWrap、添加Expanded()等时,我总是遇到异常。

任何提示,我们将不胜感激。

flutter flutter-layout
3个回答
7
投票

我找到了一个似乎对我有用的解决方案,使用 LayoutBuilder + ConstrainedBox 来包装 SingleChildScrollView 的内容。 这样,SingleChildScrollView 将始终跨越整个剩余空间。

return Column(
  children: [
    const SizedBox(
      height: 4,
      child: MyStatusbarWidget(),
    ),
    Expanded(
      child: LayoutBuilder(builder: (context, constraints) {
        return RefreshIndicator(
          onRefresh: onRefresh,
          child: SingleChildScrollView(
            physics: const AlwaysScrollableScrollPhysics(),
            child: ConstrainedBox(
                constraints: BoxConstraints(minHeight: constraints.maxHeight),
                child: child,
              ),
            ),
          ),
        );
      }),
    ),
  ],
);

1
投票

你必须用刷新指示器包裹脚手架的整个主体,而不是其中的一部分。


0
投票

我创建了一个多功能的 SmartRefreshIndicator 小部件,可以与

一起使用

可滚动和不可滚动的子部件。

它非常适合在各种 UI 元素中集成下拉刷新功能,例如 ListViewColumn 或任何需要刷新功能的小部件。

class SmartRefreshIndicator extends StatelessWidget {
  final Future<void> Function() onRefresh;
  final Widget child;

  const SmartRefreshIndicator({
    super.key,
    required this.onRefresh,
    required this.child,
  });

  @override
  Widget build(context) {
    return LayoutBuilder(
      builder: (context, constraints) => RefreshIndicator(
        onRefresh: onRefresh,
        child: SingleChildScrollView(
          physics: const AlwaysScrollableScrollPhysics(),
          child: ConstrainedBox(
            constraints: BoxConstraints(minHeight: constraints.maxHeight),
            child: child,
          ),
        ),
      ),
    );
  }
}

您可以随意扩展和自定义它以满足您的特定需求!

© www.soinside.com 2019 - 2024. All rights reserved.