如何在您的Flutter应用程序中添加SliverAppBar

Posted 小陈乱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在您的Flutter应用程序中添加SliverAppBar相关的知识,希望对你有一定的参考价值。

什么是SliverAppBar?

在Flutter中,SliverAppBar是AppBar部件的继承者,它允许您创建浮动的应用栏效果。SliverAppBar在屏幕向上滚动时展开AppBar,向下滚动时折叠。

当用户向下滚动一个长的列表时,你也可以完全删除或隐藏AppBar。SliverAppBar有很多自定义选项,所以你可以根据你的需要来定制它。

如果你是一个视觉学习者,可以看看这个快速视频教程。

下面是让SliverAppBar启动和运行的最小代码。

return Scaffold(
  //1
  body: CustomScrollView(
    slivers: <Widget>[
      //2
      SliverAppBar(
        expandedHeight: 250.0,
        flexibleSpace: FlexibleSpaceBar(
          title: Text('Goa', textScaleFactor: 1),
          background: Image.asset(
            'assets/images/beach.png',
            fit: BoxFit.fill,
          ),
        ),
      ),
      //3
      SliverList(
        delegate: SliverChildBuilderDelegate(
          (_, int index) 
            return ListTile(
              leading: Container(
                  padding: EdgeInsets.all(8),
                  width: 100,
                  child: Placeholder()),
              title: Text('Place $index + 1', textScaleFactor: 2),
            );
          ,
          childCount: 20,
        ),
      ),
    ],
  ),
); 

要添加CustomScrollView,请将CustomScrollView ,放在Scaffold widget的body部分。这是用来同步AppBar和列表的滚动位置的。

有几个小部件可以被添加到CustomScrollView中,SliverAppBar就是其中之一。

SliverAppBar提供了普通AppBar小部件的所有功能,并增加了动画功能。flexibleSpace ,用于在AppBar展开时显示任何小部件。expandedHeight ,用于设置FlexibleSpaceBar这个小部件的高度。

SliverList显示项目的列表。我们不能使用普通的ListView类,因为CustomScrollView接受sliver类型的widget。

下面是输出结果。

海滩图片来源:vecteezy.com

这里是代码如何转化为设计的。

自定义浮动行为

默认行为将在向下滚动时隐藏SliverAppBar,向上滚动时到达列表中的第一个项目时展开。然而,SliverAppBar有选项可以自定义这种行为。

SliverAppBar有三个重要的属性,即pinned,snapfloating 。设置这三个参数的组合可以使SliverAppBar按照你的需要工作。

让我们通过一个实际的例子来证明这些属性是如何工作的。

pinned: true,snap: false,floating: false:

只设置一个钉子的值为true ,当向下滚动时,SliverAppBar就会粘在顶部。当向上滚动时,SliverAppBar只在到达列表中的第一个项目时展开。

pinned: true,snap: true,floating: true:

当所有的参数都设置为true ,SliverAppBar在向下滚动时停留在顶部,向上滚动时完全展开,即使没有到达列表中的第一个项目。

pinned: true,snap: false,floating: true:

当只有snap值被设置为false ,SliverAppBar在向下滚动时保持在顶部。当我们向上滚动时,背景图片开始膨胀,并随着我们的滚动而停止。

pinned: false,snap: false,floating: true:

只将浮动值设置为true ,在向下滚动时隐藏SliverAppBar,当我们向上滚动时开始显示背景图片。

pinned: false,snap: true,floating: true:

如果你想让SliverAppBar在向下滚动时保持隐藏,而在向上滚动时显示完整的背景图片,即使是在列表中的第一个项目没有显示时。你可以只设置snap和floating为true

在SliverAppBar内添加AppBar

需要注意的是,SliverAppBar并不能完全替代正常的AppBar。在Flutter中编写应用程序的好处是,你可以混合和匹配小部件来创造新的东西。

例如,你可能会遇到这样的情况:你需要在SliverAppBar内显示一个包含搜索框的AppBar。

让我们看一个例子。下面是一个电子商务应用程序,当向下滚动时,横幅图片被隐藏,而搜索框仍然停留在顶部。

下面是如何做到这一点的。

