如何解决错误“在构建FutureBuilder <list <event >>(dirty,state:时抛出了以下断言:”

时间:2019-02-08 14:07:02

标签: dart flutter

我正在尝试解析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)));
  }
}

2 个答案:

答案 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
  }),
}