我正在尝试解析JSON并将其转换为列表视图。
我正在获取响应正文,它也被转换为列表,但是它向将来的构建器发送了null,我得到了这个错误:
/flutter ( 9715): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9715): The following assertion was thrown building FutureBuilder<List<Event>>(dirty, state:
I/flutter ( 9715): _FutureBuilderState<List<Event>>#6efa6):
I/flutter ( 9715): A build function returned null.
I/flutter ( 9715): The offending widget is: FutureBuilder<List<Event>>
I/flutter ( 9715): Build functions must never return null. To return an empty space that causes the building widget to
I/flutter ( 9715): fill available room, return "new Container()". To return an empty space that takes as little room as
I/flutter ( 9715): possible, return "new Container(width: 0.0, height: 0.0)".
I/flutter ( 9715):
I/flutter ( 9715): When the exception was thrown, this was the stack:
代码是:
import 'package:flutter/material.dart';
import 'package:event/models/readEvent.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:event/models/global.dart';
import 'dart:async';
import 'dart:convert';
import 'package:isolate/isolate_runner.dart';
Map<String, dynamic> body = {
"query": {"key": "XOXOXO", "value": "YOY", "specific": ""}
};
Future<List<Event>> fetchPosts(http.Client client) async {
http.post(URL_READEVENT, body: json.encode(body)).then((response) {
print(response.body);
final parsed = json.decode(response.body);
print(response.body);
print(parsed['rs']);
List<Event> event= (parsed["rs"] as List).map<Event>((json) =>
new Event.fromJson(json)).toList();
print(event[0].name);
return event;
});
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _count = 0;
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(
'Events',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.white,
),
body: Container(
child: Center(
child: Column(children: <Widget>[
Row(children: <Widget>[
Container(
padding: EdgeInsets.only(right: 20.0, left: 30.0, top: 16.0),
child: Image.asset('lib/images/dscnew.png',
width: 120.0, height: 120.0, fit: BoxFit.cover),
),
Column(children: <Widget>[
Text(
"Developer Student Clubs",
style: TextStyle(fontWeight: FontWeight.w700),
),
Text(
"VIT Vellore",
textAlign: TextAlign.left,
style: TextStyle(color: Colors.grey, fontWeight:FontWeight.w500),
)
]),
]),
new FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
print(snapshot.hasData);
if (snapshot.data!=null) {
print(snapshot.data);
return ListViewPosts(events: snapshot.data);
} else {
return new CircularProgressIndicator();
}
}
}
),
);
}
class ListViewPosts extends StatelessWidget {
final List<Event> events;
ListViewPosts({Key key, this.events}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 600,
width: 600,
child: Expanded(child:ListView.builder(
itemCount: events.length,
padding: const EdgeInsets.all(15.0),
itemBuilder: (context, position) {
return Column(
children: <Widget>[
Divider(height: 5.0),
ListTile(
title: Text(
'${events[0].name}',
style: TextStyle(
fontSize: 22.0,
color: Colors.deepOrangeAccent,
),
),
subtitle: Text(
'${events[0].status}',
style: new TextStyle(
fontSize: 18.0,
fontStyle: FontStyle.italic,
),
),
leading: Column(
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.blueAccent,
radius: 35.0,
child: Text(
'User ${events[0].clubName}',
style: TextStyle(
fontSize: 22.0,
color: Colors.white,
),
),
)
],
),
onTap: () => _onTapItem(context, events[position]),
),
],
);
}),
)
);
}
void _onTapItem(BuildContext context, Event post) {
// Scaffold
// .of(context)
// .showSnackBar(new SnackBar(content: new Text(post.id.toString() + ' - ' + post.title)));
}
}
答案 0 :(得分:0)
问题在于,当您的FutureBuilder
返回无数据时(首次加载FutureBuilder
时),您不会返回小部件。
尝试像这样更改您的FutureBuilder
:
FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return ListViewPosts(events: snapshot.data);
}
return CircularProgressIndicator();
},
)
答案 1 :(得分:0)
@Jordan Davies 答案绝对正确,但我想为iOS添加一些内容。如果您在 Android和iOS 中都选中了此代码,则应使用以下代码:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; // This is for IOS widgets
class API extends StatefulWidget {
@override
_APIState createState() => _APIState();
}
class _APIState extends State<API> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("POST JSON"),
),
body: Theme.of(context).platform == TargetPlatform.android
? loadAndroidLayout()
: loadIOSLayout(),
);
}
}
Widget loadIOSLayout(){
return FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return ListViewPosts(events: snapshot.data);
}
return CupertinoActivityIndicator(); //IOS loading Widget
}
}
Widget loadAndroidLayout(){
return FutureBuilder(
future: fetchPosts(new http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return ListViewPosts(events: snapshot.data);
}
return CircularProgressIndicator(); //Android loading Widget
}),
}