Scaffold(
  body: CustomScrollView(
    slivers: <Widget>[
      SliverAppBar(
        ...
        bottom: AppBar(
          title: Container(
            height: 45,
            child: TextField(
              decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: 'Enter a search term'),
            ),
          ),
        ),
      ),
      SliverGrid(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 2,
        ),
        delegate: SliverChildBuilderDelegate(
          (BuildContext context, int index) 
            return ItemTile(index);
          ,
        ),
      ),
    ],
  ),
) 

让我们来分解一下代码。首先,只要在SliverAppBar的bottom 属性中写一个普通的AppBar。该AppBar将包含TextField部件作为搜索项目的输入框。

项目的列表显示在SliverGrid中。由于我们使用了CutomScrollView,我们不能在这里使用普通的GridView

用SliverAppBar添加TabBar

TabBar小部件用于显示不同类别的内容或用户可用的功能。在某些情况下,你可能想用SliverAppBar来显示TabBar。

让我们来看看如何添加TabBar并使其表现得像下面的例子。

Scaffold(
  body: DefaultTabController(
    length: 3,
    child: NestedScrollView(
      headerSliverBuilder:
          (BuildContext context, bool innerBoxIsScrolled) 
        return <Widget>[
          SliverAppBar(
            pinned: false,
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Goa', textScaleFactor: 1),
              background: Image.asset(
                'assets/images/beach.png',
                fit: BoxFit.fill,
              ),
              stretchModes: [StretchMode.zoomBackground],
            ),
            //collapsedHeight: 100,
          ),
          SliverPersistentHeader(
            delegate: MySliverPersistentHeaderDelegate(
              TabBar(
                tabs: [
                  Tab(icon: Icon(Icons.flight)),
                  Tab(icon: Icon(Icons.directions_transit)),
                  Tab(icon: Icon(Icons.directions_car)),
                ],
              ),
            ),
            pinned: false,
          ),
        ];
      ,
      body: TabBarView(
        children: [
          Icon(Icons.flight, size: 350),
          Icon(Icons.directions_transit, size: 350),
          Icon(Icons.directions_car, size: 350),
        ],
      ),
    ),
  ),
) 

NestedScrollView部件被用来返回标题,作为SliverAppBar和SliverPersistentHeader部件的组合。SliverAppBar内部使用SliverPersistentHeader来实现收缩和增长的效果。你可以使用这个小部件来显示SliverAppBar下面的标签。

TabBarView在NestedScrollView widget的body 参数中给出。

下面是上面的代码如何转化为设计。

钉住TabBar

如果你仔细观察,当向下滚动时,TabBar是隐藏的。为了改善用户体验,在向下滚动时,你应该始终保持TabBar在顶部可见。

在SliverPersistentHeader中设置pinned 值为true ,将解决这个问题。

SliverPersistentHeader(
  delegate: MySliverPersistentHeaderDelegate(
    TabBar(
      tabs: [
        ...
      ],
    ),
  ),
  pinned: true,
) 

下面是它的工作原理。

