使用 SliverAppBar 时如何使 body 的一部分可滚动而另一部分固定
How to make one part of body scrollable and other as fixed when using SliverAppBar
我正在尝试制作一个 UI in flutter,其中我使用的是 SliverAppBar(我提到这个是因为我需要使用 CustomScrollView 或 NestedScrollView),现在在 body 中,我是让前两个元素在到达屏幕顶部时不滚动,而底部列表则滚动。
使用 CustomScrollView,它要么作为一个整体滚动,要么根本不滚动(包括 Appbar)。
在 NestedScrollView 中,如果我使用 NeverScrollableScrollPhysics,appbar 会滚动,而 body 不会。现在我要么使整个 body 可滚动,要么出现像素错误。请帮助我。
我在下面添加了 NestedScrollView 代码。一旦条条消失,我需要将搜索栏和转到购物车容器固定在顶部。
NestedScrollView(
physics: NeverScrollableScrollPhysics(),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
backgroundColor: Color(0xffececec),
shadowColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.black),
pinned: false,
centerTitle: true,
expandedHeight: 200.0,
floating: false,
forceElevated: innerBoxIsScrolled,
// snap: true,
flexibleSpace: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
padding: EdgeInsets.only(top: 80),
child: Row(
children: [
banner(
image),
banner(
image),
banner(
image),
],
),
)),
actions: [
InkWell(
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (_) => Cart()));
},
child: Icon(
Icons.shopping_cart,
color: Colors.black,
),
),
SizedBox(width: Units.width(context) * 0.03),
],
)
];
},
body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Column(
children: [
Row(
children: [
Text('Search'),
Icon(
FontAwesomeIcons.search,
color: Colors.white,
),
],
),
Container(
height: Units.height(context) * 0.1,
width: Units.height(context) * 0.17,
child: Text(
"Go to cart",
style: TextStyle(
fontSize: Units.regularText(context) * 0.9,
fontWeight: FontWeight.bold),
),
),
ListView(
shrinkWrap: true,
physics: AlwaysScrollableScrollPhysics(),
children: [
Center(
child: Wrap(
children: [
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
],
),
),
],
),
],
),
),
),
SliverAppBar
的替代方法是使用名为 sticky_headers
的包来获得您所追求的用户体验(我认为)
希望这个非常的基本示例可以演示我认为您正在寻找的功能:
首先,安装包:
sticky_headers: ^0.2.0
然后导入:
导入 'package:sticky_headers/sticky_headers.dart';
最后,实现:
Scaffold(
appBar: AppBar(title: Text("Sticky Headers Example")),
body: ListView(
children: [
Container(color: Colors.yellow, height: 100, width: double.infinity, child: Text("one"),),
StickyHeader(
header:
Column(
children: [
Container(color: Colors.green, height: 100, width: double.infinity, child: Text("two"),),
Container(color: Colors.blue, height: 100, width: double.infinity, child: Text("three"),),
],
),
content: Column(
children: [
Container(color: Colors.red, height: 600, width: double.infinity, child: Text("four"),),
Container(color: Colors.orange, height: 600, width: double.infinity, child: Text("five"),)
],
),
),
],
),
);
注意:您还可以包含多个置顶headers:
Scaffold(
appBar: AppBar(title: Text("Sticky Headers Example")),
body: ListView(
children: [
StickyHeader(
header: Container(color: Colors.green, height: 100, width: double.infinity, child: Text("six"),),
content: Container(color: Colors.red, height: 300, width: double.infinity, child: Text("seven"),),
),
StickyHeader(
header: Container(color: Colors.purple, height: 100, width: double.infinity, child: Text("eight"),),
content: Container(color: Colors.blue, height: 800, width: double.infinity, child: Text("nine"),),
),
],
),
);
我正在尝试制作一个 UI in flutter,其中我使用的是 SliverAppBar(我提到这个是因为我需要使用 CustomScrollView 或 NestedScrollView),现在在 body 中,我是让前两个元素在到达屏幕顶部时不滚动,而底部列表则滚动。 使用 CustomScrollView,它要么作为一个整体滚动,要么根本不滚动(包括 Appbar)。 在 NestedScrollView 中,如果我使用 NeverScrollableScrollPhysics,appbar 会滚动,而 body 不会。现在我要么使整个 body 可滚动,要么出现像素错误。请帮助我。
我在下面添加了 NestedScrollView 代码。一旦条条消失,我需要将搜索栏和转到购物车容器固定在顶部。
NestedScrollView(
physics: NeverScrollableScrollPhysics(),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
backgroundColor: Color(0xffececec),
shadowColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.black),
pinned: false,
centerTitle: true,
expandedHeight: 200.0,
floating: false,
forceElevated: innerBoxIsScrolled,
// snap: true,
flexibleSpace: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
padding: EdgeInsets.only(top: 80),
child: Row(
children: [
banner(
image),
banner(
image),
banner(
image),
],
),
)),
actions: [
InkWell(
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (_) => Cart()));
},
child: Icon(
Icons.shopping_cart,
color: Colors.black,
),
),
SizedBox(width: Units.width(context) * 0.03),
],
)
];
},
body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Column(
children: [
Row(
children: [
Text('Search'),
Icon(
FontAwesomeIcons.search,
color: Colors.white,
),
],
),
Container(
height: Units.height(context) * 0.1,
width: Units.height(context) * 0.17,
child: Text(
"Go to cart",
style: TextStyle(
fontSize: Units.regularText(context) * 0.9,
fontWeight: FontWeight.bold),
),
),
ListView(
shrinkWrap: true,
physics: AlwaysScrollableScrollPhysics(),
children: [
Center(
child: Wrap(
children: [
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
lappyCard(context),
],
),
),
],
),
],
),
),
),
SliverAppBar
的替代方法是使用名为 sticky_headers
希望这个非常的基本示例可以演示我认为您正在寻找的功能:
首先,安装包:
sticky_headers: ^0.2.0
然后导入: 导入 'package:sticky_headers/sticky_headers.dart';
最后,实现:
Scaffold(
appBar: AppBar(title: Text("Sticky Headers Example")),
body: ListView(
children: [
Container(color: Colors.yellow, height: 100, width: double.infinity, child: Text("one"),),
StickyHeader(
header:
Column(
children: [
Container(color: Colors.green, height: 100, width: double.infinity, child: Text("two"),),
Container(color: Colors.blue, height: 100, width: double.infinity, child: Text("three"),),
],
),
content: Column(
children: [
Container(color: Colors.red, height: 600, width: double.infinity, child: Text("four"),),
Container(color: Colors.orange, height: 600, width: double.infinity, child: Text("five"),)
],
),
),
],
),
);
注意:您还可以包含多个置顶headers:
Scaffold(
appBar: AppBar(title: Text("Sticky Headers Example")),
body: ListView(
children: [
StickyHeader(
header: Container(color: Colors.green, height: 100, width: double.infinity, child: Text("six"),),
content: Container(color: Colors.red, height: 300, width: double.infinity, child: Text("seven"),),
),
StickyHeader(
header: Container(color: Colors.purple, height: 100, width: double.infinity, child: Text("eight"),),
content: Container(color: Colors.blue, height: 800, width: double.infinity, child: Text("nine"),),
),
],
),
);