mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

A sliver that shows its [child] when the user scrolls forward and hides it when the user scrolls backwards. Similar headers can be found in Google Photos and Facebook. This sliver is preferable to the general purpose SliverPersistentHeader for its relatively narrow use case because there's no need to create a SliverPersistentHeaderDelegate or to predict the header's size. https://github.com/flutter/flutter/assets/1377460/82b67dfb-5d38-4adf-9415-fc8527d0eb9f
122 lines
3.0 KiB
Dart
122 lines
3.0 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
void main() {
|
|
runApp(const SliverFloatingHeaderApp());
|
|
}
|
|
|
|
class SliverFloatingHeaderApp extends StatelessWidget {
|
|
const SliverFloatingHeaderApp({ super.key });
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return const MaterialApp(
|
|
home: FloatingHeaderExample(),
|
|
);
|
|
}
|
|
}
|
|
|
|
class FloatingHeaderExample extends StatefulWidget {
|
|
const FloatingHeaderExample({ super.key });
|
|
|
|
@override
|
|
State<FloatingHeaderExample> createState() => _FloatingHeaderExampleState();
|
|
}
|
|
|
|
class _FloatingHeaderExampleState extends State<FloatingHeaderExample> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return const Scaffold(
|
|
body: SafeArea(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(4),
|
|
child: CustomScrollView(
|
|
slivers: <Widget>[
|
|
SliverFloatingHeader(
|
|
child: ListHeader(
|
|
text: 'SliverFloatingHeader\nScroll down a little to show\nScroll up a little to hide',
|
|
),
|
|
),
|
|
ItemList(),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// A widget that displays its text within a thick rounded rectangle border
|
|
class ListHeader extends StatelessWidget {
|
|
const ListHeader({
|
|
super.key,
|
|
required this.text,
|
|
});
|
|
|
|
final String text;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ThemeData theme = Theme.of(context);
|
|
final ColorScheme colorScheme = theme.colorScheme;
|
|
|
|
return Container(
|
|
color: colorScheme.background,
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
child: Material(
|
|
color: colorScheme.primaryContainer,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
side: BorderSide(
|
|
width: 7,
|
|
color: colorScheme.outline,
|
|
),
|
|
),
|
|
child: Container(
|
|
alignment: Alignment.center,
|
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
child: Text(
|
|
text,
|
|
textAlign: TextAlign.center,
|
|
style: theme.textTheme.headlineMedium!.copyWith(
|
|
color: colorScheme.onPrimaryContainer,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// A placeholder SliverList of 50 items.
|
|
class ItemList extends StatelessWidget {
|
|
const ItemList({
|
|
super.key,
|
|
this.itemCount = 50,
|
|
});
|
|
|
|
final int itemCount;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
|
return SliverList(
|
|
delegate: SliverChildBuilderDelegate(
|
|
(BuildContext context, int index) {
|
|
return Card(
|
|
color: colorScheme.onSecondary,
|
|
child: ListTile(
|
|
textColor: colorScheme.secondary,
|
|
title: Text('Item $index'),
|
|
),
|
|
);
|
|
},
|
|
childCount: itemCount,
|
|
),
|
|
);
|
|
}
|
|
}
|