📅  最后修改于: 2023-12-03 15:24:40.959000             🧑  作者: Mango
AppBar
的高度 - Dart在开发移动应用时,我们经常会遇到需要向上滚动页面并在顶部添加 AppBar
的情况。当用户向上滚动页面时,我们希望 AppBar
消失并且页面最上方的内容完全填满屏幕。但是常常会出现问题,因为 AppBar
的高度会占据我们想要填充的空间。在本文中,我们将提供一种通过控制器在颤动中减去 AppBar
高度的可靠方法。
SliverAppBar
SliverAppBar
是一个特殊的 AppBar
,它可以与 CustomScrollView
一起使用。SliverAppBar
不会像普通的 AppBar
一样占据页面的空间,而是将其压缩到一个可滚动的小部件中。通过使用 SliverAppBar
,我们可以轻松地在颤动中减去 AppBar
的高度。
我们创建一个新的 SliverAppBar
小部件,然后将其放置在 CustomScrollView
中:
CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
title: Text('My App'),
pinned: true,
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
'https://example.com/image.jpg',
fit: BoxFit.cover,
),
),
),
...
],
)
我们需要注意以下几点:
CustomScrollView
的 controller
设置为 _scrollController
,这样我们就可以在颤动时监听滚动事件。pinned
属性设置为 true
,这样 SliverAppBar
将保持在屏幕的顶部。expandedHeight
属性设置为 200.0
,这是 SliverAppBar
将始终保留的高度。FlexibleSpaceBar
将一个 Image
小部件放置在 SliverAppBar
的内部部分。接下来,我们需要监听 CustomScrollView
的滚动事件并根据需要更改顶部内容的高度。我们将使用一个 ScrollController
来监视滚动事件,并使用一个布尔值来跟踪当前是否正在颤动:
final _scrollController = ScrollController();
bool _isShrinking = false;
在 CustomScrollView
中,我们将使用 _scrollController
监听颤动并根据需要更改 _isShrinking
的值:
_scrollController.addListener(() {
if (_scrollController.offset > (_scrollController.position.minScrollExtent + kToolbarHeight)) {
if (!_isShrinking) {
setState(() {
_isShrinking = true;
});
}
} else {
if (_isShrinking) {
setState(() {
_isShrinking = false;
});
}
}
});
在上述代码中,我们检查滚动位置是否超过了 CustomScrollView
的最小距离(minScrollExtent
)和 AppBar
的高度(kToolbarHeight
)。如果已经超过了这个位置,我们会设置 _isShrinking
为 true
,这样我们就可以在稍后的步骤中调整页面的高度。
最后,我们需要根据 _isShrinking
的值来调整页面的高度。我们可以通过将 SliverAppBar
的大小设置为 0.0
以实现减去 AppBar
高度的效果:
SliverAppBar(
...
expandedHeight: _isShrinking ? 0.0 : 200.0,
...
)
在代码中,我们将 expandedHeight
的值根据 _isShrinking
的值设置为 0.0
或 200.0
。这样在向上滚动页面时,SliverAppBar
将逐渐消失并使内容完全填满屏幕。
在本文中,我们学习了如何使用 SliverAppBar
和 CustomScrollView
在颤动中减去 AppBar
的高度。通过在颤动事件中使用控制器来监视滚动并根据需要更改高度,我们成功地实现了这个效果。
(完整代码见下面)
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _scrollController = ScrollController();
bool _isShrinking = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
title: Text('My App'),
pinned: true,
expandedHeight: _isShrinking ? 0.0 : 200.0,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
'https://example.com/image.jpg',
fit: BoxFit.cover,
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
padding: EdgeInsets.all(20.0),
child: Text('Item $index'),
);
},
childCount: 100,
),
),
],
),
);
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.offset > (_scrollController.position.minScrollExtent + kToolbarHeight)) {
if (!_isShrinking) {
setState(() {
_isShrinking = true;
});
}
} else {
if (_isShrinking) {
setState(() {
_isShrinking = false;
});
}
}
});
}
}