Reputation: 763
I want refresh my page without having a scrollable content, i.e. without having a ListView
et al.
When I want use RefreshIndicator
, the documentation says it needs a scrollable
widget like ListView
.
But if I want to refresh and want to use the refresh animation of RefreshIndicator
without using a ListView
, GridView
or any other scorllable widget, how can i do that?
Upvotes: 14
Views: 7406
Reputation: 1
you can use CustomScrollView with SliverFillRemaining
RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: getData,
child: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Container(child: /**/))
],
),
)
this method is suitable for displaying the content of the Container on the entire available area of the screen
Upvotes: 0
Reputation: 20406
SingleChildScrollView
is not working for because it forces you to use a scrollable content, I cannot center a widget for example.
Here is the solution without any scrollable widget.
import 'package:flutter/material.dart';
void main() {
runApp(DemoApp());
}
class DemoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: RefreshIndicator(
onRefresh: () async {
await Future.delayed(const Duration(seconds: 1));
},
child: CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: Container(
color: Colors.blue,
child: Center(
child: Text("No results found."),
),
),
),
],
),
),
),
);
}
}
Credit: rohan20
Upvotes: 4
Reputation: 7209
You can just use GestureDetector
, I have created a sample for you, but it's not perfect, you can customize it to your own needs, it just detects when you swipe from the top.
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
var refresh=false;
void refreshData(){
if(!refresh){
refresh=true;
print("Refreshing");
Future.delayed(Duration(seconds: 4),(){
refresh =false;
print("Refreshed");
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Test"),
centerTitle: true,
),
body: GestureDetector(
child: Container(
color: Colors.yellow,
height: double.infinity,
width: double.infinity,
child: Center(child: Text('TURN LIGHTS ON')),
),
onVerticalDragUpdate: (DragUpdateDetails details){
print("direction ${details.globalPosition.direction}");
print("distance ${details.globalPosition.distance}");
print("dy ${details.globalPosition.dy}");
if(details.globalPosition.direction < 1 && (details.globalPosition.dy >200 && details.globalPosition.dy < 250)){
refreshData();
}
},
));
}
}
Upvotes: 2
Reputation: 126634
You can simply wrap your content in a SingleChildScrollView
, which will allow you to use a RefreshIndicator
. In order to make the pull down to refresh interaction work, you will have to use AlwaysScrollableScrollPhysics
as your content will most likely not cover more space than available without a scroll view:
RefreshIndicator(
onRefresh: () async {
// Handle refresh.
},
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: /* your content */,
),
);
Upvotes: 13