Refresh indicator without scrollview

后端 未结 8 1032
失恋的感觉
失恋的感觉 2020-12-14 15:52

I know with a ListView or SingleChildScrollView RefreshIndicator just works natively but I want to use a RefreshIndicator

相关标签:
8条回答
  • 2020-12-14 16:22

    You must do the following:

    • Use a SingleChildScrollView with the property physics set to AlwaysScrollableScrollPhysics().
    • Make sure it's child has a height of the size of the screen, which you can get with MediaQuery.of(context).size.height.

    The complete example:

    classs MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return RefreshIndicator(
          onRefresh: () {},
          child: SingleChildScrollView(
            physics: AlwaysScrollableScrollPhysics(),
            child: Container(
              child: Center(
                child: Text('Hello World'),
              ),
              height: MediaQuery.of(context).size.height,
            ),
          ),
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-14 16:26

    Most of the other answers will work but they all have some downsides. Using a SingleChildScrollView without adjusting the height will cause the "scrolling glowing effect" to be not at the bottom of the page. Setting the height to the maximum height of the current view (by using MediaQuery or a LayoutBuilder) will solve this problem, but there will be a render overflow when your content's height is bigger than the height of the available space.

    At the end, the following solution worked perfectly for me without any problems:

    LayoutBuilder(
      builder: (context, constraints) => RefreshIndicator(
        onRefresh: _refresh,
        child: SingleChildScrollView(
          physics: AlwaysScrollableScrollPhysics(),
          child: ConstrainedBox(
            constraints: BoxConstraints(
              minHeight: constraints.maxHeight
            ),
            child: Text("Your Widget")
          )
        )
      ),
    )
    
    0 讨论(0)
  • 2020-12-14 16:26

    Complementing Gustavo answer you can use constraints to define the minimum size of SingleChildScrollView in this way

    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return RefreshIndicator(
          onRefresh: () {},
          child: ConstrainedBox(
            constraints: BoxConstraints(
              minHeight: MediaQuery.of(context).size.height,
            ),
            child: SingleChildScrollView(
              physics: AlwaysScrollableScrollPhysics(),
              child: Center(
                child: Text('Hello World'),
              ),
            ),
          ),
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-14 16:27

    So in my case I wanted to display a placeholder in an empty list:

              RefreshIndicator(
                child: Stack(
                  children: <Widget>[
                    Center(
                      child: Text("The list is empty"),
                    ),
                    ListView()
                  ],
                ),
                onRefresh: () {},
              )
    
    0 讨论(0)
  • 2020-12-14 16:31

    More flexible solution is put your scrollable empty/error state widget into LayoutBuilder

    LayoutBuilder(
      builder: (context, constraints) => SingleChildScrollView(
        physics: AlwaysScrollableScrollPhysics(),
        child: SizedBox(
          height: constraints.maxHeight,
          child: ErrorState(
              subtitle: (snapshot.data as ErrorStateful).errorMessage),
        ),
      ),
    );
    
    0 讨论(0)
  • 2020-12-14 16:32

    Is it possible without page that doesn't scroll?

    -No.


    Please read the documentation of the parameter child in RefreshIndicator:

    The widget below this widget in the tree.

    The refresh indicator will be stacked on top of this child. The indicator will appear when child's Scrollable descendant is over-scrolled.

    Typically a [ListView] or [CustomScrollView].


    Is there a work-around?

    -Yes

    You can put only one widget in the Listview's children list:

    new RefreshIndicator(
      child: new ListView(
        children: <Widget>[
          new Text('This is child with refresh indicator'),
        ],
      ),
      onRefresh: () {},
    )
    
    0 讨论(0)
提交回复
热议问题