监听SliverAppBar的状态(展开或折叠

如果想要监听SliverAppBar的状态,以确定它是展开的还是折叠的,你可以使用返回的值来改变SliverAppBar的设置。例如,当它被展开时,你可以改变标题的文本颜色。

late ScrollController _scrollController;
//----------
@override
void initState() 
  // TODO: implement initState
  super.initState();

  _scrollController = ScrollController()
    ..addListener(() 
      setState(() 
        _textColor = _isSliverAppBarExpanded ? Colors.white : Colors.blue;
      );
    );

//----------
bool get _isSliverAppBarExpanded 
  return _scrollController.hasClients &&
      _scrollController.offset > (200 - kToolbarHeight);

//----------
Scaffold(
  body: CustomScrollView(
    controller: _scrollController,
    slivers: ...,
  ),
); 
  • ScrollController被创建并分配给CustomScrollView
  • 监听器被添加到ScrollController中,以计算SliverAppBar是否被展开。
  • 从监听器返回的值被用来设置标题的文本颜色。

下面是当SliverAppBar展开时改变标题 "Goa "颜色的输出。

结论

如果你已经走到了这一步,你应该具备了在你的Flutter应用程序中添加SliverAppBar的所有必要知识。

这个例子中使用的完整代码可以在GitHub上找到。

福利

大家在正式学习了flutter之后就能够深入体会,flutter学习并不算难,难得是需要具有一个清晰、系统的思维,为了帮助大家更好的理解flutter,我给大家准备了一份《Flutter进阶学习笔记》,相信大家能在它的帮助下快速掌握flutter的知识,有需要的朋友可以扫描下方卡片自取

《Flutter进阶学习笔记》

目录

第一章 为什么 Flutter 是跨平台开发的终极之选

  • 这是为什么?
  • 跨平台开发
  • 什么是Flutter
  • Flutter特性
  • Flutter 构建应用的工具
  • 使用 Flutter 构建的热门应用
  • 构建 Flutter 应用的成本

第二章 在Windows上搭建Flutter开发环境

  • 使用镜像
  • 系统要求
  • 获取Flutter SDK
  • 编辑器设置
  • android设置
  • 起步: 配置编辑器
  • 起步: 体验
  • 体验热重载

第三章 编写您的第一个 Flutter App

  • 创建 Flutter app
  • 使用外部包(package)
  • 添加一个 有状态的部件(Stateful widget)
  • 创建一个无限滚动ListView
  • 添加交互
  • 导航到新页面
  • 使用主题更改UI

第四章 Flutter开发环境搭建和调试

  • 开发环境的搭建
  • 模拟器的安装与调试
  • 开发环境的搭建
  • 模拟器的安装与调试

第五章 Dart语法篇之基础语法(一)

  • 简述
  • Hello Dart
  • 数据类型
  • 变量和常量
  • 集合(List、Set、Map)
  • 流程控制
  • 运算符
  • 异常
  • 函数
  • 总结

第六章 Dart语法篇之集合的使用与源码解析(二)

  • List
  • Set
  • Map
  • Queue
  • LinkedList
  • HashMap
  • Map、HashMap、LinkedHashMap、SplayTreeMap区别
  • 命名构造函数from和of的区别以及使用建议

第七章 Dart语法篇之集合操作符函数与源码分析(三)

  • 简述
  • Iterable
  • forEach
  • map
  • any
  • every
  • where
  • firstWhere和singleWhere和lastWhere
  • join
  • take
  • takeWhile
  • skip
  • skipWhile
  • follwedBy
  • expand
  • reduce
  • elementAt

第八章 Dart语法篇之函数的使用(四)

  • 简述
  • 函数参数
  • 匿名函数(闭包,lambda)
  • 箭头函数
  • 局部函数
  • 顶层函数和静态函数
  • main函数
  • Function函数对象

第九章 Dart语法篇之面向对象基础(五)

  • 简述
  • 属性访问器(accessor)函数setter和getter
  • 面向对象中的变量
  • 构造函数
  • 抽象方法、抽象类和接口
  • 类函数
  • 总结

第十章 Dart语法篇之面向对象继承和Mixins(六)

  • 简述
  • 类的单继承
  • 基于Mixins的多继承
  • 总结

第十一章 Dart语法篇之类型系统与泛型(七)

  • 简述
  • 可选类型
  • 接口类型
  • 泛型
  • 类型具体化
  • 总结

第十二章 Flutter中的widget

  • Flutter页面-基础Widget
  • Widget
  • StatelessWidget
  • State生命周期
  • 基础widget
  • DefaultTextStyle
  • FlutterLogo
  • Icon
  • Iamge.asset
  • CircleAvatar
  • FadeInImage
  • 按钮
  • FlatButton
  • OutlineButton
  • TextFormField

有需要的朋友可以扫描下方二维码自取

以上是关于如何在您的Flutter应用程序中添加SliverAppBar的主要内容,如果未能解决你的问题,请参考以下文章

Sliver 应用栏无法正确显示 - Flutter

Flutter:我们检测到您的应用在您的 1 个或多个 app bundle 或 APK 的清单文件中包含 requestLegacyExternalStorage 标志

如何在这张图片中将多个列表视图添加到 sliver 列表中 - 颤动

如何解决 Flutter Problem 安装问题? [复制]

Flutter Sliver系列组件入门

Android在 Flutter 中使用 WebView