Flutter - 不能将“List<Map<String, Object>>”类型的值分配给“List<Classes>”类型的变量

时间:2021-06-07 17:20:05

标签: arrays flutter dart listview

我是 flutter 的新手,我需要在列表视图中显示我的示例对象数组。但是当我尝试将我的数组设置为我的列表对象时,它会显示类似

的错误 <块引用>

'List>' 类型的值不能分配给 “列表”类型的变量。

我不知道我做错了什么?其实我不知道。这是正确的做法吗?谁能帮我找出我错在哪里?

这是我的 dart 文件:

class Classes {

        late String title;
        late List<CoursesOptions> classes;

        Classes({required this.title, required this.classes});

        factory Classes.fromJson(Map<String, dynamic> parsedJson){

            var list = parsedJson['data'] as List;
            print(list.runtimeType);
            List<CoursesOptions> dataList = list.map((i) => CoursesOptions.fromJson(i)).toList();


            return Classes(
                title: parsedJson['title'],
                classes: dataList
            );
        }
}
  class CoursesOptions {
        late int id;
        late String value;

        CoursesOptions({required this.id, required this.value});

        factory CoursesOptions.fromJson(Map<String, dynamic> parsedJson){
            return CoursesOptions(
                id : parsedJson['id'],
                value : parsedJson['value']
            );
        }
        }
class ClassSelectionPage extends StatefulWidget {
  @override
  _ClassSelectionPageState createState() => _ClassSelectionPageState();
}

class _ClassSelectionPageState extends State<ClassSelectionPage> {

  late List<Classes> futureData;
  @override
  void initState() {
    super.initState();
      var courses = [
      {
        "title": 'Choose your class',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'Grade - 10',
          },
          {
            "id": 2,
            "value": 'O/L',
          },
        ],
      },
     
{
        "title": 'Choose your A/L stream',
        "coursesOptions": [
         {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },     {
        "title": 'Choose your A/L stream',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },
  
        ];
        
    futureData = courses;// this is the point that I'm getting that error and i tried to set this value with  Classes.fromJson(futureData) its says that The argument type 'List<Map<String, Object>>' can't be assigned to the parameter type 'Map<String, dynamic> 
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Container(
              child: Text('ok'),
            ),
            Expanded(
              child: FutureBuilder<List<Classes>>(
                future: futureData,
             builder: (context, snapshot) {
              if (snapshot.hasData) {
                List<Classes>? data = snapshot.data;
                return 
                ListView.builder(
                itemCount: data!.length,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 75,
                    color: Colors.white,
                    child: Center(child: Text(data[index].title),
                  ),);
                }
              );
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }
              // By default show a loading spinner.
              return CircularProgressIndicator();
            },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:1)

问题发生在您的 initState 中:

futureData= courses

futureData 的类型为 List<Classes>,而 course 的类型为 List<Map<String, Object>>,因为您尚未对其数据进行反序列化。

    futureData = courses.map((i) => Classes.fromJson(i)).toList();

使用上述代码段,您的数据已完全反序列化。

现在您遇到的其他问题是,在您的课程变量中,您的课程列表位于 coursesOptions 键中,但在您的模型中,您要查找 data 键,该键至少在本例中不存在测试数据。 也很可能您不会从内存中的列表中反序列化,并且会拥有调用 Future 本身的存储库方法之类的东西,因此 futureValue 的类型应该是 Future。

我做了一个工作示例并更正了下面代码中的错误。

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: Scaffold(
    body: ClassSelectionPage(),
  )));
}

class Classes {
  late String title;
  late List<CoursesOptions> classes;

  Classes({required this.title, required this.classes});

  factory Classes.fromJson(Map<String, dynamic> parsedJson) {
    var list = parsedJson['coursesOptions'] as List;
    print(list.runtimeType);
    List<CoursesOptions> dataList = list.map((i) => CoursesOptions.fromJson(i)).toList();

    return Classes(title: parsedJson['title'], classes: dataList);
  }
}

class CoursesOptions {
  late int id;
  late String value;

  CoursesOptions({required this.id, required this.value});

  factory CoursesOptions.fromJson(Map<String, dynamic> parsedJson) {
    return CoursesOptions(id: parsedJson['id'], value: parsedJson['value']);
  }
}

class ClassSelectionPage extends StatefulWidget {
  @override
  _ClassSelectionPageState createState() => _ClassSelectionPageState();
}

class _ClassSelectionPageState extends State<ClassSelectionPage> {
  late Future<List<Classes>> futureData;

  @override
  void initState() {
    super.initState();
    var courses = [
      {
        "title": 'Choose your class',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'Grade - 10',
          },
          {
            "id": 2,
            "value": 'O/L',
          },
        ],
      },
      {
        "title": 'Choose your A/L stream',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },
      {
        "title": 'Choose your A/L stream',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },
    ];

    futureData = Future.value(courses.map((i) => Classes.fromJson(i)).toList());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Container(
              child: Text('ok'),
            ),
            Expanded(
              child: FutureBuilder<List<Classes>>(
                future: futureData,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    List<Classes>? data = snapshot.data;
                    return ListView.builder(
                        itemCount: data!.length,
                        itemBuilder: (BuildContext context, int index) {
                          return ExpansionTile(
                            title: Text(data[index].title),
                            children: data[index]
                                .classes
                                .map((e) => ListTile(
                                      title: Text(e.value),
                                    ))
                                .toList(),
                          );
                        });
                  } else if (snapshot.hasError) {
                    return Text("${snapshot.error}");
                  }
                  // By default show a loading spinner.
                  return CircularProgressIndicator();
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}