evergreen
evergreen

Reputation: 763

Refresh widget or page in Flutter without ListView et al

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

Answers (4)

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

TSR
TSR

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

Lakhwinder Singh
Lakhwinder Singh

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

creativecreatorormaybenot
creativecreatorormaybenot

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

Related Questions