这是我的完整类代码,我正在从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
答案 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();
},