精华内容
下载资源
问答
  • City_Slivers RMarkdown网站为内华达城市的Slivers计划生成。 该项目于2021年3月31日由尼克(TSF)和玛丽安(CSU Chico)启动
  •   今天呢,我小拉面主要想给大家讲一讲Flutter中的Slivers大家族的使用场景和方法。开发过列表布局的同学们应该对Slivers系列的控件不陌生,或多或少都用过这个库中的控件,来解决复杂的滑动嵌套布局。   比如...

    文中所有示例代码请点击:https://gitee.com/yumi0629/FlutterUI/tree/master/lib/sliver

      今天呢,我小拉面主要想给大家讲一讲Flutter中的Slivers大家族的使用场景和方法。开发过列表布局的同学们应该对Slivers系列的控件不陌生,或多或少都用过这个库中的控件,来解决复杂的滑动嵌套布局。
      比如之前讲Hero的时候提到的下面这个界面,使用普通的GridView的话是没法实现的,我们选择使用CustomScrollView,然后在slivers属性中添加子控件,在这个例子里,我们可以用SliverToBoxAdapter来做HeaderView,GridView来做主体布局,整体为一个CustomScrollView,完全不会出现任何滑动冲突的问题。


      Flutter中的Slivers大家族基本都是配合CustomScrollView来实现的,除了上面提到的滑动布局嵌套,你还可以使用Slivers来实现页面头部展开/收起、
    AppBar随手势变换等等功能。官方的Sliver库里面的控件很多,可以去Flutter API网站搜一下,这篇文章我只讲一些常用的控件。
      OK, Let's start !!

     

    SliverAppBar

      如果你是一名Android开发者,一定使用过CollapsingToolbarLayout这个布局来实现AppBar展开/收起的功能,在Flutter里面则对应SliverAppBar控件。给SliverAppBar设置flexibleSpaceexpandedHeight属性,就可以轻松完成AppBar展开/收起的功能:

    CustomScrollView(
            slivers: <Widget>[
              SliverAppBar(
                actions: <Widget>[
                  _buildAction(),
                ],
                title: Text('SliverAppBar'),
                backgroundColor: Theme.of(context).accentColor,
                expandedHeight: 200.0,
                flexibleSpace: FlexibleSpaceBar(
                  background: Image.asset('images/food01.jpeg', fit: BoxFit.cover),
                ),
                // floating: floating,
                // snap: snap,
                // pinned: pinned,
              ),
              SliverFixedExtentList(
                itemExtent: 120.0,
                delegate: SliverChildListDelegate(
                  products.map((product) {
                    return _buildItem(product);
                  }).toList(),
                ),
              ),
            ],
          );
    

     

    sliver_app_bar_01.gif


      如果设置floating属性为true,那么AppBar会在你做出下拉手势时就立即展开(即使ListView并没有到达顶部),该展开状态不显示flexibleSpace:

    sliver_app_bar_02.gif


      如果同时设置floatingsnap属性为true,那么AppBar会在你做出下拉手势时就立即全部展开(即使ListView并没有到达顶部),该展开状态显示flexibleSpace:

    sliver_app_bar_03.gif

     

      如果不想AppBar消失,则设置pinned属性为true即可:

    sliver_app_bar_04.gif

     

    SliverList

      SliverList的使用非常简单,只需设置delegate属性即可,我们一般使用SliverChildBuilderDelegate,注意记得设置childCount,否则Flutter没法知道怎么绘制:

    CustomScrollView(
            slivers: <Widget>[
              SliverList(
                delegate: SliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                    return _buildItem(context, products[index]);
                  },
                  childCount: 3,
                ),
              )
            ],
          );
    

    sliver_list.png

      你也可以通过下面的方式来设置childCount,如果不设置childCount,Flutter一旦发现delegate的某个index返回了null,就会认为childCount就是这个index。

    delegate: SliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                        if(index>products.length){
                          return null;
                        }
                    return _buildItem(context, products[index]);
                  },
    

      你也可以使用SliverChildListDelegate来构建delegate:

    delegate: SliverChildListDelegate([
                  _buildItem(),
                  _buildItem(),
                  _buildItem(),
                ]),
    

    SliverChildListDelegateSliverChildBuilderDelegate的区别:

    • SliverChildListDelegate一般用来构item建数量明确的列表,会提前build好所有的子item,所以在效率上会有问题,适合item数量不多的情况(不超过一屏)。
    • SliverChildBuilderDelegate构建的列表理论上是可以无限长的,因为使用来lazily construct优化。
      (两者的区别有些类似于ListView和ListView.builder()的区别。)

    SliverGrid

      SliverGrid有三个构造函数:SliverGrid.count()SliverGrid.extentSliverGrid()

    • SliverGrid.count()指定了一行展示多少个item,下面的例子表示一行展示4个:
    SliverGrid.count(children: scrollItems, crossAxisCount: 4)
    
    • SliverGrid.extent可以指定item的最大宽度,然后让Flutter自己决定一行展示多少个item:
    SliverGrid.extent(children: scrollItems, maxCrossAxisExtent: 90.0)
    
    • SliverGrid()则是需要指定一个gridDelegate,它提供给了程序员一个自定义Delegate的入口,你可以自己决定每一个item怎么排列:
    SliverGrid(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: products.length,
      ),
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return _buildItem(products[index]);;
        }
    );
    

    sliver_grid.png

    SliverPersistentHeader

      SliverPersistentHeader顾名思义,就是给一个可滑动的视图添加一个头(实际上,在CustomScrollView的slivers列表中,header可以出现在视图的任意位置,不一定要是在顶部)。这个Header会随着滑动而展开/收起,使用pinnedfloating属性来控制收起时Header是否展示(pinnedfloating属性不可以同时为true),pinnedfloating属性的具体意义和SliverAppBar中相同,这里就不再次解释了。

    sliver_persistent_header.gif

     

    SliverPersistentHeader(
          pinned: pinned,
          floating: floating,
          delegate: _SliverAppBarDelegate(
            minHeight: 60.0,
            maxHeight: 180.0,
            child: Container(),
          ),
        );
    

      构建一个SliverPersistentHeader需要传入一个delegate,这个delegate是SliverPersistentHeaderDelegate类型的,而SliverPersistentHeaderDelegate是一个abstract类,我们不能直接new一个SliverPersistentHeaderDelegate出来,因此,我们需要自定义一个delegate来实现SliverPersistentHeaderDelegate类:

    class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
      _SliverAppBarDelegate({
        @required this.minHeight,
        @required this.maxHeight,
        @required this.child,
      });
    
      final double minHeight;
      final double maxHeight;
      final Widget child;
    
      @override
      double get minExtent => minHeight;
    
      @override
      double get maxExtent => math.max(maxHeight, minHeight);
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return new SizedBox.expand(child: child);
      }
    
      @override
      bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
        return maxHeight != oldDelegate.maxHeight ||
            minHeight != oldDelegate.minHeight ||
            child != oldDelegate.child;
      }
    }
    

      写一个自定义SliverPersistentHeaderDelegate很简单,只需重写build()get maxExtentget minExtentshouldRebuild()这四个方法,上面就是一个最简单的SliverPersistentHeaderDelegate的实现。其中,maxExtent表示header完全展开时的高度,minExtent表示header在收起时的最小高度。因此,对于我们上面的那个自定义Delegate,如果将minHeightmaxHeight的值设置为相同时,header就不会收缩了,这样的Header跟我们平常理解的Header更像。
      之前也提到了,实际使用时,header不一定要放在slivers列表的最前面,可以随意混搭,当然,一般来说不会有这种视觉需求的:

    CustomScrollView(
            slivers: <Widget>[
              _buildHeader(0),
              SliverGrid.count(
                crossAxisCount: 3,
                children: _products.map((product) {
                  return _buildItemGrid(product);
                }).toList(),
              ),
              _buildHeader(1),
              SliverFixedExtentList(
                itemExtent: 100.0,
                delegate: SliverChildListDelegate(
                  products.map((product) {
                    return _buildItemList(product);
                  }).toList(),
                ),
              ),
              _buildHeader(2),
              SliverGrid(
                gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 200.0,
                  mainAxisSpacing: 10.0,
                  crossAxisSpacing: 10.0,
                  childAspectRatio: 3.0,
                ),
                delegate: new SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return _buildItemGrid2(_products2[index]);
                  },
                  childCount: _products2.length,
                ),
              ),
            ],
          );
    

    SliverToBoxAdapter

      SliverPersistentHeader一般来说都是会展开/收起的(除非minExtent和maxExtent值相同),那么如果想要在滚动视图中添加一个普通的控件,那么就可以使用SliverToBoxAdapter来将各种视图组合在一起,放在CustomListView中。

    sliver_adapter.png


      上图中框起来的部分全部都是SliverToBoxAdapter,结合SliverToBoxAdapter,滚动视图可以任意组合:

     

    CustomScrollView(
            physics: ScrollPhysics(),
            slivers: <Widget>[
              SliverToBoxAdapter(
                child: _buildHeader(),
              ),
              SliverGrid.count(
                crossAxisCount: 3,
                children: products.map((product) {
                  return _buildItemGrid(product);
                }).toList(),
              ),
              SliverToBoxAdapter(
                child: _buildSearch(),
              ),
              SliverFixedExtentList(
                itemExtent: 100.0,
                delegate: SliverChildListDelegate(
                  products.map((product) {
                    return _buildItemList(product);
                  }).toList(),
                ),
              ),
              SliverToBoxAdapter(
                child: _buildFooter(),
              ),
            ],
          );
    

     

    展开全文
  • SliverList SliverFixedExtentList SliverPrototypeExtentList SliverGrid

    SliverList
    SliverFixedExtentList
    SliverPrototypeExtentList
    SliverGrid

    展开全文
  • 欢迎来到GitHub Pages 该网站由塞拉利昂基金会(Sierra Fund)创建,旨在通过其“城市银计划”为内华达市提供便利。 该网站由N. Graham和M. Farumi使用RMarkdown创建。 无论是视觉还是数据更新,Webist仍处于设计...
  • 引入最高版本的pull_to_refresh1.6.0...file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:164:13: Error: Method not found: 'describeForError'. yield

    引入最高版本的pull_to_refresh1.6.0无法编译通过,提示jar包的sliver.dart类中缺少各种方法

    报错信息:

    Compiler message:
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:164:13: Error: Method not found: 'describeForError'.
          yield describeForError(
                ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:170:11: Error: Method not found: 'ErrorSummary'.
              ErrorSummary(
              ^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:172:11: Error: Method not found: 'describeForError'.
              describeForError(
              ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:175:11: Error: Method not found: 'ErrorDescription'.
              ErrorDescription(
              ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:169:28: Error: Method not found: 'FlutterError.fromParts'.
            throw FlutterError.fromParts(<DiagnosticsNode>[
                               ^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:164:13: Error: The method 'describeForError' isn't defined for the class 'RenderSliverRefresh'.
     - 'RenderSliverRefresh' is from 'package:pull_to_refresh/src/internals/slivers.dart' ('file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart').
    Try correcting the name to the name of an existing method, or defining a method named 'describeForError'.
          yield describeForError(
                ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:163:62: Error: The argument type 'Iterable<dynamic> Function()' can't be assigned to the parameter type 'void Function(StringBuffer)'.
     - 'Iterable' is from 'dart:core'.
     - 'StringBuffer' is from 'dart:core'.
    Try changing the type of the parameter, or casting the argument to 'void Function(StringBuffer)'.
        assert(geometry.debugAssertIsValid(informationCollector: () sync* {
                                                                 ^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:170:11: Error: The method 'ErrorSummary' isn't defined for the class 'RenderSliverRefresh'.
     - 'RenderSliverRefresh' is from 'package:pull_to_refresh/src/internals/slivers.dart' ('file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart').
    Try correcting the name to the name of an existing method, or defining a method named 'ErrorSummary'.
              ErrorSummary(
              ^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:172:11: Error: The method 'describeForError' isn't defined for the class 'RenderSliverRefresh'.
     - 'RenderSliverRefresh' is from 'package:pull_to_refresh/src/internals/slivers.dart' ('file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart').
    Try correcting the name to the name of an existing method, or defining a method named 'describeForError'.
              describeForError(
              ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:175:11: Error: The method 'ErrorDescription' isn't defined for the class 'RenderSliverRefresh'.
     - 'RenderSliverRefresh' is from 'package:pull_to_refresh/src/internals/slivers.dart' ('file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart').
    Try correcting the name to the name of an existing method, or defining a method named 'ErrorDescription'.
              ErrorDescription(
              ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:430:13: Error: Method not found: 'describeForError'.
          yield describeForError(
                ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:436:11: Error: Method not found: 'ErrorSummary'.
              ErrorSummary(
              ^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:438:11: Error: Method not found: 'describeForError'.
              describeForError(
              ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:441:11: Error: Method not found: 'ErrorDescription'.
              ErrorDescription(
              ^^^^^^^^^^^^^^^^
    file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.6.0/lib/src/internals/slivers.dart:435:28: Error: Method not found: 'FlutterError.fromParts'.
            throw FlutterError.fromParts(<DiagnosticsNode>[
    

    尝试各种方法无法成功引用1.6.0,改引用低版本时出错:Target of URI doesn’t exist ‘package:pull_to_refresh/pull_to_refresh.dart’
    此时,修改项目.packages文件中的pull_to_refresh-1.6.0为低版本

    pull_to_refresh:file:///Users/hyf/.pub-cache/hosted/pub.flutter-io.cn/pull_to_refresh-1.5.7/lib/
    
    展开全文
  • slivers: [ SliverAppBar( pinned: true, expandedHeight: 250.0, flexibleSpace: FlexibleSpaceBar( title: const Text('Demo'), background: Image.network('http://www.ecobentech.com/img/a.jpg',fit: ...
    import 'package:flutter/material.dart';

    void main()=>runApp(MyApp());

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    home: Scaffold(
    body: CustomScrollViewTestRoute(),
    ),
    );
    }
    }

    class CustomScrollViewTestRoute extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return CustomScrollView(
    slivers: <Widget>[
    SliverAppBar(
    pinned: true,
    expandedHeight: 250.0,
    flexibleSpace: FlexibleSpaceBar(
    title: const Text('Demo'),
    background: Image.network('http://www.ecobentech.com/img/a.jpg',fit: BoxFit.cover,),
    ),
    ),

    SliverPadding(
    padding: const EdgeInsets.all(8.0),
    sliver: SliverGrid( //Grid
    gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2, //Grid按两列显示
    mainAxisSpacing: 10.0,
    crossAxisSpacing: 10.0,
    childAspectRatio: 4.0,
    ),
    delegate: new SliverChildBuilderDelegate(
    (BuildContext context, int index) {
    //创建子widget
    return new Container(
    alignment: Alignment.center,
    color: Colors.cyan[100 * (index % 9)],
    child: new Text('grid item $index'),
    );
    },
    childCount: 20,
    ),
    ),
    ),
    //List
    SliverFixedExtentList(
    itemExtent: 50.0,
    delegate: new SliverChildBuilderDelegate(
    (BuildContext context, int index) {
    //创建列表项
    return new Container(
    alignment: Alignment.center,
    color: Colors.lightBlue[100 * (index % 9)],
    child: new Text('list item $index'),
    );
    },
    childCount: 50 //50个列表项
    ),
    ),
    ],
    );
    }
    }

    转载于:https://www.cnblogs.com/braveheart007/p/10733430.html

    展开全文
  • 更新:关于Slivers的具体用法,请看这篇文章:Flutter:Slivers大家族,让滑动视图的组合变得很简单! 本文写的只是SliverAppBar的用法,实际上使用Slivers可以实现多种折叠效果。   Android和iOS中都有类似的...
  • Flutter滚动视觉差

    2019-03-21 17:19:34
    new CustomScrollView( physics: new BouncingScrollPhysics(), // 需要使用 slivers 才可以 slivers: <Widget>[ // 头部内容 new SliverAppBar( // 高度 expandedHei...
  • Flutter之CustomScrollView

    2021-01-08 03:51:32
    class CustomScrollViewWidget extends StatelessWidget { @override Widget build(BuildContext context) { ... slivers: [ SliverAppBar( pinned: true, expandedHeight: 200.0, flexibleSpace: FlexibleSpac
  • flutter实现首页

    千次阅读 2018-12-20 15:19:23
    Flutter中的Slivers大家族基本都是配合CustomScrollView来实现的,除了上面提到的滑动布局嵌套,你还可以使用Slivers来实现页面头部展开/收起、 AppBar随手势变换等等功能。 给SliverAppBar设置flexibleSpace(展开...
  • Flutter | Sliver 系列

    2021-08-13 18:13:18
    CustomScrollView:一个滚动的容器,改组件不接受任何 child,但是你可以直接提供 Slivers 已创建各种滚动效果,例如页面中有多个可滑动的列表,如 Appbar, 列表,网格,等这种就可以直接使用 SliverAppBar,...
  • 一. JSON读取和解析 二. ListView组件 三. GridView组件 四. Slivers 五. 监听滚动事件
  • SliverList , SliverFixedExtentList

    千次阅读 2019-04-05 19:10:00
    SliverList 高度自动, SliverFixedExtentList 高度固定死. CustomScrollView( slivers:[ SliverList( delegate: SliverChildBuilderDeleg...
  • Flutter之CustomView

    2019-10-08 01:59:57
    今天呢,我小拉面主要想给大家讲一讲Flutter中的Slivers大家族的使用场景和方法。开发过列表布局的同学们应该对Slivers系列的控件不陌生,或多或少都用过这个库中的控件,来解决复杂的滑动嵌套布局。 比如之前讲...
  • CustomScrollView

    2019-04-25 10:38:00
    body: CustomScrollView( slivers: [ SliverList( delegate: SliverChildBuilderDelegate( (context, int index) { ...
  • sketches-experiment-源码

    2021-05-09 03:04:31
    # Collect all the slivers IP addresses export SLICE_ID=1514 getips > ips.txt # Deploy the experiment on all the nodes # `run` will run the provided script on the remote nodes, it also accept direct ...
  • 关键代码: Scaffold( appBar: appBar(context), resizeToAvoidBottomInset: false, ... slivers: [ SliverToBoxAdapter( child: Padding( child: Column( mainAxisAlignment: MainAxisAlignment.ce...
  • CustomScrollView( slivers: <Widget>[ SliverPersistentHeader( delegate: SliverHeaderDelegate( minHeight: MediaQuery.of(context).padding.top + 44, maxHeight: 211,
  • slivers下有多种widget 一些常用的有 SliverList SliverFixedExtentList SliverGrid SliverPadding SliverAppBar SliverToBoxAdapter SliverFillRemaining SliverSafeArea 还有一...
  • slivers: <Widget>[ const SliverAppBar( pinned: true, expandedHeight: 250.0, flexibleSpace: FlexibleSpaceBar( title: Text('Demo'), ), ), SliverGrid( gridDelegate: SliverGridDelegat.
  • Flutter之SliverAppBar

    千次阅读 2020-01-18 16:59:51
    SliverAppBar控件可以实现页面头部区域展开、折叠的效果,类似于Android...SliverAppBar控件需要和CustomScrollView搭配使用,SliverAppBar要通常放在slivers的第一位,后面接其他sliver控件。 CustomScrollView( ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 490
精华内容 196
热门标签
关键字:

Slivers