在 Flutter 中的垂直 ScrollView 内的水平 ListView 中显示来自 Firestore 的数据
Posted
技术标签:
【中文标题】在 Flutter 中的垂直 ScrollView 内的水平 ListView 中显示来自 Firestore 的数据【英文标题】:Displaying data from Firestore in a Horizontal ListView within a Vertical ScrollView in Flutter 【发布时间】:2021-10-11 17:42:42 【问题描述】:我对 Flutter 中的编码相当陌生,目前,我正在尝试开发一个图像分类应用程序。我有一个 Cloud Firestore 数据库,其中数据库中的每个文档都包含两个字段:图像标签和图像 URL。下面附上一个数据库结构的例子:
Example of the structure of the database
我正在尝试根据图像各自的标签对图像进行分类,并将它们显示在标签应显示在可滚动水平 ListView
顶部的位置,而属于标签的图像将显示在可滚动水平ListView
下方。此外,水平的ListView
小部件应包含在垂直的ScrollView
中。要实现的图像显示示例如下:
Example of the display of images to be achieved
我已经尝试过ListView
和SingleChildScrollView
之类的方法,但我最接近目标的是使用StreamBuilder
和ListView.builder
,如下面的代码所示。
代码:
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.orange[400],
centerTitle: true,
title: Text('Revision'),
titleTextStyle: TextStyle(
fontSize: 24.0,
),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection('Images').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot)
if(!snapshot.hasData)
return Center(
child: CircularProgressIndicator(),
);
return ListView(
children: snapshot.data.docs.map((document)
return SizedBox(
height: 300,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 1,
itemBuilder: (_, __) => Container(
margin: EdgeInsets.all(12),
width: 300,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(document['url']),
fit: BoxFit.scaleDown,
)
),
),
),
);
).toList(),
);
),
);
即便如此,结果仍然与前面示例中所示的图像显示相距甚远:
Example of the result of the code
结果的显示似乎是应用程序中非常常见的结构,但是,我似乎无法让它工作好几天。 :(
任何帮助将不胜感激,如果可能的话,请问是否可以修改上面的代码以实现上述结果。谢谢你,祝你有美好的一天!
编辑(这是我设法完全显示标签和图像但无法对其进行分类的代码):
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.orange[400],
centerTitle: true,
title: Text('Revision'),
titleTextStyle: TextStyle(
fontSize: 24.0,
),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection('Images').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot)
if(!snapshot.hasData)
return Center(
child: CircularProgressIndicator(),
);
return ListView(
children: snapshot.data.docs.map((document)
return Center(
child: Column(
children: [
SizedBox(height: 20),
Text(document['label']),
SizedBox(height: 20),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(document['url']),
fit: BoxFit.scaleDown
)
),
),
],
),
);
).toList(),
);
),
);
结果:Example of the edit done
编辑结果致:https://medium.com/quick-code/reading-lists-from-firestore-using-streambuilder-in-flutter-eda590f461ed
【问题讨论】:
【参考方案1】:好的,所以你想要一个上面有标题/标题的图像列表,它可以水平滚动,但列表也可以垂直滚动? 尝试这样的事情。 首先,您需要一个带有标题和图像权的图像列表。 因此,您需要一个 ListView.Builder(如果您不知道列表中有多少项目,则该 Builder 非常适合从在线数据库中获取数据)并将 scrollDirection 设置为水平并将 shrinkwrap 设置为 true。 在构建器中,您希望将 itemCount 设置为将存在的项目的长度(希望您知道它是如何完成的)并返回一个类 showData(您可以将其命名为任何名称)
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 15,
itemBuilder: (BuildContext context, int index) => ShowData();
创建一个新类 ShowData 并为其添加 Card,在 card 的子级中添加 Padding(稍后您将使用它来设置空间) 然后在 padding 的子项中添加一个列,就像您当前所做的那样。 在该列中,您可以添加图像及其标题,您将从数据库中获得 Title + Image,ListView.builder 将一次创建一个。所以每个标题+图像将是一张卡片,第二张卡片将是另一个标题+图像。 现在要使其垂直滚动,只需使用 singlechildscrollview 包装卡片(如果卡片不起作用,请尝试使用列)
您将拥有一个包含标题和图像并且可以水平滚动的项目列表,如果它下面有更多项目,那么它也可以垂直滚动(仅当它位于屏幕下方时)
您可以从这里获得想法 Horizontal ListView inside a Vertical ScrollView in Flutter 和这里 https://youtu.be/CQt91j_MsUw
【讨论】:
非常感谢!这个问题困扰了我好几天,很高兴您的精彩建议已成功解决。以上是关于在 Flutter 中的垂直 ScrollView 内的水平 ListView 中显示来自 Firestore 的数据的主要内容,如果未能解决你的问题,请参考以下文章
ScrollView中的Horizontal RecyclerView:垂直滚动时如何获得焦点?
UIScrollview中的UIWebview向scrollview发送垂直滚动事件