在 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

我已经尝试过ListViewSingleChildScrollView 之类的方法,但我最接近目标的是使用StreamBuilderListView.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 忽略水平安全区域

ScrollView swift 3中的垂直对齐图像

ScrollView中的Horizo​​ntal RecyclerView:垂直滚动时如何获得焦点?

UIScrollview中的UIWebview向scrollview发送垂直滚动事件

ViewPager中的视图在ScrollView中不能垂直滚动

ScrollView 在 Xamarin Forms 中的另一个 ScrollView 内