我需要有多个SliverAppBar,每个SliverAppBar在一个视图中都有自己的SliverList。当前,只有第一个SliverAppBar正确响应。
我当然已经在SO和Google上进行了扩展搜索,但是还没有找到解决方案!
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Details'),
),
body: CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
floating: true,
automaticallyImplyLeading: false,
title: Text('1'),
),
new SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('Text 1')),
childCount: 20,
),
),
new SliverAppBar(
automaticallyImplyLeading: false,
title: Text('2'),
floating: true,
),
new SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('Text 2')),
childCount: 20,
),
),
],
),
);
}
如果您要滚动,则在滚动列表时,我也希望标题“ 2”也浮动。
答案 0 :(得分:0)
这似乎是对CustomScrollView
的限制。可以解决此问题,但这非常棘手,除非您有固定高度的项目和固定长度的列表。如果是这样,您可以假设整个会话的高度(AppBar
高度+每个列表项的高度)。
看看:
class Foo extends StatefulWidget {
@override
_FooState createState() => _FooState();
}
class _FooState extends State<Foo> {
static const double listItemHeight = 50;
static const int listItemCount = 15;
static const double sessionHeight = kToolbarHeight + (listItemCount * listItemHeight);
int floatingAppBarIndex;
ScrollController controller;
@override
void initState() {
super.initState();
floatingAppBarIndex = 0;
controller = ScrollController()..addListener(onScroll);
}
void onScroll() {
double scrollOffset = controller.offset;
int sessionsScrolled = 0;
while (scrollOffset > sessionHeight) {
scrollOffset -= sessionHeight;
sessionsScrolled++;
}
if (sessionsScrolled != floatingAppBarIndex) {
setState(() {
floatingAppBarIndex = sessionsScrolled;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Details'),
),
body: CustomScrollView(
controller: controller,
slivers: <Widget>[
new SliverAppBar(
floating: floatingAppBarIndex == 0,
automaticallyImplyLeading: false,
title: Text('1'),
),
new SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return SizedBox(
height: listItemHeight,
child: ListTile(
title: Text('Text 1'),
),
);
},
childCount: listItemCount,
),
),
new SliverAppBar(
floating: floatingAppBarIndex == 1,
automaticallyImplyLeading: false,
title: Text('2'),
),
new SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return SizedBox(
height: listItemHeight,
child: ListTile(
title: Text('Text 2'),
),
);
},
childCount: listItemCount,
),
),
],
),
);
}
}
正如我所说,您仍然可以在具有可变值(项目高度和列表长度)的列表中执行此操作,但这非常棘手。如果是这种情况,建议您使用以下插件之一: https://pub.dartlang.org/packages/sticky_headers https://pub.dartlang.org/packages/flutter_sticky_header