跳到主內容

在列表上方放置浮動應用欄

如何將浮動應用欄或導航欄置於列表上方。

本指南介紹瞭如何在 Flutter 應用中將浮動應用欄或導航欄放置在列表上方。

概述

#

為了方便使用者檢視專案列表,您可能希望在使用者向下滾動列表時最小化應用欄(導航欄)。

將應用欄放入 CustomScrollView 中,您可以建立一個能夠最小化或在滾動列表項時移出螢幕的應用欄。

本教程演示瞭如何透過以下步驟使用 CustomScrollView 顯示帶有應用欄的列表,該應用欄會隨著使用者向下滾動列表而最小化:

  1. 建立一個 CustomScrollView
  2. CustomScrollView 新增浮動應用欄。
  3. CustomScrollView 新增專案列表。

1. 建立 CustomScrollView

#

要建立浮動應用欄,請將應用欄放入同時包含專案列表的 CustomScrollView 中。這可以同步應用欄和專案列表的滾動位置。您可以將 CustomScrollView 小部件視為一種允許您混合搭配不同型別的可滾動列表和小部件的 ListView

提供給 CustomScrollView 的可滾動列表和小部件被稱為 *slivers*(切片)。有多種型別的 sliver,例如 SliverListSliverGridSliverAppBar。事實上,ListViewGridView 小部件正是使用 SliverListSliverGrid 小部件來實現滾動的。

在此示例中,建立一個包含 SliverListCustomScrollView。此外,如果程式碼中存在 app bar 屬性,請將其刪除。

dart
MaterialApp(
  title: 'Floating App Bar',
  home: Scaffold(
    // No app bar property provided yet.
    body: CustomScrollView(
      // Add the app bar and list of items as slivers in the next steps.
      slivers: <Widget>[],
    ),
  ),
);
dart
CupertinoApp(
  title: 'Floating Navigation Bar',
  home: CupertinoPageScaffold(
    // No navigation bar property provided yet.
    child: CustomScrollView(
      // Add the navigation bar and list of items as slivers in the next steps.
      slivers: <Widget>[],
    ),
  ),
);

2. 新增浮動應用欄

#

接下來,向 CustomScrollView 新增一個應用欄。

Flutter 提供了 SliverAppBar 小部件,它與常規的 AppBar 小部件非常相似,使用 SliverAppBar 可以顯示標題、標籤頁、影像等。

此外,SliverAppBar 還允許您建立一個“浮動”應用欄,當您不在頁面頂部時,它會收縮並浮動。

要實現此效果:

  1. 從僅顯示標題的應用欄開始。
  2. pinned 屬性設定為 true
  3. 新增一個填充可用 expandedHeightflexibleSpace 小部件。
dart
slivers: [
  // Add the app bar to the CustomScrollView.
  SliverAppBar(
    // Provide a standard title.
    title: Text('Floating App Bar'),
    // Pin the app bar when scrolling.
    pinned: true,
    // Display a placeholder widget to visualize the shrinking size.
    flexibleSpace: Placeholder(),
    // Make the initial height of the SliverAppBar larger than normal.
    expandedHeight: 200,
  ),
],

Flutter 提供了 CupertinoSliverNavigationBar 小部件,它允許您擁有一個“浮動”導航欄,該導航欄會在您向下滾動時收縮,並在您不在頁面頂部時浮動。

要實現此效果:

  1. CupertinoSliverNavigationBar 新增到 CustomScrollView
  2. 從僅顯示標題的應用欄開始。
dart
slivers: [
  // Add the navigation bar to the CustomScrollView.
  CupertinoSliverNavigationBar(
    // Provide a standard title.
    largeTitle: Text('Floating App Bar'),
  ),
],

3. 新增專案列表

#

現在已經設定好了應用欄,請將專案列表新增到 CustomScrollView 中。您有兩種選擇:SliverListSliverGrid。如果您需要依次顯示專案列表,請使用 SliverList 小部件。如果您需要顯示網格列表,請使用 SliverGrid 小部件。

dart
// Next, create a SliverList
SliverList.builder(
  // The builder function returns a ListTile with a title that
  // displays the index of the current item.
  itemBuilder: (context, index) =>
      ListTile(title: Text('Item #$index')),
  // Builds 50 ListTiles
  itemCount: 50,
)
dart
// Next, create a SliverList
SliverList.builder(
  // The builder function returns a CupertinoListTile with a title
  // that displays the index of the current item.
  itemBuilder: (context, index) =>
      CupertinoListTile(title: Text('Item #$index')),
  // Builds 50 CupertinoListTile
  itemCount: 50,
)

互動示例

#
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 app bar provided to 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),
              // Pin the app bar when scrolling
              pinned: 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.builder(
              // The builder function returns a ListTile with a title that
              // displays the index of the current item.
              itemBuilder: (context, index) =>
                  ListTile(title: Text('Item #$index')),
              // Builds 50 ListTiles
              itemCount: 50,
            ),
          ],
        ),
      ),
    );
  }
}
import 'package:flutter/cupertino.dart';

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

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

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

    return CupertinoApp(
      title: title,
      home: CupertinoPageScaffold(
        // No navigation bar provided to CupertinoPageScaffold,
        // only a body with a CustomScrollView.
        child: CustomScrollView(
          slivers: [
            // Add the navigation bar to the CustomScrollView.
            const CupertinoSliverNavigationBar(
              // Provide a standard title.
              largeTitle: Text(title),
            ),
            // Next, create a SliverList
            SliverList.builder(
              // The builder function returns a CupertinoListTile with a title
              // that displays the index of the current item.
              itemBuilder: (context, index) =>
                  CupertinoListTile(title: Text('Item #$index')),
              // Builds 50 CupertinoListTile
              itemCount: 50,
            ),
          ],
        ),
      ),
    );
  }
}