我需要在屏幕顶部实现过滤器。这个想法是,当您向下滚动时,过滤器应该消失,但标题和前导小部件应该保持可见。此外,向上滚动时,过滤器应该重新出现。有人对如何实现这一目标有任何建议吗?此功能的最佳用途是什么?
您可以使用 ScrollController 来检测滚动方向并结合使用 SliverAppBar 和 SliverPersistentHeader 来实现布局。
import 'package:flutter/material.dart';
class ScrollableFiltersPage extends StatefulWidget {
@override
_ScrollableFiltersPageState createState() => _ScrollableFiltersPageState();
}
class _ScrollableFiltersPageState extends State<ScrollableFiltersPage> {
final ScrollController _scrollController = ScrollController();
bool _showFilters = true;
double _lastOffset = 0;
@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.offset > _lastOffset && _showFilters) {
setState(() => _showFilters = false); // Scrolling down
} else if (_scrollController.offset < _lastOffset && !_showFilters) {
setState(() => _showFilters = true); // Scrolling up
}
_lastOffset = _scrollController.offset;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
controller: _scrollController,
slivers: [
SliverAppBar(
pinned: true,
title: Text('Title'),
leading: Icon(Icons.menu),
),
SliverPersistentHeader(
pinned: true,
delegate: _FiltersDelegate(
showFilters: _showFilters,
child: Container(
color: Colors.blueGrey,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(onPressed: () {}, child: Text("Filter 1")),
TextButton(onPressed: () {}, child: Text("Filter 2")),
TextButton(onPressed: () {}, child: Text("Filter 3")),
],
),
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('Item $index')),
childCount: 50,
),
),
],
),
);
}
}
class _FiltersDelegate extends SliverPersistentHeaderDelegate {
final bool showFilters;
final Widget child;
_FiltersDelegate({required this.showFilters, required this.child});
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return AnimatedOpacity(
duration: Duration(milliseconds: 200),
opacity: showFilters ? 1.0 : 0.0,
child: child,
);
}
@override
double get maxExtent => 50.0;
@override
double get minExtent => 50.0;
@override
bool shouldRebuild(covariant _FiltersDelegate oldDelegate) =>
showFilters != oldDelegate.showFilters || child != oldDelegate.child;
}
我希望这对您有帮助。 谢谢你:)