【问题标题】:Flutter Error: The getter 'iterator' was called on null - I'm using FutureBuilderFlutter 错误:在 null 上调用了 getter 'iterator' - 我正在使用 FutureBuilder
【发布时间】:2021-10-23 23:47:45
【问题描述】:

我正在尝试从 firebase 存储 获取数据/图像,然后使用 FutureBuilder 将它们放入 ImageSlider,我已成功添加到列表中但未能通过进入未来建设者。如果知道我应该怎么做才能使它正确,我会为您的贡献感到高兴。

注意:在未来的构建器之后,我将图像放入提供者,如果您对我可以使用什么而不是提供者有任何建议,以便当用户想要再次查看产品图像时,用户可以查看图像而无需重新加载相同产品图片。

import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:kariakoonline/constants.dart';
import 'package:kariakoonline/models/product_images.dart';
import 'package:kariakoonline/provider/productImages_provider.dart';
import 'package:kariakoonline/provider/product_provider.dart';
import 'package:provider/provider.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;

class ProductImages extends StatefulWidget {
  const ProductImages({
    Key key,
    @required this.product,
    this.sellerId,
    this.productId,
  }) : super(key: key);

  final String product;
  final String sellerId;
  final String productId;

  @override
  _ProductImagesState createState() => _ProductImagesState();
}

class _ProductImagesState extends State<ProductImages> {
  int selectedImage = 0;
  ProductImagesModel imgModel = ProductImagesModel();
  List<ProductImagesModel> listPic = [];

  @override
  void initState() {
    print(
        'id:${widget.product} - productId: ${widget.productId} and Seller: ${widget.sellerId}');
    // listProductImages();
    super.initState();
  }

  Future<void> listProductImages() async {
    List<ProductImagesModel> url = [];
    List<String> images = [];
    String imgUrl;
    firebase_storage.ListResult result = await firebase_storage
        .FirebaseStorage.instance
        .ref('product_images/${widget.sellerId}/${widget.productId}')
        .listAll();
    if (result.items != null) {
      for (firebase_storage.Reference ref in result.items) {
        imgUrl = await firebase_storage.FirebaseStorage.instance
            .ref(ref.fullPath)
            .getDownloadURL();
        if (imgUrl != null) {
          images.add(imgUrl);
        }
      }
      final imgUrlMode = imgModel.copy(id: widget.product, image: images);
      url.add(imgUrlMode);
      print('images: $images');
      print('img url mode: ${imgUrlMode.image}');
      print('url $url');
    }
    return url;
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: listProductImages(),
        builder: (context, snapshot) {
          final imgProvider = Provider.of<ProductImagesProvider>(context);
          final providerImg = imgProvider.productImg;
          imgProvider.setProductImg(snapshot.data);
          print('My Data:');
          print('My Data: ${snapshot.data}');
          print('Provider Model IMG Length: ${imgProvider.productImg.length}');
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Container(
              height: MediaQuery.of(context).size.height / 2,
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  CircularProgressIndicator(),
                ],
              ),
            );
          }
          if (snapshot.hasError) {
            return Container(
              height: MediaQuery.of(context).size.height / 2,
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text('Something is wrong. Try again letter'),
                ],
              ),
            );
          }
          if (snapshot.data == null) {
            return Container(
              height: MediaQuery.of(context).size.height / 2,
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text('Error Occoured. Try again letter'),
                ],
              ),
            );
          }

          return Container(
            child: Column(
              children: <Widget>[
                SizedBox(
                  width: double.infinity,
                  child: AspectRatio(
                    aspectRatio: 1,
                    child: CarouselSlider(
                      options: CarouselOptions(
                        disableCenter: true,
                        onScrolled: (index) {},
                      ),
                      items: <Widget>[
                        ...List.generate(
                          providerImg.length,
                          (index) => CachedNetworkImage(
                            imageUrl: providerImg[index].image[selectedImage],
                            imageBuilder: (context, imageProvider) => Container(
                              decoration: BoxDecoration(
                                image: DecorationImage(
                                  image: imageProvider,
                                  fit: BoxFit.cover,
                                ),
                              ),
                            ),
                            placeholder: (context, url) => Container(
                              width: MediaQuery.of(context).size.width,
                              height: MediaQuery.of(context).size.height,
                              child: Center(
                                child: CircularProgressIndicator(),
                              ),
                            ),
                            errorWidget: (context, url, error) => Stack(
                              children: <Widget>[
                                Container(
                                  width: MediaQuery.of(context).size.width,
                                  height: MediaQuery.of(context).size.height,
                                  child: Image.asset(
                                    'assets/images/placeholder.jpg',
                                    fit: BoxFit.cover,
                                  ),
                                ),
                                Center(
                                  child: CircularProgressIndicator(),
                                )
                              ],
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                ),
                SizedBox(height: 5),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    ...List.generate(
                      providerImg.length,
                      (index) => buildSmallPreview(index),
                    ),
                  ],
                ),
              ],
            ),
          );
        });
  }

  GestureDetector buildSmallPreview(int index) {
    final productData = Provider.of<KariakooProducts>(context, listen: false);
    final specDataById = productData.findProductId(widget.product);
    return GestureDetector(
      onTap: () {
        setState(() {
          selectedImage = index;
        });
      },
      child: Container(
        height: 40,
        width: 40,
        margin: EdgeInsets.symmetric(horizontal: 5),
        decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(
              color: selectedImage == index ? kPrimaryColor : kSecondaryColor),
        ),
        child: Image.network(
          '',
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

【问题讨论】:

  • 我要尝试的第一件事是更改listProductImages 签名以返回Future&lt;List&lt;ProductImagesModel&gt;&gt; 而不是Future&lt;void&gt;
  • 我尝试将 'Future' 和 'Future>' 都放入,但它仍然给我一个错误 (调用了 getter 'iterator'空) @EmilWalser
  • 为您使用Provider的各个地方添加代码。

标签: firebase flutter null firebase-storage flutter-futurebuilder


【解决方案1】:

我找到了解决方案。 从声明开始

 Future<List<ProductImagesModel>> listPic;

然后我从未来函数 listProductImages() 启动 listPic

 @override
 void initState() {
 listPic = listProductImages();
 super.initState();
 }

然后我在 FutureBuilder 中调用 listPic

 @override
 Widget build(BuildContext context) {
 return FutureBuilder(
    future: listPic,
    builder: (context, snapshot) {
  ......
  ......

【讨论】:

    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 2021-08-11
    • 2020-01-08
    • 2021-12-10
    • 2020-03-24
    • 2021-05-25
    • 2023-03-08
    相关资源
    最近更新 更多