[英]How to implemented Nested ListView.builder in Flutter?
我已经看过这篇文章
对于嵌套滚动,但根据官方 flutter 频道的视频中的解释,这不是正确的方法
我想实现以下布局
列表 header,如 Claim requested credentials、Claim received credentials、Pending Requests 等是动态的,将来自后端。 此外,列表 header 中的每个项目,如模块 1:设计金融服务,也是动态的
所以我需要列表中的列表
我正在使用 CustomScroll 但我无法实现内部列表视图
我正在寻找一个惰性列表选项,而不仅仅是将内部列表映射到列或列表上,因为内部列表可能包含 100 个项目
这是我取得的成就
这是示例代码
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
HeaderGradient(),
Positioned(
top: 110,
left: 0,
right: 0,
bottom: 0,
child: Container(
padding: const EdgeInsets.all(8.0),
decoration: const BoxDecoration(
color: grayColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: ManageCredentialHeader(),
),
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return ManageCredentialCard();
}, childCount: 10))
],
),
),
)
],
),
);
}
}
和
class ManageCredentialCard extends StatelessWidget {
const ManageCredentialCard({super.key});
@override
Widget build(BuildContext context) {
return Card(
color: Theme.of(context).colorScheme.background,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Column(
children: [
const ManageCredentialCardHeader(),
const ManageCredentialCardItem()
],
),
),
);
}
}
ManageCredentialCardItem
是内部列表
一旦我将ManageCredentialCardItem
包装在ListView.builder
,我就会收到错误提示
RenderFlex children have non-zero flex but incoming height constraints are
unbounded.
When a column is in a parent that does not provide a finite height constraint,
for example if it is
in a vertical scrollable, it will try to shrink-wrap its children along the
vertical axis. Setting a
flex on a child (e.g. using Expanded) indicates that the child is to expand to
fill the remaining
space in the vertical direction.
检查示例 repo以检查我尝试过的内容和完整的源代码
要解决“ListView.builder”问题,我建议将其包装成“Expanded”并将“ListView”的“shrinkWrap”属性设置为 true。
至于列表问题中的列表,我不确定我是否理解正确,但是将内部列表的“主要”属性设置为 false 应该可以使它跟随一般列表的滚动并避免在内部滚动。
可能还需要将 'shrinkWrap' 设置为 true,因为它没有定义高度,使其不懒惰,但我会尝试用 'Expanded' 包装它,因为它可能有相同的结果保持它懒惰
正如@Yeasin Sheikh 所建议的,您不需要在ManageCredentialCardItem
中使用Listview.builder
,因为ManageCredentialCardItem
的父级正在处理滚动,即
SliverList( // 👈 This will handle scroll
delegate: SliverChildBuilderDelegate((context, index) {
return ManageCredentialCard(); //👈 So you can use column instead
},childCount: 10))
如果您有必须使用ListView.builder
从远程源获取结果的用例,则可以在ListView.builder
中使用shrinkWrap: true
prop
我不太确定你想要达到什么效果,但是:
如果您的目标是像这样在您的ManageCredentialCard
中显示完整的项目列表:
您只需要使用以下内容更新ManageCredentialCard
小部件
class ManageCredentialCard extends StatelessWidget {
const ManageCredentialCard({super.key});
@override
Widget build(BuildContext context) {
return Card(
color: Theme.of(context).colorScheme.background,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Column(
children: [
const ManageCredentialCardHeader(),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return const ManageCredentialCardItem();
},
itemCount: 20,
)
// const ManageCredentialCardItem()
],
),
),
);
}
}
但
如果您的目标是限制Cards
的大小,并且能够像这样滚动 Items 列表
您必须使用SizeBox
为您的卡片定义高度限制。
class ManageCredentialCard extends StatelessWidget {
const ManageCredentialCard({super.key});
@override
Widget build(BuildContext context) {
return Card(
color: Theme.of(context).colorScheme.background,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Column(
children: [
const ManageCredentialCardHeader(),
SizedBox(
height: 150,
child: ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemBuilder: (context, index) {
return const ManageCredentialCardItem();
},
itemCount: 10,
),
)
// const ManageCredentialCardItem()
],
),
),
);
}
}
您唯一需要做的就是在到达其中一个内部列表的Listview
时滚动主列表视图。
为此,您可以使用NotificationListener
小部件,如本文所述:
Flutter:ListView:当子 ListView 到达底部时滚动父 ListView - ClampingScrollPhysics 在大小容器中不起作用
我指的是在条子上生成所有东西
child: CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: ManageCredentialHeader(),
),
for (int i = 0; i < 10; i++)
SliverPadding(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
childCount: 10 + 1, //extend by 1 for header
(context, index) {
return index == 0
? const ManageCredentialCardHeader()
: const ManageCredentialCardItem();
}),
),
)
],
),
您还可以为儿童创建自定义条子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.