如何在颤动中直接将数据从 StreamBuilder 获取到 GridView 中?

Posted

技术标签:

【中文标题】如何在颤动中直接将数据从 StreamBuilder 获取到 GridView 中?【英文标题】:How to get data from the StreamBuilder into the GridView directly in flutter? 【发布时间】:2021-09-21 09:03:23 【问题描述】:

您好,我正在设置个人资料页面,我正在尝试从 Firestore 获取数据,所以我设置了一个 StreamBuilder 并给了它流来获取数据,但问题是如何使用该数据将其显示到我的 GridView 中?

我的代码:

StreamBuilder<List<UserModel>>(
     stream: userProviderData.user,
     builder: (context, snapshot) 
       return GridView(
         gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
           crossAxisCount: 2,
           crossAxisSpacing: 10,
           mainAxisSpacing: 10,
         ),
         primary: false,
         shrinkWrap: true,
         children: [
           Text(
             'How Do I get the FullName here?' ?? fullNameOnNullText,
             style: Theme.of(context).textTheme.subtitle2.copyWith(fontWeight: 
                 FontWeight.w600),
          ),
        ],
      );

【问题讨论】:

【参考方案1】:

您可以使用构建器中快照的.data 属性从StreamBuilder 获取数据。

由于您的数据是一个列表,您可以将其映射到GridView 中的子小部件列表。

见下文:

StreamBuilder<List<UserModel>>(
     stream: userProviderData.user,
     builder: (context, snapshot) 
       List<UserModel> userModelList = snapshot.data;

       return GridView(
         gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
           crossAxisCount: 2,
           crossAxisSpacing: 10,
           mainAxisSpacing: 10,
         ),
         primary: false,
         shrinkWrap: true,
         children: userModelList.map((UserModel userModel) =>
           Text(
             userModel.name,
             style: Theme.of(context).textTheme.subtitle2.copyWith(fontWeight: 
                 FontWeight.w600),)
           .toList()
  ,
);

【讨论】:

感谢您的回答,但我在做了一些实验后设法解决了问题,我只是将 StreamBuilder() 移到了文件内树的最高点,将 UserService()List 更改为只是 UserModel 并且我调用数据的方式只是使用 snapshot.data.fullName 也由于某种原因直接连接到 UserService() cuz,当我将它从它返回的 BL 连接到 getter 时 b>null, Stream&lt;UserModel&gt; get getCurrentUserData =&gt; userService.getCurrentUser(); 知道如何解决这个问题吗?【参考方案2】:

在返回小部件之前,您应该先检查流是否已完成加载。 获取数据后,最好的方式是使用List&lt;Widget&gt;.generate()进行子创建。

你可以试试这个:

StreamBuilder<List<UserModel>>(
  stream: userProviderData.user,
  builder: (context, snapshot) 
    if (!snapshot.hasData)  // Check the status here
      return Center(child: CircularProgressIndicator());
    
    return GridView(
      gridDelegate:
          const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        crossAxisSpacing: 10,
        mainAxisSpacing: 10,
      ),
      primary: false,
      shrinkWrap: true,
      children: List<Widget>.generate(
        snapshot.data.length, // same length as the data
        (index) => Text(
          snapshot.data[index].fullName, // Use the fullName property of each item
          style: Theme.of(context)
              .textTheme
              .subtitle2
              .copyWith(fontWeight: FontWeight.w600),
        ),
      ),
    );
  ,
);

【讨论】:

感谢您的回答,但我在做了一些实验后设法解决了问题,我只是将 StreamBuilder() 移到了文件内树的最高点,将 UserService()List 更改为只是 UserModel 并且我调用数据的方式只是使用 snapshot.data.fullName 也由于某种原因直接连接到 UserService() cuz,当我将它从它返回的 BL 连接到 getter 时 b>nullStream&lt;UserModel&gt; get getCurrentUserData =&gt; userService.getCurrentUser(); 知道如何解决这个问题吗?

以上是关于如何在颤动中直接将数据从 StreamBuilder 获取到 GridView 中?的主要内容,如果未能解决你的问题,请参考以下文章

我如何从颤动的firebase实时数据库中检索数据

如何在颤动中将数据从复选框存储到 Firebase

如何在颤动中访问此 JSON 数据?

如何在颤动中将数据从一个小部件传递到另一个小部件?

如何在颤动中将列表数据从一个屏幕传递到另一个屏幕(StatefulWidget)

如何在不使用共享首选项的情况下将数据存储为颤动的对象[关闭]