Material Floating Search Bar

pub package GitHub Stars

一个可扩展的浮动搜索栏的Flutter实现,也称为持久化搜索,类似于Google在其应用程序中广泛使用的搜索栏。

CircularFloatingSearchBarTransition ExpandingFloatingSearchBarTransition SlideFadeFloatingSearchBarTransition

单击此处查看完整示例。

安装

将其添加到您的pubspec.yaml文件中

dependencies:
  material_floating_search_bar: ^0.3.7

从命令行安装软件包

flutter packages get

如果您喜欢此软件包,请考虑通过在GitHub上为其加星标并在pub.dev上点赞来支持它!❤️

用法

FloatingSearchBar应放置在您Widget树中的主内容上方,并允许其填充所有可用空间。

@override
Widget build(BuildContext context) {
  return Scaffold(
    // This is handled by the search bar itself.
    resizeToAvoidBottomInset: false,
    body: Stack(
      fit: StackFit.expand,
      children: [
        buildMap(),
        buildBottomNavigationBar(),
        buildFloatingSearchBar(),
      ],
    ),
  );
}

Widget buildFloatingSearchBar() {
  final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;

  return FloatingSearchBar(
    hint: 'Search...',
    scrollPadding: const EdgeInsets.only(top: 16, bottom: 56),
    transitionDuration: const Duration(milliseconds: 800),
    transitionCurve: Curves.easeInOut,
    physics: const BouncingScrollPhysics(),
    axisAlignment: isPortrait ? 0.0 : -1.0,
    openAxisAlignment: 0.0,
    width: isPortrait ? 600 : 500,
    debounceDelay: const Duration(milliseconds: 500),
    onQueryChanged: (query) {
      // Call your model, bloc, controller here.
    },
    // Specify a custom transition to be used for
    // animating between opened and closed stated.
    transition: CircularFloatingSearchBarTransition(),
    actions: [
      FloatingSearchBarAction(
        showIfOpened: false,
        child: CircularButton(
          icon: const Icon(Icons.place),
          onPressed: () {},
        ),
      ),
      FloatingSearchBarAction.searchToClear(
        showIfClosed: false,
      ),
    ],
    builder: (context, transition) {
      return ClipRRect(
        borderRadius: BorderRadius.circular(8),
        child: Material(
          color: Colors.white,
          elevation: 4.0,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: Colors.accents.map((color) {
              return Container(height: 112, color: color);
            }).toList(),
          ),
        ),
      );
    },
  );
}

Scrollables一起使用

默认情况下,builder返回的Widget不允许具有无界(无限)高度。这对于搜索栏能够在其子项区域下方点击时自行消失是必要的。(例如,当您有一系列项目但项目不足以填满整个屏幕时,如上方的GIF所示,用户期望在点击列表中的最后一项下方时能够关闭搜索栏)。

因此,所有ScrollablesshrinkWrap应设置为truephysics应设置为NeverScrollableScrollPhysics。在Columns上,mainAxisSize应设置为MainAxisSize.min

如果您不想要此行为,可以将isScrollControlled标志设置为true。然后,您可以使用扩展的Widgets,例如带Scrollables的,但要确保搜索栏可能无法检测到在背景区域的点击。

自定义

有许多自定义选项

