跳至主要内容

在列表上方放置浮动应用栏

为了方便用户查看项目列表,您可能希望在用户向下滚动列表时隐藏应用栏。如果您的应用显示一个“高”应用栏,占据了大量的垂直空间,这一点尤其重要。

通常,您可以通过向Scaffold小部件提供appBar属性来创建应用栏。这会创建一个固定的应用栏,始终保持在Scaffoldbody之上。

将应用栏从Scaffold小部件移动到CustomScrollView允许您创建一个应用栏,当您滚动浏览CustomScrollView中包含的项目列表时,该应用栏会滚动到屏幕外。

此示例演示了如何使用CustomScrollView显示项目列表,并在顶部显示一个应用栏,该应用栏在用户使用以下步骤向下滚动列表时会滚动到屏幕外。

  1. 创建一个CustomScrollView
  2. 使用SliverAppBar添加一个浮动应用栏。
  3. 使用SliverList添加项目列表。

1. 创建一个CustomScrollView

#

要创建浮动应用栏,请将应用栏放置在也包含项目列表的CustomScrollView中。这会同步应用栏和项目列表的滚动位置。您可以将CustomScrollView小部件视为一个ListView,它允许您混合和匹配不同类型的可滚动列表和小部件。

提供给CustomScrollView的可滚动列表和小部件称为sliver。有几种类型的sliver,例如SliverListSliverGridSliverAppBar。实际上,ListViewGridView小部件使用SliverListSliverGrid小部件来实现滚动。

在本示例中,创建一个包含SliverAppBarSliverListCustomScrollView。此外,请移除您提供给Scaffold小部件的任何应用栏。

dart
Scaffold(
  // No appBar property provided, only the body.
  body: CustomScrollView(
      // Add the app bar and list of items as slivers in the next steps.
      slivers: <Widget>[]),
);

2. 使用SliverAppBar添加一个浮动应用栏

#

接下来,向CustomScrollView添加一个应用栏。Flutter 提供了SliverAppBar小部件,它与普通的AppBar小部件非常相似,使用SliverAppBar显示标题、选项卡、图像等。

但是,SliverAppBar还允许您创建一个“浮动”应用栏,当用户向下滚动列表时,该应用栏会滚动到屏幕外。此外,您可以配置SliverAppBar,使其在用户滚动时收缩和展开。

要创建此效果

  1. 从仅显示标题的应用栏开始。
  2. floating属性设置为true。这允许用户在向上滚动列表时快速显示应用栏。
  3. 添加一个flexibleSpace小部件,以填充可用的expandedHeight
dart
CustomScrollView(
  slivers: [
    // Add the app bar to the CustomScrollView.
    const SliverAppBar(
      // Provide a standard title.
      title: Text(title),
      // Allows the user to reveal the app bar if they begin scrolling
      // back up the list of items.
      floating: true,
      // Display a placeholder widget to visualize the shrinking size.
      flexibleSpace: Placeholder(),
      // Make the initial height of the SliverAppBar larger than normal.
      expandedHeight: 200,
    ),
  ],
)

3. 使用SliverList添加项目列表

#

现在您已将应用栏就位,请向CustomScrollView添加项目列表。您有两个选项:SliverListSliverGrid。如果您需要依次显示项目列表,请使用SliverList小部件。如果您需要显示网格列表,请使用SliverGrid小部件。

SliverListSliverGrid小部件采用一个必需参数:SliverChildDelegate,它为SliverListSliverGrid提供一个小部件列表。例如,SliverChildBuilderDelegate允许您创建一个项目列表,这些项目会在您滚动时延迟构建,就像ListView.builder小部件一样。

dart
// Next, create a SliverList
SliverList(
  // Use a delegate to build items as they're scrolled on screen.
  delegate: SliverChildBuilderDelegate(
    // The builder function returns a ListTile with a title that
    // displays the index of the current item.
    (context, index) => ListTile(title: Text('Item #$index')),
    // Builds 1000 ListTiles
    childCount: 1000,
  ),
)

交互式示例

#
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    const title = 'Floating App Bar';

    return MaterialApp(
      title: title,
      home: Scaffold(
        // No appbar provided to the Scaffold, only a body with a
        // CustomScrollView.
        body: CustomScrollView(
          slivers: [
            // Add the app bar to the CustomScrollView.
            const SliverAppBar(
              // Provide a standard title.
              title: Text(title),
              // Allows the user to reveal the app bar if they begin scrolling
              // back up the list of items.
              floating: true,
              // Display a placeholder widget to visualize the shrinking size.
              flexibleSpace: Placeholder(),
              // Make the initial height of the SliverAppBar larger than normal.
              expandedHeight: 200,
            ),
            // Next, create a SliverList
            SliverList(
              // Use a delegate to build items as they're scrolled on screen.
              delegate: SliverChildBuilderDelegate(
                // The builder function returns a ListTile with a title that
                // displays the index of the current item.
                (context, index) => ListTile(title: Text('Item #$index')),
                // Builds 1000 ListTiles
                childCount: 1000,
              ),
            ),
          ],
        ),
      ),
    );
  }
}