在寻找解决方案时,我发现了一些相关讨论,但没有一个解决方案适用于我的案例。
我在我的应用程序中制作了一个“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()等时,我总是遇到异常。
任何提示,我们将不胜感激。
我找到了一个似乎对我有用的解决方案,使用 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,
),
),
),
);
}),
),
],
);
你必须用刷新指示器包裹脚手架的整个主体,而不是其中的一部分。
我创建了一个多功能的 SmartRefreshIndicator 小部件,可以与
一起使用可滚动和不可滚动的子部件。
它非常适合在各种 UI 元素中集成下拉刷新功能,例如 ListView、Column 或任何需要刷新功能的小部件。
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,
),
),
),
);
}
}
您可以随意扩展和自定义它以满足您的特定需求!