首页 > 解决方案 > 通过使用flutter http请求获取数据并在向下滚动屏幕时加载更多数据

问题描述

我使用flutter http请求从服务器获取数据,并在用户滚动到屏幕底部时加载更多数据。我收到此错误“未处理的异常:'List' 类型不是'Product' 类型的子类型”。请帮忙,我整天都在挣扎,没有成功。

模型.dart 文件

 class Product {
  final int id;
  final String accountName,
      callNumber,
      whatsappNumber,
      businessLocation,
      caption;
  final List<Images> productPhoto;

  Product({
    this.id,
    this.accountName,
    this.callNumber,
    this.whatsappNumber,
    this.businessLocation,
    this.caption,
    this.productPhoto,
  });

  // this is static method
  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      accountName: json['account_name'],
      callNumber: json['call_number'],
      whatsappNumber:
          json['whatsapp_number'] != null ? json['whatsapp_number'] : null,
      businessLocation: json['business_location'],
      caption: json['caption'],
      productPhoto:
          (json['post_photos'] as List).map((i) => Images.fromJson(i)).toList(),
    );
  }
}

class Images {
  final String filename;

  Images({this.filename});

  factory Images.fromJson(Map<String, dynamic> json) {
    return Images(
      filename: json['filename'],
    );
  }
}

explore.dart 文件(我将 models.dart 导入此文件)

    import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:windowshoppi/models/global.dart';
import 'package:windowshoppi/models/product.dart';
import 'package:http/http.dart' as http;


class Explore extends StatefulWidget {
  @override
  _ExploreState createState() => _ExploreState();
}

class _ExploreState extends State<Explore> {
  ScrollController _scrollController = ScrollController();
  List<Product> data;
  String nextUrl;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this.fetchProduct(http.Client(), ALL_PRODUCT_URL);

    _scrollController.addListener(() {
//      print(_scrollController.position.pixels);
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        if (nextUrl != null) {
          this.fetchProduct(http.Client(), nextUrl);
        }

//        print(nextUrl);
      }
    });
  }

  Future<List<Product>> fetchProduct(http.Client client, url) async {
    final response = await client.get(url);

    if (response.statusCode == 200) {
      Map<String, dynamic> mapResponse = json.decode(response.body);

      nextUrl = mapResponse['next'];
      if (mapResponse["count"] != "") {
        final products = mapResponse["results"].cast<Map<String, dynamic>>();
        final listOfProducts = await products.map<Product>((json) {
          return Product.fromJson(json);
        }).toList();
//        return listOfProducts;
        setState(() {
          data.add(listOfProducts);
        });
      } else {
        return [];
      }
    } else {
      throw Exception('failed to load data from internet');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('http get'),
      ),
      body: ListView.builder(
        controller: _scrollController,
        itemCount: data == null ? 0 : data.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: Container(
              height: 200,
              color: Colors.blue,
              child: Text(data[index].caption),
            ),
          );
        },
      ),
    );
  }
}

标签: flutterdart

解决方案


看看这部分代码。

final listOfProducts = await products.map<Product>((json) {
          return Product.fromJson(json);
        }).toList();

.map()方法中,您将其转换为类型 < Product >。所以从你提到的错误来看,“未处理的异常:类型'List'不是产品类型的子类型”

我认为返回的 json 数据包含一个列表,而不是产品字段。我强烈建议您检查一次返回的 json 数据,并仔细检查您是否针对正确的 JSON 树节点。

让我知道这是否解决了问题。


推荐阅读