我试图将Google表格数据导出为JSON,并借助在媒介article中解释的示例,在flutter应用程序中显示表格,但这会引发错误。
[ERROR:flutter/runtime/dart_isolate.cc(717)] Isolate (407760049) 'main.dart:_spawn()' exited with an error
E/flutter (13106): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (13106): type 'int' is not a subtype of type 'String' in type cast
E/flutter (13106): #0 new Result.fromJson (package:supershopping_flutter_app/main.dart:39:28)
E/flutter (13106): #1 parseResults.<anonymous closure> (package:supershopping_flutter_app/main.dart:19:46)
E/flutter (13106): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:414:29)
E/flutter (13106): #3 ListIterable.toList (dart:_internal/iterable.dart:219:19)
E/flutter (13106): #4 parseResults (package:supershopping_flutter_app/main.dart:19:62)
E/flutter (13106): #5 _IsolateConfiguration.apply (package:flutter/src/foundation/isolates.dart:88:16)
E/flutter (13106): #6 _spawn.<anonymous closure> (package:flutter/src/foundation/isolates.dart:96:30)
E/flutter (13106): #7 Timeline.timeSync (dart:developer/timeline.dart:168:22)
E/flutter (13106): #8 _spawn (package:flutter/src/foundation/isolates.dart:93:12)
E/flutter (13106): #9 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:292:17)
E/flutter (13106): #10 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
I/flutter (13106): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (13106): The following NoSuchMethodError was thrown building NotificationListener<KeepAliveNotification>:
I/flutter (13106): The getter 'length' was called on null.
I/flutter (13106): Receiver: null
I/flutter (13106): Tried calling: length
data.json
[
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
},
{
"sex": "Both sexes",
"region": "State",
"year": 2016,
"statistic": "Population 2011 (Number)",
"value": 4588252
}
]
main.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Result>> fetchResults(http.Client client) async {
final response = await client.get('https://imtusharrai.github.io/app-data/data.json');
// Use the compute function to run parseResults in a separate isolate
return compute(parseResults, response.body);
}
// A function that will convert a response body into a List<Result>
List<Result> parseResults(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Result>((json) => Result.fromJson(json)).toList();
}
class Result {
final String sex;
final String region;
final int year;
final String statistic;
final String value;
Result({this.sex, this.region, this.year, this.statistic, this.value});
bool selected = false;
factory Result.fromJson(Map<String, dynamic> json) {
return Result(
sex: json['sex'] as String,
region: json['region'] as String,
year: json['year'] as int,
statistic: json['statistic'] as String,
value: json['value'] as String,
);
}
}
class ResultsDataSource extends DataTableSource {
final List<Result> _results;
ResultsDataSource(this._results);
void _sort<T>(Comparable<T> getField(Result d), bool ascending) {
_results.sort((Result a, Result b) {
if (!ascending) {
final Result c = a;
a = b;
b = c;
}
final Comparable<T> aValue = getField(a);
final Comparable<T> bValue = getField(b);
return Comparable.compare(aValue, bValue);
});
notifyListeners();
}
int _selectedCount = 0;
@override
DataRow getRow(int index) {
assert(index >= 0);
if (index >= _results.length) return null;
final Result result = _results[index];
return DataRow.byIndex(
index: index,
selected: result.selected,
onSelectChanged: (bool value) {
if (result.selected != value) {
_selectedCount += value ? 1 : -1;
assert(_selectedCount >= 0);
result.selected = value;
notifyListeners();
}
},
cells: <DataCell>[
DataCell(Text('${result.sex}')),
DataCell(Text('${result.region}')),
DataCell(Text('${result.year}')),
DataCell(Text('${result.statistic}')),
DataCell(Text('${result.value}')),
]);
}
@override
int get rowCount => _results.length;
@override
bool get isRowCountApproximate => false;
@override
int get selectedRowCount => _selectedCount;
void _selectAll(bool checked) {
for (Result result in _results) result.selected = checked;
_selectedCount = checked ? _results.length : 0;
notifyListeners();
}
}
class DataTableDemo extends StatefulWidget {
ResultsDataSource _resultsDataSource = ResultsDataSource([]);
bool isLoaded = false;
@override
_DataTableDemoState createState() => _DataTableDemoState();
}
class _DataTableDemoState extends State<DataTableDemo> {
ResultsDataSource _resultsDataSource = ResultsDataSource([]);
bool isLoaded = false;
int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
int _sortColumnIndex;
bool _sortAscending = true;
void _sort<T>(
Comparable<T> getField(Result d), int columnIndex, bool ascending) {
_resultsDataSource._sort<T>(getField, ascending);
setState(() {
_sortColumnIndex = columnIndex;
_sortAscending = ascending;
});
}
Future<void> getData() async {
final results = await fetchResults(http.Client());
if (!isLoaded) {
setState(() {
_resultsDataSource = ResultsDataSource(results);
isLoaded = true;
});
}
}
@override
Widget build(BuildContext context) {
getData();
return Scaffold(
appBar: AppBar(
title: const Text('Data tables'),
),
body: ListView(padding: const EdgeInsets.all(20.0), children: <Widget>[
PaginatedDataTable(
header: const Text('Census Data'),
rowsPerPage: _rowsPerPage,
onRowsPerPageChanged: (int value) {
setState(() {
_rowsPerPage = value;
});
},
sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,
onSelectAll: _resultsDataSource._selectAll,
columns: <DataColumn>[
DataColumn(
label: const Text('Sex'),
onSort: (int columnIndex, bool ascending) => _sort<String>(
(Result d) => d.sex, columnIndex, ascending)),
DataColumn(
label: const Text('Region'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort<String>(
(Result d) => d.region, columnIndex, ascending)),
DataColumn(
label: const Text('Year'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort<num>(
(Result d) => d.year, columnIndex, ascending)),
DataColumn(
label: const Text('Data'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort<String>(
(Result d) => d.statistic, columnIndex, ascending)),
DataColumn(
label: const Text('Value'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort<String>(
(Result d) => d.value, columnIndex, ascending)),
],
source: _resultsDataSource)
]));
}
}
void main() {
runApp(MaterialApp(home: DataTableDemo()));
}
答案 0 :(得分:0)
类型'int'不是类型转换类型'字符串'的子类型
此行value: json['value'] as String
中的问题没有意义,因为值DataType为int
应该是这样
value: json['value']