flutter - 带有 ScrollController 的嵌套 ListView 不滚动
问题描述
我正在构建一个带有自定义导航栏的小部件,其中包括Stack
主体和导航栏。
@override
Widget build(BuildContext context) {
return Stack(
children: [
_buildBody(),
_buildNavigationBar(),
],
);
}
正文由ListView
带有标题的a 和ListView.builder
嵌套在内容下方的a 组成。
Widget _buildBody() {
return ListView(
padding: EdgeInsets.only(top: 44.0 + MediaQuery.of(context).padding.top),
controller: _scrollController,
children: [
Opacity(
opacity: 1.0 - _navigationBarOpacity,
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: _buildHeaderTitle(
title: widget.title,
fontSize: _largeFontSize,
fontWeight: _largeFontWeight,
color: widget.color,
),
),
),
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: widget.itemCount,
itemBuilder: (context, index) {
return widget.itemBuilder(context, index);
},
),
],
);
}
我ScrollController
在主要/根目录上使用 aListView
来淡入和淡出我的导航栏。这按预期工作。
但是,添加ScrollController
到ListView
停止任何滚动/弹跳交互。我怎样才能解决这个问题?
ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
setState(() {
double min = 0.0;
double max = 25.0;
_navigationBarOpacity = (_scrollController.offset - min) / (max - min);
if (_navigationBarOpacity < 0) _navigationBarOpacity = 0;
if (_navigationBarOpacity > 1) _navigationBarOpacity = 1;
});
});
}
有趣的是,如果我将 移动ScrollController
到 nestedt ListView.builder
,根会ListView
滚动/弹跳,但是我不能再根据偏移量调整 UI,因为它是错误的ListView
。
另一个有趣的地方,ListView
如果它的孩子超过它的高度,根会正常滚动。但是,在某些情况下它不会出现这种情况,我希望它会在拉动时反弹。
更新
即使我删除了 stack 和 nested ListView
,一个简单的单数ListView
的ScrollController
也不会在拖动时滚动,没有它,它会。这是需要解决的根本问题。
@override
Widget build(BuildContext context) {
return ListView(
padding: EdgeInsets.only(top: 44.0 + MediaQuery.of(context).padding.top),
controller: _scrollController,
children: [
Opacity(
opacity: 1.0 - _navigationBarOpacity,
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: _buildHeaderTitle(
title: widget.title,
fontSize: _largeFontSize,
fontWeight: _largeFontWeight,
color: widget.color,
),
),
),
],
);
}
解决方案
通过将父级包装ListView
在.PrimaryScrollController
primary = true
ListView
这允许PrimaryScrollController
管理控制器,但ListView
保持典型的滚动行为,因为它不再管理ScrollController
.
请参阅 Flutter 文档:https ://api.flutter.dev/flutter/widgets/ScrollView/primary.html
推荐阅读
- reactjs - 如何启用多边形(地理围栏)编辑启用,点击多边形本身,而不点击编辑按钮
- javascript - 如何更换或修复旧的 www.dynarch.com 日历
- oauth - 令牌端点如何知道在授权代码生成期间经过身份验证的用户
- c - calloc() 指向 struct 中的指针在 clang 上不起作用
- swift - Swift - 从网址保存视频
- python - 如何使用控制语句迭代列?
- pyspark - 在不平衡的数据集上为 pyspark (ml) 中的多类随机森林和 gbt 模型设置最佳阈值
- python - 'cover' 属性没有与之关联的文件。姜戈
- c# - TopMost 的替代方案,不关注任务栏
- node.js - 如何从 npm packge 访问 laravel .env 文件?