我试图使SliverPersistentHeaderDelegate先折叠,然后屏幕的其余部分滚动。
这是密码。
class MyHomePage extends StatelessWidget {
const MyHomePage({
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
physics: const PageScrollPhysics(),
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: SliverAppBarDelegate(),
),
const SliverToBoxAdapter(
child: SizedBox(height: 24),
),
SliverPersistentHeader(
pinned: true,
delegate: SliverGreenMenuBarDelegate(),
),
const SliverPadding(padding: EdgeInsets.only(bottom: 15)),
SliverFillRemaining(
child: SizedBox(
height: 200,
child: Container(
color: Colors.amber,
),
),
),
],
),
);
}
}
class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
SliverAppBarDelegate();
var expandedHeight = 220.0;
@override
double get maxExtent => expandedHeight;
@override
double get minExtent => kToolbarHeight + 20;
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
var colorScheme = Theme.of(context).colorScheme;
double radius() {
if (!overlapsContent && shrinkOffset == 0.0) {
return 20.0;
} else {
return 20 - shrinkOffset / 11;
}
}
final Widget appBar = FlexibleSpaceBar.createSettings(
minExtent: minExtent,
maxExtent: maxExtent,
currentExtent: math.max(minExtent, maxExtent - shrinkOffset),
child: AppBar(
actions: [
IconButton(
padding: const EdgeInsets.all(0),
constraints: const BoxConstraints(),
onPressed: () {},
icon: const Icon(Icons.abc),
),
Padding(
padding: const EdgeInsets.only(right: 16, left: 35),
child: IconButton(
padding: const EdgeInsets.all(0),
constraints: const BoxConstraints(),
onPressed: () {},
icon: const Icon(Icons.ac_unit_sharp),
),
),
],
flexibleSpace: const FlexibleSpaceBar(
expandedTitleScale: 1,
titlePadding: EdgeInsets.only(top: 4, left: 56, right: 56),
title: SafeArea(
child: Text("Hello world"),
),
),
elevation: 10,
shadowColor: colorScheme.secondary.withOpacity(0.2),
primary: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(radius()),
bottomRight: Radius.circular(radius()),
),
),
),
);
return appBar;
}
}
class SliverGreenMenuBarDelegate extends SliverPersistentHeaderDelegate {
@override
double get maxExtent => 75.0;
@override
double get minExtent => 40.0;
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
@override
Widget build(
BuildContext context,
double shrinkOffset,
bool overlapsContent,
) {
double horizontalPadding() {
if (!overlapsContent && shrinkOffset == 0.0) {
return 25.0;
} else {
return 25 - (shrinkOffset / 3);
}
}
double cornerRadius() {
if (!overlapsContent && shrinkOffset == 0.0) {
return 15.0;
} else {
return 15 - shrinkOffset / 5;
}
}
return FlexibleSpaceBar.createSettings(
maxExtent: maxExtent,
minExtent: minExtent,
currentExtent: math.max(minExtent, maxExtent - shrinkOffset),
isScrolledUnder: true,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: horizontalPadding()),
child: Container(
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(cornerRadius()),
topRight: Radius.circular(cornerRadius()),
bottomLeft: const Radius.circular(15),
bottomRight: const Radius.circular(15),
),
),
),
),
);
}
}
这是视频
基本上,我想要的是绿色的部分先崩溃,黄色的部分在它下面。
我如何才能做到这一点?
最终结果应该如下面的屏幕截图所示。
| 在scrool之后| After scrool |
| --| ------------ |
| | |
|
|
|
提前感谢您的帮助!
1条答案
按热度按时间t2a7ltrp1#
This video is output