Flutter/Dart 当我尝试从互联网导入数据时,它没有加载

Flutter/Dart When I try to import data from internet, it doesn't load it

我是 Flutter/Dart 的新手... 我正在尝试使用 json.decode 从 http 导入数据,但它始终为空,显示 'loading...'。我正在使用 FutureBuilder!我已经搜索了解决方案,但没有找到。我正在使用 https://jsonplaceholder.typicode.com/posts 来模拟它。 希望有人能帮忙! :))

class Page1 extends StatelessWidget {

  //********************************** GOOGLE MAPS *****************************************

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MapView(),
    );
  }
}

class MapView extends StatefulWidget {
  @override
  _MapViewState createState() => _MapViewState();
}

class _MapViewState extends State<MapView> {

  CameraPosition _initialLocation = CameraPosition(target: LatLng(0.0, 0.0));
  GoogleMapController mapController;

  final Geolocator _geolocator = Geolocator();
  Position _currentPosition;

  @override
  void initState() {
    super.initState();
    _getCurrentLocation();
  }
  _getCurrentLocation() async {
    await _geolocator
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high)
        .then((Position position) async {
      setState(() {
        // Store the position in the variable
        _currentPosition = position;

        print('CURRENT POS: $_currentPosition');

        // For moving the camera to current location
        mapController.animateCamera(
          CameraUpdate.newCameraPosition(
            CameraPosition(
              target: LatLng(position.latitude, position.longitude),
              zoom: 13.0,
            ),
          ),
        );
      });
    }).catchError((e) {
      print(e);
    });
  }

  @override
  Widget build(BuildContext context) {

    // Determining the screen width & height
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;


    //********************************** GOOGLE MAPS SCREEN **********************************

    return Container(
      height: height,
      width: width,
      child: Scaffold(
          body: Stack(
            children: <Widget>[

              GoogleMap(
                initialCameraPosition: _initialLocation,
                myLocationEnabled: true,
                myLocationButtonEnabled: false,
                mapType: MapType.normal,
                zoomGesturesEnabled: true,
                zoomControlsEnabled: false,
                onMapCreated: (GoogleMapController controller) {
                  mapController = controller;
                },
              ),
              SafeArea(child:
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Container(
                      child: Material(
                        shape:StadiumBorder(),
                        color: Color(0xffeb5c68),
                        child: InkWell(
                          splashColor: Color(0xffda1b2b) ,
                          child: SizedBox(
                            width: 130,
                            height: 47,
                            child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Text("MY ORDERS", style: TextStyle(fontWeight: FontWeight.bold)),
                                  SizedBox(width: 3),
                                  Icon(Icons.arrow_forward),
                            ]
                          ),
                          ),
                          onTap: () {
                            Navigator.push(
                              context,
                              MaterialPageRoute(builder: (context) => Page2()),
                            );
                          },
                      ),
                    ),
                  )
                ]
              ),
              ),

            SafeArea(child:
             Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
              ClipOval(
                child: Material(
                  color: Color(0xffeb5c68),
                  child: InkWell(
                    splashColor: Color(0xffda1b2b),
                    child: SizedBox(
                      width: 56,
                      height: 56,
                      child: Icon(Icons.my_location, size: 28,),
                    ),
                    onTap: () {
                      mapController.animateCamera(
                        CameraUpdate.newCameraPosition(
                          CameraPosition(
                            target: LatLng(
                              _currentPosition.latitude,
                              _currentPosition.longitude,
                            ),
                            zoom: 13.0,
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ),
              ]
            ),
            ),

              //********************************** ORDERS **********************************

              Container(
                padding: EdgeInsets.only(top: 550, bottom: 50),
                child: FutureBuilder(
                    future: getTechies(),
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    print(snapshot.data);
                    if (snapshot.data == null) {
                      return Container(
                          child: Center(
                              child: Text("Loading...", style: TextStyle(fontSize: 30),)
                          )
                      );
                    } else {
                      return ListView.builder(
                        itemCount: snapshot.data.length,
                          itemBuilder: (BuildContext context, int index){
                            return ListTile(
                              title: Text(snapshot.data[index].userId),
                              subtitle: Text(snapshot.data[index].id),
                            );
                          }
                      );
                    }
                  }

              )
              ),
            ],
          )
      ),
    );
  }

  Future<List<Technician>> getTechies() async {
    var data = await http.get("https://jsonplaceholder.typicode.com/posts");
    var jsonData = json.decode(data.body);

    List<Technician> techies = [];

    for (var u in jsonData) {
      Technician myTechy = Technician(u["userId"], u["id"], u["tittle"], u["body"]);

      techies.add(myTechy);
    }


    return techies;
  }
}

    //********************************** PAGE 2 **********************************
class Page2 extends StatelessWidget {


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("YOUR ORDERS"),
        backgroundColor: Colors.green
      ),
    );
  }
}

技术员class:

class Technician {
  final String userId;
  final String id;
  final String tittle;
  final String body;
 
  Technician(this.userId, this.id, this.tittle, this.body);
}

提取数据时出错

使用try catch查看错误。你会看到这个错误

type 'int' is not a subtype of type 'String'

修复方法如下

Future<List<Technician>> getTechies() async {
    try {
      var data = await http.get("https://jsonplaceholder.typicode.com/posts");
      var jsonData = json.decode(data.body);

      List<Technician> techies = [];

      for (var u in jsonData) {
        Technician myTechy = Technician(u["userId"], u["id"], u["tittle"], u["body"]);

        techies.add(myTechy);
      }

      return techies;
    } catch (e) {
      print(e);
    }
  }

iduserIdint 。所以把你的 Technician class 改成这个

class Technician {
  final int userId;
  final int id;
  final String tittle;
  final String body;

  Technician(this.userId, this.id, this.tittle, this.body);
}

如果您不想更改 Technician class。在循环中执行此操作

for (var u in jsonData) {
        Technician myTechy = Technician(u["userId"].toString(), u["id"].toString(), u["tittle"], u["body"]);

        techies.add(myTechy);
      }

然后把你的list.builder改成这个

return ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (BuildContext context, int index) {
                        return ListTile(
                          title: Text(snapshot.data[index].userId.toString()),
                          subtitle: Text(snapshot.data[index].id.toString()),
                        );
                      },
                    );