Flutter-参数类型'List <List <SubCategoriesFolder >> Function(String)'不能分配给参数类型

时间:2020-06-18 06:39:58

标签: flutter dart

我正在尝试应用函数 compute 从responseJSON获取数据。 为此,我使用quicktype.io生成函数。

这是我到目前为止所做的:

      final subCategoriesFolder = await compute(subCategoriesFolderFromJson, responseJSON);

错误1:

error: The argument type 'List<List<SubCategoriesFolder>> Function(String)' can't be assigned to the parameter type 'FutureOr<List<List<SubCategoriesFolder>>> Function(dynamic)'. (argument_type_not_assignable at lib\src\ui\pages\subcategories.dart:84)

错误2:

error: Couldn't infer type parameter 'Q'.

Tried to infer 'dynamic' for 'Q' which doesn't work:
  Parameter 'callback' declared as     'FutureOr<R> Function(Q)'
                       but argument is 'List<List<SubCategoriesFolder>> Function(String)'.
The type 'dynamic' was inferred from:
  Parameter 'message' declared as     'Q'
                      but argument is 'dynamic'.

Consider passing explicit type argument(s) to the generic.

 (could_not_infer at lib\src\ui\pages\subcategories.dart:84)

来源:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter/foundation.dart';
// import 'dart:isolate';
// import 'package:flutter/foundation.dart';
// import 'catwidget.dart';

// To parse this JSON data, do
//
//     final subCategoriesFolder = subCategoriesFolderFromJson(jsonString);

List<List<SubCategoriesFolder>> subCategoriesFolderFromJson(String str) => List<List<SubCategoriesFolder>>.from(json.decode(str).map((x) => List<SubCategoriesFolder>.from(x.map((x) => SubCategoriesFolder.fromJson(x)))));

String subCategoriesFolderToJson(List<List<SubCategoriesFolder>> data) => json.encode(List<dynamic>.from(data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));

class SubCategoriesFolder {
  SubCategoriesFolder({
    this.children,
    this.title,
  });

  List<Child> children;
  String title;

  factory SubCategoriesFolder.fromJson(Map<String, dynamic> json) => SubCategoriesFolder(
    children: List<Child>.from(json["children"].map((x) => Child.fromJson(x))),
    title: json["title"],
  );

  Map<String, dynamic> toJson() => {
    "children": List<dynamic>.from(children.map((x) => x.toJson())),
    "title": title,
  };
}

class Child {
  Child({
    this.title,
    this.uri,
    this.iconuri,
    this.charset,
  });

  String title;
  String uri;
  String iconuri;
  String charset;

  factory Child.fromJson(Map<String, dynamic> json) => Child(
    title: json["title"],
    uri: json["uri"],
    iconuri: json["iconuri"] == null ? null : json["iconuri"],
    charset: json["charset"] == null ? null : json["charset"],
  );

  Map<String, dynamic> toJson() => {
    "title": title,
    "uri": uri,
    "iconuri": iconuri == null ? null : iconuri,
    "charset": charset == null ? null : charset,
  };
}

class Subfolder extends StatefulWidget {
  @override
  SubFolder createState() => SubFolder();
}

class SubFolder extends State<Subfolder> {

  Future _fetchJSON() async {
    var response = await http.get(
      "http://10.0.2.2:5000/subcategories",
      headers: {"Accept": "application/json"},
    );

    if (response.statusCode == 200) {
      String responseBody = response.body;
      //var responseJSON = json.decode(responseBody);
      var responseJSON = await compute(jsonDecode, responseBody);
      //final subCategoriesFolder = subCategoriesFolderFromJson(responseJSON);
      final subCategoriesFolder = await compute(subCategoriesFolderFromJson, responseJSON);
      print(subCategoriesFolder.runtimeType);//THis is not being set, error here
      print(subCategoriesFolder);
      //     name = responseJSON['name'];
      //     avatar = responseJSON['avatar_url'];
    }
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: CupertinoColors.darkBackgroundGray,
      body: FutureBuilder(
          future: _fetchJSON(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.data == null) {
                return Center(child: Text('No data'));
              } else
                return Container(
                  child: Text(snapshot.data),
                );
              /*return GridView(
                gridDelegate:
                SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
                children: <Widget>[
                  for(var item in snapshot.data ) singleCategoryTemp(item)
                ],
              ); */
            } else if (snapshot.connectionState == snapshot.error) {
              return Center(
                  child: Text('Error: Please try again later')); // error
            } else {
              return Center(child: CircularProgressIndicator()); // loading
            }
          }),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

您可以在下面复制粘贴运行完整代码
您可以使用compute(subCategoriesFolderFromJson, responseBody)
我使用嵌套的ListView来显示数据,请检查完整代码
代码段

