CupertinoSliverNavigationBar

一个带有iOS11风格大标题的iOS风格导航栏,使用slivers实现

CupertinoSliverNavigationBar是Flutter中用于实现iOS风格(Cupertino)的**可折叠导航栏(Sliver Navigation Bar)**的组件,通常与CustomScrollView或者NestedScrollView结合使用,实现类似iOS原生"大标题"导航栏的效果(如iOS设置应用)。

核心特性

  1. 大标题模式: 滚动时标题从大字体变为小字体(类似iOS 11+的导航栏)
  2. 可折叠: 滚动时导航栏会收缩(类似SliverAppBarfloating效果)
  3. iOS风格: 自动适配iOS的过渡动画和样式

构造函数

CupertinoSliverNavigationBar.new({
  Key? key, 
  Widget? largeTitle, 
  Widget? leading, 
  bool automaticallyImplyLeading = true, 
  bool automaticallyImplyTitle = true, 
  bool alwaysShowMiddle = true, 
  String? previousPageTitle, 
  Widget? middle, 
  Widget? trailing, 
  Border? border = _kDefaultNavBarBorder, 
  Color? backgroundColor, 
  bool automaticBackgroundVisibility = true, 
  bool enableBackgroundFilterBlur = true, 
  Brightness? brightness, 
  EdgeInsetsDirectional? padding, 
  bool transitionBetweenRoutes = true, 
  Object heroTag = _defaultHeroTag, 
  bool stretch = false, 
  PreferredSizeWidget? bottom, 
  NavigationBarBottomMode? bottomMode
})

“大标题导航栏 + 折叠搜索框” 做成一条Sliver,滚动时搜索框会像原生iOS的Settings/Mail一样:

  • 在顶部时:大标题+下方搜索框
  • 向上滚动后:搜索框被吸到导航栏中间,成为紧凑的搜索栏
CupertinoSliverNavigationBar.search({
  Key? key, 
  required Widget searchField, 
  Widget? largeTitle, 
  Widget? leading, //自定义左侧按钮
  bool automaticallyImplyLeading = true, 
  bool automaticallyImplyTitle = true, 
  bool alwaysShowMiddle = true, 
  String? previousPageTitle,   //返回按钮文字
  Widget? middle, 
  Widget? trailing, //右侧按钮
  Border? border = _kDefaultNavBarBorder,  //底部分隔线 
  Color? backgroundColor, //背景色
  bool automaticBackgroundVisibility = true, 
  bool enableBackgroundFilterBlur = true, 
  Brightness? brightness, 
  EdgeInsetsDirectional? padding, 
  bool transitionBetweenRoutes = true, 
  Object heroTag = _defaultHeroTag, 
  bool stretch = false, //弹性拉伸
  NavigationBarBottomMode? bottomMode = NavigationBarBottomMode.automatic, 
  ValueChanged<bool>? onSearchableBottomTap
})

属性

属性名属性类型说明
alwaysShowMiddleboolmiddle字段对应的组件始终可见
automaticallyImplyLeadingbool若没有提供leading组件,且automaticallyImplyLeading为true,则leading会自动显示为返回箭头图标按钮
automaticallyImplyTitlebool若没有提供largeTitle组件,且automaticallyImplyTitle设置为true,则largeTitle会自动从当前CupertinoPageRoute中提取标题文本
automaticBackgroundVisibilitybool导航栏滚动后背景显示情况
backgroundColorColor?背景颜色
borderBorder?导航栏边框,默认情况下只显示底部的边框
bottomPreferredSizeWidget?如果没有设置largeTitle情况下,设置bottom组件显示在导航栏底部
bottomModeNavigationBarBottomMode?当导航栏折叠到最小时,「大标题」是否仍然保留在导航栏底部,还是完全切换到中间的小标题
enableBackgroundFilterBlurbool是否给导航栏背景加iOS风格的(毛玻璃blur)效果
heroTagObject当页面发生Hero转场,告诉Flutter哪两个导航栏是同一对Hero,避免同类型组件因为默认tag相同而互相抢动画
largeTitleWidget?导航栏标题组件
leadingWidget?放置在导航栏首部的组件,如果不设置的话,通常会展示一个返回箭头或者取消按钮
middleWidget?导航栏中间用于替换largeTitle的组件
onSearchableBottomTapValueChanged<bool>?点击折叠的搜索区域时的回调
opaquebool设置为true时,当内容向上滚动、导航栏被压缩成普通高度后,背景是否强制保持100%不透明
paddingEdgeInsetsDirectional?内边距
previousPageTitleString?路由返回按钮旁边的文字内容
searchFieldWidget?导航栏搜索栏的搜索框组件
stretchbool设置导航栏向下滚动时,区域展示效果
trailingWidget?导航栏尾部的组件,通常会设置搜索或者额外操作
transitionBetweenRoutesbool路由切换时,上下页是否共享Hero动画

automaticBackgroundVisibility设置:

场景true(默认)false
用户把列表 拉到最顶部再往下拽导航栏背景 完全透明,只剩标题文字和按钮导航栏背景 始终可见(毛玻璃/颜色不消失)
向上滚动一点点背景立即重新出现背景保持可见,无变化

onSearchableBottomTap的作用是:

  1. 页面处于折叠状态(用户往上滑了一段,大标题已收起)
  2. 搜索栏此时变成一条细高的横条(高度≈56 pt,iOS 叫它 searchable bottom)
  3. 用户点一下这条横条 → 框架会先自动展开搜索框并聚焦键盘,随后再调用设置的onSearchableBottomTap

previousPageTitle的作用是:

场景返回按钮文字
不设置 previousPageTitle系统规则:<br>• 如果上一页是 CupertinoPageRoute 且设置了 title,就用它;<br>• 否则显示本地化 “Back”。
设置 previousPageTitle: '列表'无论上一页标题是什么,统一显示 “列表”

stretch的作用是:

stretch下拉时的表现
false(默认)导航栏高度固定,下拉只会露出空白背景,无弹性拉伸。
true下拉时大标题区域会被 拉长(最多约 100 pt),松手后弹性回弹,和 iOS 系统 Mail、设置等应用一致。