0

我正在开发一个简单的 ListView 应用程序,该应用程序从 Internet 填充并使用 Provider 存储在数据库中。但是 ListView 没有被填充。在项目吸气剂上它变得空了。但是在我改变了消费者之后。

现在我收到一个错误,getter 项目被调用为 null。

堆栈溢出

 ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (15505): The following NoSuchMethodError was thrown building FutureBuilder<void>(dirty, state:
I/flutter (15505): _FutureBuilderState<void>#7948f):
I/flutter (15505): The getter 'items' was called on null.
I/flutter (15505): Receiver: null
I/flutter (15505): Tried calling: items
I/flutter (15505): 
I/flutter (15505): The relevant error-causing widget was:
I/flutter (15505):   FutureBuilder<void>
I/flutter (15505):   file:///C:/Users/Admin/lib/main.dart:27:13
I/flutter (15505): 
I/flutter (15505): When the exception was thrown, this was the stack:
I/flutter (15505): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter (15505): #1      _MyAppState.build.<anonymous closure> (package:list_cart_interview/main.dart:37:33)
I/flutter (15505): #2      _FutureBuilderState.build (package:flutter/src/widgets/async.dart:751:55)
I/flutter (15505): #3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4744:28)
I/flutter (15505): #4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
I/flutter (15505): #5      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart

主要.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/product.dart';
import 'provider/product_provider.dart';
import 'widgets/list_item.dart';

void main() {
  runApp(
    MaterialApp(
      home: ChangeNotifierProvider.value(
        value: ProductsProvider(),
        child: MyApp(),
      ),
    ),
  );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
          future: Provider.of<ProductsProvider>(context, listen: false)
              .getProducts(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            }

            print(snapshot.data.items.length);
            if (snapshot.connectionState == ConnectionState.done) {
              return Consumer<ProductsProvider>(
                child: Center(
                  child: CircularProgressIndicator(),
                ),
                builder: (context, productProvider, child) =>
                    productProvider.items.length <= 0
                        ? child
                        : ListView.builder(
                            itemCount: productProvider.items.length,
                            itemBuilder: (context, index) {
                              return ListItem();
                            },
                          ),
              );
            }
            return Container();
          }),
    );
  }
}

product_provider.dart

import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:list_cart_interview/hellper/sqlite_helper.dart';
import 'dart:convert';
import '../models/product.dart';

class ProductsProvider with ChangeNotifier {
  List<Products> _items = [];

  List get items {
    return [..._items];
  }

  Future<void> getDataFromInternet() async {
    try {
      Response response = await get('https://jsonkeeper.com/b/YIDG');

      Map<String, dynamic> extractedData = jsonDecode(response.body);

      final length = extractedData['data']['products'].length;
      print(length);

      for (int i = 0; i < length; i++) {
        DatabaseHelper.insert({
          'id': extractedData['data']['products'][i]['prodCode'],
          'prodName': extractedData['data']['products'][i]['prodName'],
          'prodImage': extractedData['data']['products'][i]['prodImage'],
          'prodPrice': extractedData['data']['products'][i]['prodPrice'],
          'cartQuantity': 0,
        });
      }
    } catch (error) {
      throw (error);
    }
  }

  Future getProducts() async {
    await getDataFromInternet();
    final productsList = await DatabaseHelper.getProductsFromDB();
    print(" hbj ${productsList}");

    _items = productsList
        .map(
          (item) => Products(
            item['id'],
            item['prodName'],
            item['prodImage'],
            item['prodPrice'],
            item['cartQuantity'],
          ),
        )
        .toList();
    print('-items: ${_items}');
    notifyListeners();
  }
}

我认为 getProducts() 方法在上面的代码中产生了问题。现在得到一个唯一的孩子就是这个小部件。请帮忙

4

2 回答 2

1

snapshot.data在访问项目之前,您需要检查您是否有数据。

if(snapshot.hasData) {
  // return your ListView
}

于 2021-01-07T15:08:20.687 回答
0

尽量避免将 Providers 与 FutureBuilder 一起使用。
FutureBuilders 依赖于 Future,即最终返回一个值。
在您的情况下,提供者调用notifyListeners();并结束。
没有任何东西被退回。
如果您希望使用项目列表,请使用侦听更改的消费者。

如果使用 FutureBuilder 是绝对必要的,让你的getProducts()方法返回一些FutureBuilder可以使用的值。
例如,您可以根据是否获取数据返回一个布尔值。

于 2021-01-07T18:32:40.130 回答