Future<List<List<SubCategoriesFolder>>> _fetchJSON() async {
...
if (response.statusCode == 200) {
      String responseBody = response.body;
      return compute(subCategoriesFolderFromJson, responseBody);
    }

工作演示

enter image description here

完整代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

List<List<SubCategoriesFolder>> subCategoriesFolderFromJson(String str) =>
    List<List<SubCategoriesFolder>>.from(json.decode(str).map((x) =>
        List<SubCategoriesFolder>.from(
            x.map((x) => SubCategoriesFolder.fromJson(x)))));

String subCategoriesFolderToJson(List<List<SubCategoriesFolder>> data) =>
    json.encode(List<dynamic>.from(
        data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));

class SubCategoriesFolder {
  SubCategoriesFolder({
    this.children,
    this.title,
  });

  List<Child> children;
  String title;

  factory SubCategoriesFolder.fromJson(Map<String, dynamic> json) =>
      SubCategoriesFolder(
        children:
            List<Child>.from(json["children"].map((x) => Child.fromJson(x))),
        title: json["title"],
      );

  Map<String, dynamic> toJson() => {
        "children": List<dynamic>.from(children.map((x) => x.toJson())),
        "title": title,
      };
}

class Child {
  Child({
    this.title,
    this.uri,
    this.iconuri,
    this.charset,
  });

  String title;
  String uri;
  String iconuri;
  String charset;

  factory Child.fromJson(Map<String, dynamic> json) => Child(
        title: json["title"],
        uri: json["uri"],
        iconuri: json["iconuri"] == null ? null : json["iconuri"],
        charset: json["charset"] == null ? null : json["charset"],
      );

  Map<String, dynamic> toJson() => {
        "title": title,
        "uri": uri,
        "iconuri": iconuri == null ? null : iconuri,
        "charset": charset == null ? null : charset,
      };
}

class Subfolder extends StatefulWidget {
  @override
  SubFolder createState() => SubFolder();
}

class SubFolder extends State<Subfolder> {
  Future<List<List<SubCategoriesFolder>>> _fetchJSON() async {
    /*var response = await http.get(
      "http://10.0.2.2:5000/subcategories",
      headers: {"Accept": "application/json"},
    );*/

    String jsonString = '''
    [[
{
   "title" : "1",
   "children" : [{
       "title":"abc1",
       "uri" : "def1",
       "iconuri" : "123",
       "charset" : "456"
   },
   {
       "title":"abc2",
       "uri" : "def1",
       "iconuri" : "123",
       "charset" : "456"
   }]
},
{
   "title" : "2",
   "children" : [{
       "title":"abc2",
       "uri" : "def2",
       "iconuri" : "789",
       "charset" : "321"
   }]
}
]]
    ''';

    http.Response response = http.Response(jsonString, 200);

    if (response.statusCode == 200) {
      String responseBody = response.body;
      return compute(subCategoriesFolderFromJson, responseBody);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        //backgroundColor: CupertinoColors.darkBackgroundGray,
        body: FutureBuilder(
            future: _fetchJSON(),
            builder: (BuildContext context,
                AsyncSnapshot<List<List<SubCategoriesFolder>>> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('none');
                case ConnectionState.waiting:
                  return Center(child: CircularProgressIndicator());
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return ListView.separated(
                        separatorBuilder: (BuildContext context, int index) {
                          return SizedBox(
                            height: 10,
                          );
                        },
                        shrinkWrap: true,
                        itemCount: snapshot.data.length,
                        itemBuilder: (context, index) {
                          return Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: <Widget>[
                              Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  children: <Widget>[
                                    /*  Expanded(
                                        flex: 1, child: Text(snapshot.data[index].toString())),*/
                                    Expanded(
                                      flex: 2,
                                      child: Container(
                                        height: 50,
                                        child: ListView.separated(
                                            separatorBuilder:
                                                (BuildContext context,
                                                    int index) {
                                              return SizedBox(
                                                width: 10,
                                              );
                                            },
                                            shrinkWrap: true,
                                            scrollDirection: Axis.horizontal,
                                            itemCount:
                                                snapshot.data[index].length,
                                            itemBuilder: (context, index1) {
                                              return Row(
                                                  mainAxisAlignment:
                                                      MainAxisAlignment.center,
                                                  crossAxisAlignment:
                                                      CrossAxisAlignment.center,
                                                  children: <Widget>[
                                                    Container(
                                                      width: 120,
                                                      child: Column(
                                                        children: <Widget>[
                                                          Text(
                                                            snapshot
                                                                .data[index]
                                                                    [index1]
                                                                .title,
                                                            style: TextStyle(
                                                                color:
                                                                    Colors.red),
                                                          ),
                                                          Expanded(
                                                            child: ListView
                                                                .separated(
                                                                    separatorBuilder:
                                                                        (BuildContext
                                                                                context,
                                                                            int
                                                                                index) {
                                                                      return SizedBox(
                                                                        width:
                                                                            2,
                                                                      );
                                                                    },
                                                                    shrinkWrap:
                                                                        true,
                                                                    scrollDirection:
                                                                        Axis
                                                                            .horizontal,
                                                                    itemCount: snapshot
                                                                        .data[
                                                                            index]
                                                                            [
                                                                            index1]
                                                                        .children
                                                                        .length,
                                                                    itemBuilder:
                                                                        (context,
                                                                            index2) {
                                                                      return Row(
                                                                          mainAxisAlignment: MainAxisAlignment
                                                                              .spaceEvenly,
                                                                          children: <
                                                                              Widget>[
                                                                            Text(snapshot.data[index][index1].children[index2].title,
                                                                                style: TextStyle(color: Colors.red)),
                                                                          ]);
                                                                    }),
                                                          ),
                                                        ],
                                                      ),
                                                    )
                                                  ]);
                                            }),
                                      ),
                                    )
                                  ])
                            ],
                          );
                        });
                  }
              }
            }));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Subfolder(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}