flutter - CustomScrollView 中的多个 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”也浮动。
解决方案
这似乎是一个限制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
推荐阅读
- html - 选中单选按钮时如何设置粗体标签
- key - 更换密钥后 RFID-RC522 无法访问扇区
- wpf - Prism7.1 中新的 IModule 界面缺少对面向方面编程的支持
- excel - 在php中使用phpspreadsheet写入多表excel
- spring - 依次运行IntegrationFlow
- sql - 如何根据应用于不同列的条件查找行差异
- ios - 我们可以在 iPhone 应用程序图标的左上角显示徽章图标,而不是通常的右上角显示吗?
- angular6 - hostEl.createShadowRoot 不是 Angular 6 中使用 jest 进行单元测试的函数
- ios - 在现有键值中添加新数组对象而不更改 - Objective C
- openmdao - 我无法记录/访问衍生品