如何处理此抖动异常(未处理的异常:NoSuchMethodError:在空值上调用了方法'findAncestorStateOfType')

时间:2020-07-14 16:14:50

标签: flutter

我想从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)

2 个答案:

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

工作演示

enter image description here

完整代码

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);