While looking for solutions, I found some related discussions, but none of the solutions worked in my case.
I made a "RefreshableScrollFrame" widget in my app, which offers a generic frame for pages that should show a StatusBar (loading indicator, etc.) and which should provide a pull-down to refresh.
RefreshableScrollFrame
return Center(
child: Column(
children: [
SizedBox(
height: 4,
child: const MyStatusbarWidget(),
),
RefreshIndicator(
onRefresh: onRefresh,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: child,
),
)
],
),
);
Child Option - ListView:
ListView.builder(
itemCount: items.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, i) => Card(
child: ListTile(
title: Text(items[i].name),
),
),
);
Child Option - Column with the ListView and static items:
Column(
children: [
ListView.builder(
itemCount: items.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, i) => Card(
child: ListTile(
title: Text(items[i].name),
),
),
),
...someStaticWidgets,
],
);
So far so good, everything works fine, except for one important detail. The RefreshIndicator is only triggered in areas, which are covered by the child widget. If the content is small and covers just the top of the page, the gesture is detected only in that area. If the content is just an empty ListView, I won't even be able to trigger a refresh.
I tried several suggested solutions in order to "expand" the child to the whole screen, but I always ran into exceptions, when trying to get rid of shrinkWrap, when adding Expanded(), and so on.
Any hints would be appreciated.
I found a solution that seems to work for me, using a LayoutBuilder + ConstrainedBox to wrap the contents of the SingleChildScrollView. This way, the SingleChildScrollView will always span the whole remaining space.
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,
),
),
),
);
}),
),
],
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With