字段 描述
body 显示在FloatingSearchBar下方的Widget。如果FloatingSearchBar应该对滚动事件做出反应(即,当Scrollable向下滚动时从视图中隐藏,并在向上滚动时再次显示)则很有用。有关更多信息,请参见此处
accentColor 用于诸如进度指示器之类的元素的颜色。如果未指定,则默认为主题的强调色。
backgroundColor 卡片的颜色。如果未指定,则默认为theme.cardColor
shadowColor elevation > 0时绘制的阴影的颜色。如果未指定,则默认为Colors.black54
iconColor 指定时,将覆盖此FloatingSearchBar的主题图标颜色,例如可以轻松调整所有actionsleadingActions的图标颜色。
backdropColor FloatingSearchBar打开时填充可用空间的颜色。通常是偏黑色的。如果未指定,则默认为Colors.black26
margins 其父项边缘的内边距。这可用于定位FloatingSearchBar。如果未指定,FloatingSearchBar将尝试将其自身定位在顶部,并偏移MediaQuery.of(context).viewPadding.top以避免状态栏。
padding 卡片的内边距。仅水平值会被考虑。
insets leadingActions、输入字段和actions之间的内边距。仅水平值会被考虑。
高度 卡片的高度。如果未指定,则默认为48.0像素。
elevation 卡片的阴影。
width FloatingSearchBar的宽度。默认情况下,FloatingSearchBar将扩展以填充所有可用宽度。此值可以设置为避免这种情况。
openWidth FloatingSearchBar打开时的宽度。当打开时的最大宽度应与maxWidth指定的宽度不同时,可以使用此属性。如果未指定,将使用maxWidth的值。
axisAlignment 当可用宽度大于maxWidth指定的宽度时,FloatingSearchBar应如何对齐。如果未指定,则默认为0.0,该值会将FloatingSearchBar居中。
openAxisAlignment 当可用宽度大于openMaxWidth指定的宽度时,FloatingSearchBar应如何对齐。如果未指定,将使用axisAlignment的值。
border 卡片的边框。
borderRadius 卡片的BorderRadius。如果未指定,则默认为BorderRadius.circular(4)
hintStyle TextField中提示文本的TextStyle
queryStyle TextField中输入文本的TextStyle
clearQueryOnClose FloatingSearchBar关闭时,是否应清除当前查询。如果未指定,则默认为true
automaticallyImplyDrawerHamburger 当Widget树中存在带有DrawerScaffold时,是否应显示汉堡菜单。
closeOnBackdropTap 当点击背景时,FloatingSearchBar是否应关闭。如果未指定,则默认为true
automaticallyImplyBackButton 如果封闭的路由可以被弹出,是否自动显示后退按钮。如果未指定,则默认为true
progress 卡片内LinearProgressIndicator的进度。当设置为0..1之间的double时,将显示一个已确定的LinearProgressIndicator。当设置为true时,FloatingSearchBar将显示一个不确定的LinearProgressIndicator。当为nullfalse时,将隐藏LinearProgressIndicator
transitionDuration 打开和关闭状态之间的动画持续时间。
transitionCurve 打开和关闭状态之间的动画曲线。
debounceDelay 用户停止键入到onQueryChanged回调被调用之间的时间延迟。这很有用,例如,如果您想避免为每个字符执行昂贵的操作,例如网络调用。
title FloatingSearchBar关闭时,用于替换TextField的Widget。
提示 TextField提示文本的值。
actions TextField之后显示的一系列Widget。可以考虑使用FloatingSearchBarActions来实现更高级的、可以与FloatingSearchBar交互的操作。在从左到右的语言中,它们将显示在TextField的左侧。
leadingActions TextField之前显示的一系列Widget。可以考虑使用FloatingSearchBarActions来实现更高级的、可以与FloatingSearchBar交互的操作。在从左到右的语言中,它们将显示在TextField的右侧。
onQueryChanged TextField内的查询输入发生更改时调用的回调。
onSubmitted 当用户提交查询时(例如,按下搜索按钮)调用的回调。
onFocusChanged FloatingSearchBar获得或失去焦点时调用的回调。
transition 用于在关闭和打开状态之间进行动画的过渡。下面列出了所有可用的过渡。
builder FloatingSearchBar主体的构建器。通常是项目列表。请注意,除非isScrollControlled设置为true,否则FloatingSearchBar的主体不能具有无界高度,这意味着所有ScrollablesshrinkWrap应设置为true
控制器 FloatingSearchBar的控制器,可用于以编程方式打开、关闭、显示或隐藏FloatingSearchBar
isScrollControlled FloatingSearchBar的主体是否使用了自己的Scrollable。这将允许FloatingSearchBar的主体具有无界高度。请注意,当设置为true时,当用户点击Scrollable中子项的高度下方时,FloatingSearchBar将无法自行关闭,当子项小于可用高度时。
initiallyHidden 设置为true以初始隐藏搜索栏。您必须调用控制器上的show才能再次显示FloatingSearchBar

过渡

到目前为止,共有三种过渡类型,如上所示。

过渡 描述
CircularFloatingSearchBarTransition 将子项裁剪为扩展的圆形。
ExpandingFloatingSearchBarTransition FloatingSearchBar的背景填充所有可用空间。类似于Gmail等许多Google应用中使用的。
SlideFadeFloatingSearchBarTransition 垂直滑动并淡出子项。

您还可以通过扩展FloatingSearchBarTransition轻松创建自己的自定义过渡。

滚动

Scrolling

浮动搜索栏的一个常见行为是,当用户向下滚动Scrollable时消失,并在向上滚动时再次出现。通过将您的Widget传递给FloatingSearchBarbody字段,可以轻松实现这一点。这样,FloatingSearchBar就可以监听ScrollNotifications。为了使FloatingSearchBar不与Widget树下方的所有Scrollable交互,您应该将所有需要与FloatingSearchBar交互的Scrollable包装在FloatingSearchBarScrollNotifier中。

示例

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FloatingSearchBar(
      // Your pages or just a simple Scaffold...
      body: IndexedStack(
        children: [
          MyAwesomePage(),
        ],
      ),
    );
  }
}

class MyAwesomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// Wrap your Scrollable in a FloatingSearchBarScrollNotifier
    /// to indicate that the FloatingSearchBar should react to
    /// scroll events from this Scrollable.
    return FloatingSearchBarScrollNotifier(
      child: ListView.builder(
        itemCount: 42,
        itemBuilder: (_, index) => Item('Item $index'),
      ),
    );
  }
}

FloatingSearchBarController

FloatingSearchBarController可用于控制FloatingSearchBar显而易见)。

方法 描述
open() 展开FloatingSearchBar
close() 关闭FloatingSearchBar
show() FloatingSearchBar先前通过hide()隐藏时,显示FloatingSearchBar
hide() 视觉上隐藏FloatingSearchBar(滑出屏幕)。
query 设置InputField中查询的输入。
清除() 清除查询。

浮动搜索应用栏

有时,FloatingSearchBar可能不是您用例最适合的搜索方法。因此,还有一个FloatingSearchAppBar。它是一个普通的AppBar,具有简单的搜索集成,与普通的FloatingSearchBar非常相似。

FloatingSearchAppBar example

附加自定义

除了FloatingSearchBar的大多数字段外,FloatingSearchAppBar还具有以下附加字段:

字段 描述
colorOnScroll body内的Scrollable滚动时(即Scrollable不在顶部)栏的颜色。
liftOnScrollElevation body内的Scrollable滚动时(即Scrollable不在顶部)栏的阴影。
alwaysOpened 栏是否应始终处于打开状态。例如,如果您有一个专门用于搜索的页面,这很有用。
hideKeyboardOnDownScroll body内的Scrollable滚动时隐藏键盘,并在用户滚动到顶部时再次显示键盘。

GitHub

查看 Github