小部件库捕获异常,IDE 说 getter 在 null 上被调用,即使它不是 null
flutter Exception caught by widgets library, IDE says getter was called on null even it isn't null
我正在用 flutter 编写一个移动应用程序,我得到一个 json 并将其转换为一个对象,如下所示 class:
class UserProfile {
String role;
List<Town> interestingTown;
String sId;
String uid;
Town myTown;
int iV;
UserProfile(
{this.role,
this.interestingTown,
this.sId,
this.uid,
this.myTown,
this.iV});
UserProfile.fromJson(Map<String, dynamic> json) {
role = json['role'];
if (json['interestingTown'] != null) {
interestingTown = new List<Town>();
json['interestingTown'].forEach((v) {
interestingTown.add(new Town.fromJson(v));
});
}
sId = json['_id'];
uid = json['uid'];
myTown = json['myTown'] != null
? new Town.fromJson(json['myTown'])
: null;
iV = json['__v'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['role'] = this.role;
if (this.interestingTown != null) {
data['interestingTown'] =
this.interestingTown.map((v) => v.toJson()).toList();
}
data['_id'] = this.sId;
data['uid'] = this.uid;
if (this.myTown != null) {
data['myTown'] = this.myTown.toJson();
}
data['__v'] = this.iV;
return data;
}
static Resource<myTown> get profile {
return Resource(
url: Constants.HEADLINE_GET_PROFILO,
parse: (response) {
UserProfile profile = UserProfile.fromJson(jsonDecode(response.body));
return profile;
});
}
}
class Town{
bool enabled;
List<String> categories;
String sId;
String nameTown;
int iV;
Town(
{this.enabled,
this.categories,
this.sId,
this.nameTown,
this.iV});
Town.fromJson(Map<String, dynamic> json) {
enabled = json['enabled'];
categories = json['categories'].cast<String>();
sId = json['_id'];
nameTown = json['nameTown'];
iV = json['__v']; }
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['enabled'] = this.enabled;
data['categories'] = this.categories;
data['_id'] = this.sId;
data['nameTown'] = this.nameTown;
data['__v'] = this.iV;
return data; }
}
之后,当我运行下面的class加载一个屏幕时,我得到这个错误(模拟器屏幕红了将近5秒):
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building MyAccountsPage(dirty, state: MyAccountsPageList#4dae7):
The getter 'myTown' was called on null.
Receiver: null
Tried calling: myTown
The relevant error-causing widget was:
MyAccountsPage file:///C:/Users/StudioProjects/my_project/lib/bloc.navigation_bloc/navigation_bloc.dart:36:15
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 MyAccountsPageList.build (package:civic_points/pages/myaccountspage.dart:145:35)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4667:11)
...
====================================================================================================
将近五秒钟后,屏幕加载但加载不正确,因为布尔变量设置不正确。
但是,问题是我可以打印 profile.myTown.nameTown,所以 myTown 不为空。
如果我尝试打印 profile.interestingTown[0].nameTown.
,也会发生同样的错误
之前,我曾尝试使用一些 if 语句设置变量,但我遇到了同样的错误,屏幕一直保持红色,几秒钟后没有加载。
我无法修复错误,所以我 post 了 class 的所有代码,希望有人能帮助我解决问题。
class MyAccountsPage extends StatefulWidget with NavigationStates {
@override
createState() => MyAccountsPageList();
}
class MyAccountsPageList extends State<MyAccountsPage> {
UserProfile profile;
bool boolinterestingTown = true;
bool boolmyTown = true;
int modify;
int myIndex;
bool add = false;
var deleteTown;
@override
void initState() {
super.initState();
_getProfile();
try {
print (profile.myTown.nameTown);
} catch (e) {
boolmyTown = false;
try {
print(profile.interestingTown[0].nameTown);
} catch (e) {
boolinterestingTown = false;
}
}
}
void _getProfile() {
WebserviceToken().load(UserProfile.profile).then((getProfile) => {
setState(() => {this.profile = getProfile}),
});
}
void deleteTownMe() async {
var headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer ${token}'};
var request = http.Request(
'DELETE', Uri.parse('http:..........'));
request.body = '''{
"town": "${deleteTown}"
}''';
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 201) {
print(response.statusCode);
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
}
Widget _buildItemsForTownListView(BuildContext context, int index) {
final town = profile.interestingTown[index].nameTown;
return new Container(
child: Column(
children: <Widget>[
Text(
town,
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: RaisedButton(
child: Text("Modify"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 2;
myIndex = index;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, town),
)));
},
),
),
SizedBox(width: 10),
Flexible(
child: RaisedButton(
child: Text("Delete"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
deleteTown = town;
deleteTownMe();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection()));
},
),
),
],
),
),
SizedBox(height: 20),
],
),
);
}
@override
Widget build(BuildContext context) {
var myTown = profile.myTown.nameTown;
print(profile.myTown.nameTown);
return Scaffold(
appBar: AppBar(
titleSpacing: 50.0,
title: new Text("My profile"),
automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: Container(
margin: const EdgeInsets.fromLTRB(16, 16, 0, 0),
width: double.infinity,
color: Colors.white,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(height: 40),
CircleAvatar(
backgroundImage: NetworkImage(
imageUrl,
),
radius: 48,
backgroundColor: Colors.transparent,
),
SizedBox(height: 48),
Text(
'User',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
name,
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
if (boolmyTown)
Text(
'My town',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
if (boolmyTown)
Text(
myTown,
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
if (boolmyTown)
RaisedButton(
child: Text("Modify"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 1;
myIndex = 0;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, ''),
)));
},
),
if (boolinterestingTown && boolmyTown)
SizedBox(height: 20),
if (boolinterestingTown && boolmyTown)
Text(
'Interesting towns',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
if (boolinterestingTown && boolmyTown)
ListView.builder(
itemCount: profile.interestingTowns.length,
shrinkWrap: true,
itemBuilder: _buildItemsForTownListView,
),
if (boolmyTown && !boolinterestingTown)
SizedBox(height: 20),
if (boolmyTown)
RaisedButton(
child: Text("Add ineresting town"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 2;
myIndex = profile.interestingTown.length;
add = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, ''),
)));
},
),
if (!boolmyTown)
RaisedButton(
child: Text("Add your town"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 1;
myIndex = 0;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, ''),
)));
},
),
],
),
),
),
),
);
}
}
您需要确认变量 profile
是否为空。
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_getProfile();
});
}
@override
Widget build(BuildContext context) {
var myTown = (profile == null) ? null : profile.myTown.nameTown;
return Scaffold(
appBar: AppBar(
titleSpacing: 50.0,
title: new Text("My profile"),
automaticallyImplyLeading: false,
),
body: (profile == null)
? Center(child: CircularProgressIndicator(),)
: SingleChildScrollView(child: Container(),),
);
}
我正在用 flutter 编写一个移动应用程序,我得到一个 json 并将其转换为一个对象,如下所示 class:
class UserProfile {
String role;
List<Town> interestingTown;
String sId;
String uid;
Town myTown;
int iV;
UserProfile(
{this.role,
this.interestingTown,
this.sId,
this.uid,
this.myTown,
this.iV});
UserProfile.fromJson(Map<String, dynamic> json) {
role = json['role'];
if (json['interestingTown'] != null) {
interestingTown = new List<Town>();
json['interestingTown'].forEach((v) {
interestingTown.add(new Town.fromJson(v));
});
}
sId = json['_id'];
uid = json['uid'];
myTown = json['myTown'] != null
? new Town.fromJson(json['myTown'])
: null;
iV = json['__v'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['role'] = this.role;
if (this.interestingTown != null) {
data['interestingTown'] =
this.interestingTown.map((v) => v.toJson()).toList();
}
data['_id'] = this.sId;
data['uid'] = this.uid;
if (this.myTown != null) {
data['myTown'] = this.myTown.toJson();
}
data['__v'] = this.iV;
return data;
}
static Resource<myTown> get profile {
return Resource(
url: Constants.HEADLINE_GET_PROFILO,
parse: (response) {
UserProfile profile = UserProfile.fromJson(jsonDecode(response.body));
return profile;
});
}
}
class Town{
bool enabled;
List<String> categories;
String sId;
String nameTown;
int iV;
Town(
{this.enabled,
this.categories,
this.sId,
this.nameTown,
this.iV});
Town.fromJson(Map<String, dynamic> json) {
enabled = json['enabled'];
categories = json['categories'].cast<String>();
sId = json['_id'];
nameTown = json['nameTown'];
iV = json['__v']; }
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['enabled'] = this.enabled;
data['categories'] = this.categories;
data['_id'] = this.sId;
data['nameTown'] = this.nameTown;
data['__v'] = this.iV;
return data; }
}
之后,当我运行下面的class加载一个屏幕时,我得到这个错误(模拟器屏幕红了将近5秒):
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building MyAccountsPage(dirty, state: MyAccountsPageList#4dae7):
The getter 'myTown' was called on null.
Receiver: null
Tried calling: myTown
The relevant error-causing widget was:
MyAccountsPage file:///C:/Users/StudioProjects/my_project/lib/bloc.navigation_bloc/navigation_bloc.dart:36:15
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 MyAccountsPageList.build (package:civic_points/pages/myaccountspage.dart:145:35)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4667:11)
...
====================================================================================================
将近五秒钟后,屏幕加载但加载不正确,因为布尔变量设置不正确。 但是,问题是我可以打印 profile.myTown.nameTown,所以 myTown 不为空。
如果我尝试打印 profile.interestingTown[0].nameTown.
,也会发生同样的错误之前,我曾尝试使用一些 if 语句设置变量,但我遇到了同样的错误,屏幕一直保持红色,几秒钟后没有加载。
我无法修复错误,所以我 post 了 class 的所有代码,希望有人能帮助我解决问题。
class MyAccountsPage extends StatefulWidget with NavigationStates {
@override
createState() => MyAccountsPageList();
}
class MyAccountsPageList extends State<MyAccountsPage> {
UserProfile profile;
bool boolinterestingTown = true;
bool boolmyTown = true;
int modify;
int myIndex;
bool add = false;
var deleteTown;
@override
void initState() {
super.initState();
_getProfile();
try {
print (profile.myTown.nameTown);
} catch (e) {
boolmyTown = false;
try {
print(profile.interestingTown[0].nameTown);
} catch (e) {
boolinterestingTown = false;
}
}
}
void _getProfile() {
WebserviceToken().load(UserProfile.profile).then((getProfile) => {
setState(() => {this.profile = getProfile}),
});
}
void deleteTownMe() async {
var headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer ${token}'};
var request = http.Request(
'DELETE', Uri.parse('http:..........'));
request.body = '''{
"town": "${deleteTown}"
}''';
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 201) {
print(response.statusCode);
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
}
Widget _buildItemsForTownListView(BuildContext context, int index) {
final town = profile.interestingTown[index].nameTown;
return new Container(
child: Column(
children: <Widget>[
Text(
town,
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: RaisedButton(
child: Text("Modify"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 2;
myIndex = index;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, town),
)));
},
),
),
SizedBox(width: 10),
Flexible(
child: RaisedButton(
child: Text("Delete"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
deleteTown = town;
deleteTownMe();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection()));
},
),
),
],
),
),
SizedBox(height: 20),
],
),
);
}
@override
Widget build(BuildContext context) {
var myTown = profile.myTown.nameTown;
print(profile.myTown.nameTown);
return Scaffold(
appBar: AppBar(
titleSpacing: 50.0,
title: new Text("My profile"),
automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: Container(
margin: const EdgeInsets.fromLTRB(16, 16, 0, 0),
width: double.infinity,
color: Colors.white,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(height: 40),
CircleAvatar(
backgroundImage: NetworkImage(
imageUrl,
),
radius: 48,
backgroundColor: Colors.transparent,
),
SizedBox(height: 48),
Text(
'User',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
name,
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
if (boolmyTown)
Text(
'My town',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
if (boolmyTown)
Text(
myTown,
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
if (boolmyTown)
RaisedButton(
child: Text("Modify"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 1;
myIndex = 0;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, ''),
)));
},
),
if (boolinterestingTown && boolmyTown)
SizedBox(height: 20),
if (boolinterestingTown && boolmyTown)
Text(
'Interesting towns',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
if (boolinterestingTown && boolmyTown)
ListView.builder(
itemCount: profile.interestingTowns.length,
shrinkWrap: true,
itemBuilder: _buildItemsForTownListView,
),
if (boolmyTown && !boolinterestingTown)
SizedBox(height: 20),
if (boolmyTown)
RaisedButton(
child: Text("Add ineresting town"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 2;
myIndex = profile.interestingTown.length;
add = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, ''),
)));
},
),
if (!boolmyTown)
RaisedButton(
child: Text("Add your town"),
textColor: Colors.white,
color: Colors.blueGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
modify = 1;
myIndex = 0;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => citySelection(
profileParameters:
new ProfileParameters(modify, myIndex, add, ''),
)));
},
),
],
),
),
),
),
);
}
}
您需要确认变量 profile
是否为空。
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_getProfile();
});
}
@override
Widget build(BuildContext context) {
var myTown = (profile == null) ? null : profile.myTown.nameTown;
return Scaffold(
appBar: AppBar(
titleSpacing: 50.0,
title: new Text("My profile"),
automaticallyImplyLeading: false,
),
body: (profile == null)
? Center(child: CircularProgressIndicator(),)
: SingleChildScrollView(child: Container(),),
);
}