任何关于从哪里开始的帮助都将是巨大的帮助,先感谢您!
编辑:我现在认为我理解了布局部分,但我只是找不到绘画应该发生的位置。
编辑2:为了澄清,这是期望的“粘性标头效果”:如何在RecyclerView中制作粘性标头?(无需外部库)这是“快照”效果:https://rubensousa.github.io/2016/08/recyclerviewsnap
对于"粘性标题效果",我自己也遇到了这个问题,所以我创建了这个包来管理带有slivers的粘性标题: https://github.com/letsar/flutter_sticky_header
CustomScrollView
中为每个部分创建一个SliverStickyHeader
。new SliverStickyHeader(
header: new Container(
height: 60.0,
color: Colors.lightBlue,
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: new Text(
'Header #0',
style: const TextStyle(color: Colors.white),
),
),
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(context, i) => new ListTile(
leading: new CircleAvatar(
child: new Text('0'),
),
title: new Text('List tile #$i'),
),
childCount: 4,
),
),
);
如果您需要,以上演示的完整源代码可以在这里获得:https://github.com/letsar/flutter_sticky_header/blob/master/example/lib/main.dart
希望这对您有所帮助。
非常简单:
使用 CustomScrollView
,并将 SliverList
和 SliverAppBar
作为其子项。如果需要,您可以用 SliverGrid
替换 SliverList
。
然后,根据您想要实现的效果,在SliverAppBar
上设置几个属性:
最终,您可能会得到类似于:
new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
title: new Text("Title"),
snap: true,
floating: true,
),
new SliverFixedExtentList(
itemExtent: 50.0,
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: new Text('list item $index'),
);
},
),
),
],
)
更好的是,您可以在单个CustomScrollView
中连接不同的滚动行为。这意味着您可以通过将SliverGrid
作为scrollView的子项添加,潜在地拥有一个网格后面跟着一个列表。SliverPersistentHeader
代码以实现自定义行为。 - Rémi RousseletanimateTo
。 - Rémi Rousselet我使用以下代码成功在Flutter中实现iOS应用程序的stickyheader效果 - 感谢这里编写的代码提供了灵感(https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/animation/home.dart#L112):
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
@required this.collapsedHeight,
@required this.expandedHeight,}
);
final double expandedHeight;
final double collapsedHeight;
@override double get minExtent => collapsedHeight;
@override double get maxExtent => math.max(expandedHeight, minExtent);
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return new Container(color: Colors.red,
child: new Padding(
padding: const EdgeInsets.only(
left: 8.0, top: 8.0, bottom: 8.0, right: 8.0),
child: new Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text("Time"), new Text("Price"), new Text("Hotness")
],
),
)
);
}
@override
bool shouldRebuild(@checked _SliverAppBarDelegate oldDelegate) {
return expandedHeight != oldDelegate.expandedHeight
|| collapsedHeight != oldDelegate.collapsedHeight;
}
}
为了使其固定,将_SliverAppBarDelegate添加到silvers小部件列表中:
new SliverPersistentHeader(delegate: new _SliverAppBarDelegate(collapsedHeight: 36.0, expandedHeight: 36.0), pinned: true, ),
我不太确定如何使_SliverAppBarDelegate自动包裹内容,我必须为它提供36个逻辑像素的大小才能使其工作。如果有人知道如何让它自动包裹内容,请在下面的答案中留言。
我解决了这个问题,建议使用sticky_and_expandable_list.
如果不使用sliver,您可以通过Flutter社区提供的优秀插件来实现此功能。
StickyHeader
或StickyHeaderBuilder
放置在任何可滚动内容中。ListView
中应用StickyHeader
的示例,那么其他小部件如SingleChildScrollView
或CustomScrollView
呢?SingleChildScrollView
和StickyHeader
,当然您可以将其放置在任何想要的SingleChildScrollView
中。return Container(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("My title"),
StickyHeader(
header: Container(
child: // Put here whatever widget you like as the sticky widget
),
content: Column(
children: [
Container(
child: // Put here whatever widget you like as scrolling content (Column, Text, ListView, etc...)
),
],
),
),
],
),
),
);