刷新指示器没有滚动视图

时间:2018-05-06 00:38:27

标签: flutter

我知道(function(){ 'use strict'; angular.module('moiveapp', ['ngRoute'],['firebase']) .factory("Movie", ["$firebaseObject", function($firebaseObject) { return function(ID) { // create a reference to the database node where we will store our data var ref = firebase.database().ref("allmovies").push(); var movieRef = ref.child(ID); // return it as a synchronized object return $firebaseObject(movieRef); } } ]) .controller("MovieCtrl", ['$scope','Movie', function($scope,Movie) { $scope.test = Movie("001"); }]); })(); ListView SingleChildScrollView本身就可以使用,但我想在不滚动的页面上使用RefreshIndicator。这是否可能,如果是这样,怎么样?

9 个答案:

答案 0 :(得分:18)

您必须执行以下操作:

  • 使用SingleChildScrollView,将physics设置为AlwaysScrollableScrollPhysics()
  • 确保其中的孩子的身高与屏幕相同,MediaQuery.of(context).size.height可以获得。

完整的例子:

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,
        ),
      ),
    );
  }
}

答案 1 :(得分:3)

大多数其他答案都可以,但是它们都有一些缺点。使用SingleChildScrollView而不调节高度会导致“滚动发光效果”不在页面底部。将高度设置为当前视图的最大高度(通过使用MediaQueryLayoutBuilder)可以解决此问题,但是当您的内容的高度大于屏幕视图的高度时,将出现渲染溢出。可用空间。

最后,以下解决方案对我来说是完美的,没有任何问题:

LayoutBuilder(
  builder: (context, constraints) => RefreshIndicator(
    onRefresh: _refresh,
    child: SingleChildScrollView(
      physics: AlwaysScrollableScrollPhysics(),
      child: ConstrainedBox(
        constraints: BoxConstraints(
          minHeight: constraints.maxHeight
        ),
        child: Text("Your Widget")
      )
    )
  ),
)

答案 2 :(得分:1)

没有不滚动的页面是否可以?

-No。

请阅读RefreshIndicator中参数child的文档:

  

树中此小部件下方的小部件。

     

刷新指示符将堆叠在此子项的顶部。当孩子的Scrollable后代过度滚动时,指示符将出现。

     

通常是[ListView]或[CustomScrollView]。

有解决办法吗?

是的

您只能在Listview的子列表中放置一个小部件:

new RefreshIndicator(
  child: new ListView(
    children: <Widget>[
      new Text('This is child with refresh indicator'),
    ],
  ),
  onRefresh: () {},
)

答案 3 :(得分:1)

因此,在我的情况下,我想在一个空列表中显示一个占位符:

          RefreshIndicator(
            child: Stack(
              children: <Widget>[
                Center(
                  child: Text("The list is empty"),
                ),
                ListView()
              ],
            ),
            onRefresh: () {},
          )

答案 4 :(得分:1)

这是您需要的完整代码(包括解决使用appBar时的高度问题):

import 'package:flutter/material.dart';

class RefreshFullScreen extends StatefulWidget {
  const RefreshFullScreen({Key? key}) : super(key: key);

  @override
  _RefreshFullScreenState createState() => _RefreshFullScreenState();
}

class _RefreshFullScreenState extends State<RefreshFullScreen> {
  @override
  Widget build(BuildContext context) {

    double height = MediaQuery.of(context).size.height; // Full screen width and height
    EdgeInsets padding = MediaQuery.of(context).padding; // Height (without SafeArea)
    double netHeight = height - padding.top - kToolbarHeight; // Height (without status and toolbar)

    return Scaffold(
      appBar: AppBar(),
      body: RefreshIndicator(
        onRefresh: () {
          return Future.delayed(
            Duration(seconds: 1),
                () {
            },
          );
        }, child: SingleChildScrollView(
            physics: AlwaysScrollableScrollPhysics(),
            child: Container(
              color: Colors.red,
              height: netHeight,
            )
      ),
      ),
    );
  }
}

这是结果:

enter image description here

答案 5 :(得分:0)

ListView.builder 中使用 physics:AlwaysScrollableScrollPhysics()

示例:

RefreshIndicator(
   onRefresh: () => _onRefresh(),
   child: Center(
            child: ListView.builder(
                     physics: AlwaysScrollableScrollPhysics(),
                      controller: _scrollController,
                      itemCount: 4,
                      addAutomaticKeepAlives: true,
                      itemBuilder: (BuildContext context, int position) {
                            return Text("Hello $position");
                          }
              ),
      ),
)

答案 6 :(得分:0)

补充古斯塔沃答案,您可以使用约束以这种方式定义SingleChildScrollView的最小大小

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'),
          ),
        ),
      ),
    );
  }
}

答案 7 :(得分:0)

您可以使用只有一个孩子 CustomScrollViewSliverFillRemaining 作为不显示数据小部件的案例:

CustomScrollView(
    slivers: [
    SliverFillRemaining(
        child: Center(
        child: Text(
            AppLocalizations.of(context).noData,
        ),
        ),
    )
    ],
)

答案 8 :(得分:-1)

建议将AlwaysScrollableScrollPhysics()RefreshIndicator一起使用,因为如果Scrollable的内容可能不足以进行过度滚动,请考虑将其physics属性设置为AlwaysScrollableScrollPhysics

parent可以用来组合不同类型的ScrollPhysics对象,而不是创建自己的子类,以获得所需的滚动物理特性。例如:

ListView(
  physics: const AlwaysScrollableScrollPhysics(),
  children: ...
)

enter image description here

注意RefreshIndicator仅可用于垂直滚动视图。