在列表顶部放置一个浮动的 app bar
为了方便用户查看列表,你可能希望在用户向下滚动列表时隐藏 app bar,尤其在你的 app bar 特别高,导致它占据了很多竖向空间的时候。
一般情况下,你可以通过给 Scaffold
组件设置一个 appBar
属性来创建一个 app bar。这个 app bar 会始终固定在 Scaffold
组件的 body
上方。
把 app bar 从 Scaffold
组件挪到一个 CustomScrollView
里,可以让你创建一个随着你滑动 CustomScrollView
里列表的同时在屏幕外自动随之滚动的 app bar。
下面这篇教程将介绍如何通过 CustomScrollView
来生成一个带有随着用户滑动列表同时会在屏幕外随之滚动的 app bar 的列表。
-
创建一个
CustomScrollView
-
通过
SliverAppBar
来添加一个浮动的 app bar -
通过
SliverList
来添加列表
1. 创建一个 CustomScrollView
#
要创建一个浮动的 app bar,你需要将 app bar
放在一个包含列表的 CustomScrollView
里,这会同步 app bar 和列表的滚动位置。你可以把 CustomScrollView
组件当成一个可以让你把不同类型的可滚动列表和组件混合匹配在一起的 ListView
。
可以放在 CustomScrollView
里的可滚动列表和组件我们称之为 slivers。有几种类型的 slivers,比如 SliverList
、SliverGrid
和 SliverAppBar
。实际上,ListView
和 GridView
组件底层使用的就是 SliverList
和 SliverGrid
。
以下例子演示了创建一个包含 SliverAppBar
和 SliverList
的 CustomScrollView
。另外你需要删除你之前可能设置在 Scaffold
组件上的 app bar!
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
来添加一个浮动的 app bar
#
接下来为 CustomScrollView
添加一个 app bar。
Flutter 提供开箱即用的 SliverAppBar
组件,与普通的 AppBar
组件非常相似,你可以使用 SliverAppBar
来显示标题、标签、图像等内容。
同时,SliverAppBar
组件也提供一种创建 “浮动” app bar 的能力,当用户向下滚动列表时,app bar 会随之在屏幕外滚动。此外,你可以配置 SliverAppBar
在用户滚动时缩小或展开。
要达到这个效果:
-
先创建一个只显示标题的 app bar
-
将
floating
属性设为true
,这使用户在向上滚动列表时能快速显示 app bar。 -
添加一个
flexibleSpace
组件,这个组件将填充可用的expandedHeight
。
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
来添加一个列表
#
现在你已经创建好一个 app bar,接下来应该给 CustomScrollView
添加一个列表。你有两种选择:选择 SliverList
或者 SliverGrid
。如果你需要一个一个往下排地显示列表中的内容,应该用 SliverList
组件。如果需要网格状地显示列表中的内容,应该用 SliverGrid
组件。
SliverList
和 SliverGrid
组件都需要一个必要参数:SliverChildDelegate
。虽然听起来很花哨,但它只是用来给列表组件
SliverList
或 SliverGrid
提供一个代理。例如,SliverChildBuilderDelegate
允许你创建一组可以在滚动时懒加载的列表项,就和 ListView.builder
组件差不多。
// 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,
),
),
],
),
),
);
}
}
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-07-03。 查看文档源码 或者 为本页面内容提出建议。