吸气剂长度在null上被调用

时间:2019-11-25 12:25:13

标签: flutter

这是我的完整类代码,我正在从mySQL检索数据并将其显示在屏幕上,但是我一直在不断收到此错误, getter'length'被调用为null。 接收者:null 尝试致电:长度,我找不到我做错了什么,做错了什么,一切都看起来不错,做错了什么,请帮忙!

import 'dart:async';
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' show get;
    import 'dart:convert';

class Spacecraft {
  final String id;
  final String name , experience , img_url , rating, contact, description;

  Spacecraft({
    this.id,
    this.name,
    this.experience,
    this.img_url,
    this.rating,
    this.contact,
    this.description
  });

  factory Spacecraft.fromJson(Map<String, dynamic> jsonData) {
    return Spacecraft(
      id: jsonData['id'],
      name: jsonData['name'],
      experience: jsonData['experience'],
      img_url: "http://sha-way.freeweb.pk/images/"+jsonData['img_url'],
      rating: jsonData['rating'],
      contact: jsonData['contact'],
      description: jsonData['description'],
    );
  }
}

class CustomListView extends StatelessWidget {
  final List<Spacecraft> spacecrafts;
  CustomListView([this.spacecrafts]);

  Widget build(context) {
    return ListView.builder(
      itemCount: spacecrafts.length,
      itemBuilder: (context, int currentIndex) {
        return createViewItem(spacecrafts[currentIndex], context);
      },
    );
  }

  Widget createViewItem(Spacecraft spacecraft, BuildContext context) {
    return new ListTile(
        title: new Card(
          elevation: 5.0,
          child: new Container(
            decoration: BoxDecoration(border: Border.all(color: Colors.orange)),
            padding: EdgeInsets.all(20.0),
            margin: EdgeInsets.all(20.0),
            child: Column(
              children: <Widget>[
                Padding(
                  child: Image.network(spacecraft.img_url),
                  padding: EdgeInsets.only(bottom: 8.0),
                ),
                Row(children: <Widget>[
                  Padding(
                      child: Text(
                        spacecraft.name,
                        style: new TextStyle(fontWeight: FontWeight.bold),
                        textAlign: TextAlign.right,
                      ),
                      padding: EdgeInsets.all(1.0)),
                  Text(" | "),
                  Padding(
                      child: Text(
                        spacecraft.experience,
                        style: new TextStyle(fontStyle: FontStyle.italic),
                        textAlign: TextAlign.right,
                      ),
                      padding: EdgeInsets.all(1.0)),
                ]),
              ],
            ),
          ),
        ),
        onTap: () {
          //We start by creating a Page Route.
          //A MaterialPageRoute is a modal route that replaces the entire
          //screen with a platform-adaptive transition.
          var route = new MaterialPageRoute(
            builder: (BuildContext context) =>
            new SecondScreen(value: spacecraft),
          );
          //A Navigator is a widget that manages a set of child widgets with
          //stack discipline.It allows us navigate pages.
          Navigator.of(context).push(route);
        });
  }
}

//Future is n object representing a delayed computation.
Future<List<Spacecraft>> downloadJSON() async {
  final jsonEndpoint =
      "http://sha-way.freeweb.pk";

  final response = await get(jsonEndpoint);

  if (response.statusCode == 200) {
    List spacecrafts = json.decode(response.body);
    return spacecrafts
        .map((spacecraft) => new Spacecraft.fromJson(spacecraft))
        .toList();
  } else
    throw Exception('We were not able to successfully download the json data.');
}

class SecondScreen extends StatefulWidget {
  final Spacecraft value;

  SecondScreen({Key key, this.value}) : super(key: key);

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

class _SecondScreenState extends State<SecondScreen> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text('Detail Page')),
      body: new Container(
        child: new Center(
          child: Column(
            children: <Widget>[
              Padding(
                child: new Text(
                  'BACHAY LOG KI DETAILS',
                  style: new TextStyle(fontWeight: FontWeight.bold,fontSize: 20.0),
                  textAlign: TextAlign.center,
                ),
                padding: EdgeInsets.only(bottom: 20.0),
              ),
              Padding(
                //`widget` is the current configuration. A State object's configuration
                //is the corresponding StatefulWidget instance.
                child: Image.network('${widget.value.img_url}'),
                padding: EdgeInsets.all(12.0),
              ),
              Padding(
                child: new Text(
                  'NAME : ${widget.value.name}',
                  style: new TextStyle(fontWeight: FontWeight.bold),
                  textAlign: TextAlign.left,
                ),
                padding: EdgeInsets.all(20.0),
              ),
              Padding(
                child: new Text(
                  'EXPERIENCE : ${widget.value.experience}',
                  style: new TextStyle(fontWeight: FontWeight.bold),
                  textAlign: TextAlign.left,
                ),
                padding: EdgeInsets.all(20.0),
              )
            ],   ),
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.deepOrange,
      ),
      home: new Scaffold(
        appBar: new AppBar(title: const Text('MySQL Images Text')),
        body: new Center(
          //FutureBuilder is a widget that builds itself based on the latest snapshot
          // of interaction with a Future.
          child: new FutureBuilder<List<Spacecraft>>(
            future: downloadJSON(),
            //we pass a BuildContext and an AsyncSnapshot object which is an
            //Immutable representation of the most recent interaction with
            //an asynchronous computation.
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                List<Spacecraft> spacecrafts = snapshot.data;
                return new CustomListView(spacecrafts);
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              //return  a circular progress indicator.
              return new CircularProgressIndicator();
            },
          ),

        ),
      ),
    );
  }
}

这是我遇到的错误

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building CustomListView(dirty):
The getter 'length' was called on null.
Receiver: null
Tried calling: length

2 个答案:

答案 0 :(得分:-1)

您在犯一个小错误。

在这里,您将航天器定义为可选项目:

CustomListView([this.spacecrafts]);

但是当您在此处致电时

 List<Spacecraft> spacecrafts = snapshot.data;
 return new CustomListView(spacecrafts);

您像调用它一样是强制性参数,因此实际上并没有传递任何参数,因为没有为正确的变量赋值。

如果要保留该可选内容,则应按以下方式调用CustomListView:

List<Spacecraft> spacecrafts = snapshot.data;
 return new CustomListView(spacecrafts:spacecrafts);

否则,如果没有可能省略列表的情况,请更改以下内容:

CustomListView([this.spacecrafts]);

对此:

CustomListView(this.spacecrafts);

答案 1 :(得分:-1)

这是错误: itemCount:spacecrafts.length,

为什么? 因为它使用null初始化

  final List<Spacecraft> spacecrafts; **<-- this is null(empty) - no length**
  CustomListView([this.spacecrafts]);

  Widget build(context) {
    return ListView.builder(
      itemCount: spacecrafts.length, **<-- spacecrafts is null, has no data**
      itemBuilder: (context, int currentIndex) {
        return createViewItem(spacecrafts[currentIndex], context);
      },
    );
  }

您将在不同的类中更新新的航天器列表

 builder: (context, snapshot) {
              if (snapshot.hasData) {
                List<Spacecraft> spacecrafts = snapshot.data; **<-- new spacecrafts initialization in a dofferent Class** 
                return new CustomListView(spacecrafts);
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              //return  a circular progress indicator.
              return new CircularProgressIndicator();
            },