我想从URL中获取数据并显示在列表视图中,但是会发生错误(未处理的异常:NoSuchMethodError:方法'findAncestorStateOfType'在null上被调用)。我进行了很多搜索,但是我的问题无法解决,而且我不明白自己在这里犯了什么错误。这是我的代码和错误列表。请向我建议。
import 'package:deviceinstallation/model/order_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'dashboard_screen.dart';
import 'ordercountdetail.dart';
void main()=> runApp(OrderScreen());
class OrderScreen extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyOrderPage(title: 'Flutter Demo Home Page'),
);
}
}
class MyOrderPage extends StatefulWidget{
@override
MyOrderPage({Key key, this.title}) : super(key: key);
final String title;
@override
OrderScreenState createState() => OrderScreenState();
}
class OrderScreenState extends State<MyOrderPage> {
Icon cusIcon =Icon(Icons.search);
Widget cusSearchBar= Text("Order");
bool _isLoading=false;
final String sUrl= "https://fasttracksoft.us/api_v2/device_installation/";
List<OrderModel> orderList;
BuildContext context;
Future<List<OrderModel>> _orderList()async{
setState(() {
_isLoading=true;
});
final prefs= await SharedPreferences.getInstance();
var params = "myaccount.php?id="+prefs.getString("id")+"&type=" +"order";
print(params);
try{
final res =await http.get(sUrl+params);
//print(res.body);
if(res.statusCode==200){
orderList= orderModelFromJson(res.body);
if(orderList!=null){
setState(() {
_isLoading=false;
});
}
}
}catch(e){
}
return orderList;
}
@override
void initState() {
// TODO: implement initState
super.initState();
setState(()
{
this._orderList();
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
setState(() => this.context = context);
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
},
),
title: cusSearchBar,
actions: <Widget>[
IconButton(
onPressed: () {
setState(() {
if(this.cusIcon.icon==Icons.search){
this.cusIcon=Icon(Icons.cancel);
this.cusSearchBar=TextField(
textInputAction: TextInputAction.go,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Search here",
),
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
),
);
}else{
this.cusIcon =Icon(Icons.search);
this.cusSearchBar= Text("AppBar");
}
});
},
icon: cusIcon,
),
],
),
body: ListView.builder(
itemCount: null== orderList ? 0 : orderList.length ,
itemBuilder: (context, index) {
OrderModel orderModel= orderList[index];
return Padding(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 5.0, right: 5.0),
child: GestureDetector(
onTap: ()=> Navigator.push(context, new MaterialPageRoute(builder: (context)=> new OrderCountDetails())),
child: Card(
elevation: 10,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery
.of(context)
.size
.width * 15.5,
color: Colors.green,
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0, left: 15.0, right: 0.0),
child: Text("NEW ORDER",
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 10.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text('Customer Name :'+ orderModel.customerName.toString(),
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text('Type :'+orderModel.type.toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text('Total Devices :',
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text('Address :'+orderModel.address.toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 10.0, left: 10.0, right: 10.0),
child: Text('New Orders Count :'+orderModel.neworder,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
],
),
),
),
),
);
},
),
);
}
}
Performing hot restart...
Syncing files to device Mi A2...
Malformed message
Restarted application in 2,060ms.
I/flutter ( 9906): Started the splash screen
I/flutter ( 9906): Finished
E/flutter ( 9906): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'findAncestorStateOfType' was called on null.
E/flutter ( 9906): Receiver: null
E/flutter ( 9906): Tried calling: findAncestorStateOfType<NavigatorState>()
E/flutter ( 9906): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter ( 9906): #1 Navigator.of (package:flutter/src/widgets/navigator.dart:1492:19)
E/flutter ( 9906): #2 Navigator.pushNamed (package:flutter/src/widgets/navigator.dart:917:22)
E/flutter ( 9906): #3 _MyHomePageState.finished (package:deviceinstallation/splash_screen.dart:59:15)
E/flutter ( 9906): #4 _rootRun (dart:async/zone.dart:1122:38)
E/flutter ( 9906): #5 _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter ( 9906): #6 _CustomZone.runGuarded (dart:async/zone.dart:925:7)
E/flutter ( 9906): #7 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23)
E/flutter ( 9906): #8 _rootRun (dart:async/zone.dart:1126:13)
E/flutter ( 9906): #9 _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter ( 9906): #10 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:949:23)
E/flutter ( 9906): #11 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:23:15)
E/flutter ( 9906): #12 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:384:19)
E/flutter ( 9906): #13 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:418:5)
E/flutter ( 9906): #14 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
E/flutter ( 9906):
E/flutter ( 9906): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Invalid argument(s)
答案 0 :(得分:1)
您可以在下面复制粘贴运行完整代码
我用3秒的延迟来模拟网络通话
步骤1:从setState(() => this.context = context);
中删除build
步骤2:使用addPostFrameCallback
呼叫_orderList()
中的initState
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_orderList();
});
}
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
List<OrderModel> orderModelFromJson(String str) =>
List<OrderModel>.from(json.decode(str).map((x) => OrderModel.fromJson(x)));
String orderModelToJson(List<OrderModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class OrderModel {
OrderModel({
this.neworder,
this.address,
this.type,
this.customerName,
});
String neworder;
String address;
String type;
String customerName;
factory OrderModel.fromJson(Map<String, dynamic> json) => OrderModel(
neworder: json["neworder"],
address: json["address"],
type: json["type"],
customerName: json["customerName"],
);
Map<String, dynamic> toJson() => {
"neworder": neworder,
"address": address,
"type": type,
"customerName": customerName,
};
}
void main() => runApp(OrderScreen());
class OrderScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyOrderPage(title: 'Flutter Demo Home Page'),
);
}
}
class MyOrderPage extends StatefulWidget {
@override
MyOrderPage({Key key, this.title}) : super(key: key);
final String title;
@override
OrderScreenState createState() => OrderScreenState();
}
class OrderScreenState extends State<MyOrderPage> {
Icon cusIcon = Icon(Icons.search);
Widget cusSearchBar = Text("Order");
bool _isLoading = false;
final String sUrl = "https://fasttracksoft.us/api_v2/device_installation/";
List<OrderModel> orderList;
BuildContext context;
Future<List<OrderModel>> _orderList() async {
setState(() {
_isLoading = true;
});
/*final prefs= await SharedPreferences.getInstance();
var params = "myaccount.php?id="+prefs.getString("id")+"&type=" +"order";
print(params);*/
try {
//final res =await http.get(sUrl+params);
//print(res.body);
String jsonString = '''
[
{
"neworder" : "order 1",
"address" : "abc",
"type" : "def",
"customerName": "aaa"
},
{
"neworder" : "order 2",
"address" : "abc1",
"type" : "def1",
"customerName": "aaa1"
}
]
''';
await Future.delayed(Duration(seconds: 3), () {});
final res = http.Response(jsonString, 200);
if (res.statusCode == 200) {
orderList = orderModelFromJson(res.body);
if (orderList != null) {
setState(() {
_isLoading = false;
});
}
}
} catch (e) {}
return orderList;
}
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_orderList();
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
//setState(() => this.context = context);
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
/*Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);*/
},
),
title: cusSearchBar,
actions: <Widget>[
IconButton(
onPressed: () {
setState(() {
if (this.cusIcon.icon == Icons.search) {
this.cusIcon = Icon(Icons.cancel);
this.cusSearchBar = TextField(
textInputAction: TextInputAction.go,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Search here",
),
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
),
);
} else {
this.cusIcon = Icon(Icons.search);
this.cusSearchBar = Text("AppBar");
}
});
},
icon: cusIcon,
),
],
),
body: ListView.builder(
itemCount: null == orderList ? 0 : orderList.length,
itemBuilder: (context, index) {
OrderModel orderModel = orderList[index];
return Padding(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 5.0, right: 5.0),
child: GestureDetector(
//onTap: ()=> Navigator.push(context, new MaterialPageRoute(builder: (context)=> new OrderCountDetails())),
child: Card(
elevation: 10,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width * 15.5,
color: Colors.green,
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0, left: 15.0, right: 0.0),
child: Text(
"NEW ORDER",
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 10.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text(
'Customer Name :' +
orderModel.customerName.toString(),
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text(
'Type :' + orderModel.type.toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text(
'Total Devices :',
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 0.0, left: 10.0, right: 10.0),
child: Text(
'Address :' + orderModel.address.toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
new Container(
padding: const EdgeInsets.only(
top: 0.0, bottom: 10.0, left: 10.0, right: 10.0),
child: Text(
'New Orders Count :' + orderModel.neworder,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
),
),
],
),
),
),
),
);
},
),
);
}
}
答案 1 :(得分:0)
不要在build内部将setState()作为第一行调用-
@override
Widget build(BuildContext context) {
// TODO: implement build
setState(() => this.context = context);