Loading

【Flutter】可滚动组件之CustomScrollView

前言

CustomScrollView是可以使用Sliver来自定义滚动模型(效果)的组件。它可以包含多种滚动模型,举个例子,假设有一个页面,顶部需要一个GridView,底部需要一个ListView,而要求整个页面的滑动效果是统一的,即它们看起来是一个整体。如果使用GridView+ListView来实现的话,就不能保证一致的滑动效果,因为它们的滚动效果是分离的,所以这时就需要一个"胶水",把这些彼此独立的可滚动组件"粘"起来,而CustomScrollView的功能就相当于“胶水”。

接口描述

const CustomScrollView({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    Key center,
    double anchor = 0.0,
    double cacheExtent,
    this.slivers = const <Widget>[],
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  })

const SliverAppBar({
    Key key,
    this.leading,
    this.automaticallyImplyLeading = true,
    this.title,
    this.actions,
    this.flexibleSpace,
    this.bottom,
    this.elevation,
    this.forceElevated = false,
    this.backgroundColor,
    this.brightness,
    this.iconTheme,
    this.actionsIconTheme,
    this.textTheme,
    this.primary = true,
    this.centerTitle,
    this.titleSpacing = NavigationToolbar.kMiddleSpacing,
    this.expandedHeight,
    this.floating = false,
    this.pinned = false,
    this.snap = false,
    this.shape,
  })

代码示例

// CustomScrollView


import 'package:flutter/material.dart';

class CustomScrollViewTest extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    // 因为本路由没有使用Scaffold,为了让子级Widget(如Text)使用
    // Material Design 默认的样式风格,我们使用Material作为本路由的根。
    return Material(
      child: CustomScrollView(
        slivers: <Widget>[
          // 类似AppBar,包括一个导航栏,两者不同之处在于SliverAppBar可以集成到CustomScrollView。
          // SliverAppBar可以结合FlexibleSpaceBar实现Material Design中头部伸缩的模型。
          SliverAppBar(
            pinned: true,
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: const Text('Demo'),
              background: Image.asset('assets/images/avatar.png', fit: BoxFit.cover,),
            ),
          ),

          // 用SliverPadding包裹以给SliverGrid添加补白。SliverGrid是一个两列,宽高比为4的网格,它有20个子组件。
          SliverPadding(
            padding: const EdgeInsets.all(8.0),
            sliver: SliverGrid(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                // Grid按两列显示
                crossAxisCount: 2,
                mainAxisSpacing: 10.0,
                crossAxisSpacing: 10.0,
                childAspectRatio: 4.0,
              ),
              delegate: SliverChildBuilderDelegate((BuildContext context, int index){
                // 创建子widget
                return Container(
                  alignment: Alignment.center,
                  color: Colors.cyan[100*(index%9)],
                  child: Text('grid item $index'),
                );
              },
                childCount: 20,
              ),
            ),
          ),

          // 是一个所有子元素高度都为50像素的列表
          SliverFixedExtentList(
            itemExtent: 50.0,
            delegate: SliverChildBuilderDelegate((BuildContext context, int index){
              // 创建列表项
              return Container(
                alignment: Alignment.center,
                color: Colors.lightBlue[100*(index%9)],
                child: Text('list item $index'),
              );
            },
              // 50个列表项
              childCount: 50,
            ),
          )
        ],
      ),
    );
  }
}

总结

  • 头部SliverAppBar:SliverAppBar对应AppBar,两者不同之处在于SliverAppBar可以集成到CustomScrollView。SliverAppBar可以结合FlexibleSpaceBar实现Material Design中头部伸缩的模型,具体效果。
  • 中间的SliverGrid:它用SliverPadding包裹以给SliverGrid添加补白。SliverGrid是一个两列,宽高比为4的网格,它有20个子组件。
  • 底部SliverFixedExtentList:它是一个所有子元素高度都为50像素的列表。
posted @ 2020-01-15 10:38  Parzulpan  阅读(4364)  评论(0编辑  收藏  举报