flutter3.0学习笔记

SliverAppBar滚动折叠

Preview

SliverAppBar实现页面头部的展开、合并的效果。SliverAppBar控件需要和CustomScrollView搭配使用,SliverAppBar要通常放在slivers的第一位,后面接其他sliver控件。 构造函数:

const SliverAppBar({
    super.key,
    this.leading,//左侧图标或者文字
    this.automaticallyImplyLeading = true,//没有leading且true,默认返回箭头,反之是返回title
    this.title,//标题
    this.actions,//右侧操作
    this.flexibleSpace,//背景内容区
    this.bottom,//底部区,可以放tabbar
    this.elevation,//阴影
    this.scrolledUnderElevation,
    this.shadowColor,
    this.surfaceTintColor,
    this.forceElevated = false,//是否显示阴影
    this.backgroundColor,//背景颜色
    this.brightness,
    this.iconTheme,//图标主题
    this.actionsIconTheme,//功能菜单icon主题
  
    this.textTheme,//文字主题
    this.primary = true,//是否显示在状态栏的下面,flase会占领状态栏的高度
    this.centerTitle,//标题是否居中
    this.excludeHeaderSemantics = false,
    this.titleSpacing,//标题横向间距
    this.collapsedHeight,
    this.expandedHeight,//合并的高度
    this.floating = false,//滑动时是否悬浮
    this.pinned = false,//标题栏是否固定
    this.snap = false,//配合floating,snap为true,floating也要为true才会有效果。true的时候会监听你的手势结束时的动作时是下滑,那么SliverAppBar展开,上滑则是收缩折叠至上一次折叠的位置处,但是这个效果需要一个基础就是存在上一次折叠的位置,否则不生效
    this.stretch = false,//true:SliverAppBar完全展开后是否可以继续拉伸,注意这个需要外部滑动组件physics的支持(设置BouncingScrollPhysics(),滑动到标界可以继续滑动拥有回弹效果),否则是不会生效的
    this.stretchTriggerOffset = 100.0,//拉伸监听触发的偏移
    this.onStretchTrigger,//拉伸监听
    this.shape,//SliverAppBar形状
    this.toolbarHeight = kToolbarHeight,//SliverAppBar高度 默认56
    this.leadingWidth,//leading宽度
   ...
  }) 
  • FlexibleSpaceBar属性
const FlexibleSpaceBar({
    super.key,
    this.title,//标题
    this.background,//背景颜色
    this.centerTitle,//标题是否居中
    this.titlePadding,//标题内边距
    this.collapseMode = CollapseMode.parallax,//折叠模式
    this.stretchModes = const <StretchMode>[StretchMode.zoomBackground],//拉伸模式
    this.expandedTitleScale = 1.5,//展开标题大小
  }) 
  • CollapseMode属性
CollapseMode.none:背景不跟随滚动
CollapseMode.parallax:背景跟随滚动但是具有滚动视差效果
CollapseMode.pin:背景完全随着滚动
  • StretchMode属性
zoomBackground:背景小部件将展开以填充额外的空间
blurBackground:使用[ImageFilter.blur]效果,背景将模糊
fadeTitle:随着用户过度滚动,FlexibleSpaceBar标题将消失

基本例子:

import 'package:flutter/material.dart';
class SliverAppBarPage extends StatefulWidget {
  const SliverAppBarPage({Key? key}) : super(key: key);

  @override
  State<SliverAppBarPage> createState() => _SliverAppBarPageState();
}
class _SliverAppBarPageState extends State<SliverAppBarPage> {
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
        body: CustomScrollView(
          slivers: [
            const SliverAppBar(
              title: Text('标题'),//标题
              expandedHeight: 200,//展开高度
              floating: false,//滑动时是否悬浮
              pinned: true,//标题栏固定
              snap: false,
              backgroundColor: Colors.green,
            ),
            SliverFixedExtentList(
                delegate: SliverChildBuilderDelegate(
                    (context,int index) => Card(
                      child: Container(
                        alignment: Alignment.center,
                        color: Colors.primaries[(index % 15)],
                        child: Text("Item $index",style: const TextStyle(fontSize: 30,color: Colors.white),),
                      ),
                    )),
                itemExtent: 80
            )
          ],
        ),
    );
  }
}

Simulator Screen Shot - iPhone 14 Pro Max - 2022-11-06 at 15.54.23.png

  • 添加leadingactions
leading: IconButton(onPressed: (){}, icon: const Icon(Icons.arrow_back)),
actions: [
    IconButton(onPressed: (){}, icon: const Icon(Icons.add)),
    IconButton(onPressed: (){}, icon: const Icon(Icons.more_horiz))
],

image.png

  • 滑动标题上移效果 flexibleSpace
 flexibleSpace: const FlexibleSpaceBar(
    title: Text('移动标题'),
    centerTitle: true,
    collapseMode: CollapseMode.pin,
  ),

image.png

  • flexibleSpace加背景图
 flexibleSpace:  FlexibleSpaceBar(
    background: Image.asset("images/logo.png"),
    title: const Text('移动标题'),
    centerTitle: true,
    collapseMode: CollapseMode.pin,
  ),

image.png

完整例子:

import 'package:flutter/material.dart';

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

  @override
  State<SliverAppBarPage> createState() => _SliverAppBarPageState();
}

class _SliverAppBarPageState extends State<SliverAppBarPage> {
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
        body: CustomScrollView(
          slivers: [
             SliverAppBar(
              leading: IconButton(onPressed: (){}, icon: const Icon(Icons.arrow_back)),
              actions: [
                IconButton(onPressed: (){}, icon: const Icon(Icons.add)),
                IconButton(onPressed: (){}, icon: const Icon(Icons.more_horiz))
              ],
              flexibleSpace:  FlexibleSpaceBar(
                background: Image.asset("images/logo.png",fit: BoxFit.fill,),
                title: const Text('移动标题'),
                centerTitle: true,
                collapseMode: CollapseMode.pin,
                stretchModes: const [StretchMode.fadeTitle],
              ),
              title: const Text('标题'),//标题
              expandedHeight: 200,//展开高度
              floating: false,//滑动时是否悬浮
              pinned: true,//标题栏固定
              snap: false,
              backgroundColor: Colors.green,
            ),
            SliverFixedExtentList(
                delegate: SliverChildBuilderDelegate(
                    (context,int index) => Card(
                      child: Container(
                        alignment: Alignment.center,
                        color: Colors.primaries[(index % 15)],
                        child: Text("Item $index",style: const TextStyle(fontSize: 30,color: Colors.white),),
                      ),
                    )),
                itemExtent: 80
            )
          ],
        ),
    );
  }
}