迭代抖动图中的元素

时间:2018-11-19 17:08:26

标签: dart flutter maps

我正在尝试通过map包获取扑扑中的元素数组。

我阅读了this教程,以了解如何在颤振中显示多个坐标。本教程手动添加元素,我需要使用api rest添加。

我创建了一个foreach来检索数组中的所有元素,然后将所有坐标添加到列表中。问题:列表以initstate方法重置,因此我无法花费列表长度来循环所有坐标。

这是代码:

 MapController mapController;
  Map<String, LatLng> coords;
  List<Marker> markers;
  List<Map<String, LatLng>> listado = [];

  Future<Null> fetchPost() async {
    final response = await http.get(url);
    final responseJson = json.decode(response.body);
    for (Map user in responseJson) {
      coords.putIfAbsent("Test", () => new LatLng(user['lat'], user['long']));
      listado.add(coords);
     // print(listado.toList());
    }
  }

  @override
  void initState() {
    super.initState();
    mapController = new MapController();
    coords = new Map<String, LatLng>();
    fetchPost();
    markers = new List<Marker>();
    for (int i = 0; i < listado.length; i++) {
      print(listado[1].values.elementAt(i));
      markers.add(new Marker(
          width: 80.0,
          height: 80.0,
          point: listado[1].values.elementAt(i),
          builder: (ctx) => new Icon(Icons.home, color: Colors.red[300])));
    }
  }

  @override
  Widget build(BuildContext context) {
    return new FlutterMap(
      options: new MapOptions(
        center: new LatLng(37.7525244, 139.1650556),
        zoom: 5.0,
      ),
      mapController: mapController,
      layers: [
        new TileLayerOptions(
            urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
            subdomains: ['a', 'b', 'c']),
        new MarkerLayerOptions(markers: markers)
      ],
    );
  }
}

final String url =
    'https://my-json-server.typicode.com/tobiobi/myjasonserver/coordinates';

//STATES
class UserDetails {
  final String name;
  final double lat, long;

  UserDetails({this.name, this.lat, this.long});

  factory UserDetails.fromJson(Map<dynamic, dynamic> json) {
    return new UserDetails(
      name: json['name'],
      lat: json['lat'],
      long: json['long'],
    );
  }
}

那么,如何获取列表中的所有坐标并循环迭代?

更新

我尝试

 void initState() {
    super.initState();
    mapController = new MapController();
    coords = new Map<String, LatLng>();
    fetchPost().then((data) {
      print(data);
      for (int i = 0; i < listado.length; i++) {
        markers.add(new Marker(
            width: 80.0,
            height: 80.0,
            point: coords.values.elementAt(i),
            builder: (ctx) => new Icon(Icons.home, color: Colors.red[300])));
      }
    });
  }

但是返回“ getter迭代器在null上被调用”。数据具有此json

 this: MapsPageState
 data: null

里面,我有listado数组和坐标,但是¿我如何获得?

更新2:解决方案

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:igota/screens/partials/alertmessages.dart';

class MapsPage extends StatefulWidget {
  static String tag = 'maps-page';

  @override
  MapsPageState createState() => new MapsPageState();
}

class MapsPageState extends State<MapsPage> {
  MapController mapController;
  Map<String, LatLng> coords;
  List<Marker> markers;
  List<Map<String, LatLng>> list = [];
    int _counter = 0;


  bool loading;
  Future<Null> fetchPost() async {
    list = List();
    markers = List();
    mapController = new MapController();
    coords = new Map<String, LatLng>();
    final response = await http.get(
        'https://my-json-server.typicode.com/tobiobi/myjasonserver/coordinates').catchError((error) {
      print(error.toString());
      AlertMessages.general(context,'No ha sido posible acceder a los datos');
    });
    final List responseJson = json.decode(response.body) as List;
    for (Map<String, dynamic> data in responseJson) {
            _counter++;

      coords.putIfAbsent("Test $_counter", () => new LatLng(double.parse(data['lat'].toString()),  double.parse(data['long'].toString())));
     list.add(coords);
     loading=false;
    }
    return;
  }
  @override
  void initState(){
    loading = true;
    super.initState();

    fetchPost().then((data) {
      for (int i = 0; i < list.length; i++) {
        markers.add(new Marker(
            width: 80.0,
            height: 80.0,
            point: list[0].values.elementAt(i),
            builder: (ctx) => new Icon(Icons.home, color: Colors.red[300])));
      }
      setState( () { } );
    }).catchError((error) {
      print(error.toString());
      AlertMessages.general(context, 'Problemas internos de código');
    });
  }

  @override
  Widget build(BuildContext context) {
    if (loading) {
      return new Container(
          color: Colors.red[300],
          child: new Center(
            child: new CircularProgressIndicator(
              valueColor: new AlwaysStoppedAnimation<Color>(Colors.white),
            ),
          ));
    } else {
      return new FlutterMap(
        options: new MapOptions(
          center: new LatLng(37.7525244, 139.1650556),
          zoom: 5.0,
        ),
        mapController: mapController,
        layers: [
          new TileLayerOptions(
              urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
              subdomains: ['a', 'b', 'c']),
          new MarkerLayerOptions(markers: markers)
        ],
      );
    }
  }
}

2 个答案:

答案 0 :(得分:1)

因此,当您尝试遍历listado.length时,其主要原因是fetchPost();为零,是因为您没有等待fetchPost();方法完成其执行。您将listado声明为Future,这意味着它可以异步运行。

您需要做的是确保在尝试遍历fetchPost()时,是在fetchPost().then( (data){ for (int i = 0; i < listado.length; i++) { print(listado[1].values.elementAt(i)); markers.add(new Marker( width: 80.0, height: 80.0, point: listado[1].values.elementAt(i), builder: (ctx) => new Icon(Icons.home, color: Colors.red[300]) )); } }); 上的回调方法中执行迭代。因此,您的代码应如下所示:

fetchPost()

这样,isLoadingData完成后,将运行回调方法,并且`listado'将具有最新数据。

我建议您还引入一种true状态,无论何时调用fetchPost()都应设置为false,并在回调方法的末尾设置为set_header_labels。这样一来,您就可以让用户知道您在后台执行某种处理,而他们也不必盯着空白页而无需任何反馈。

希望这会有所帮助。

答案 1 :(得分:0)

使用@ user8518697的答案,然后执行以下操作。

将标记初始化为List<Marker> markers = new List();
-使用for(int i = 0; i < (responseJson.length); i++)代替for(Map user in responseJson)

我也想对您的代码表示感谢。我已经能够使用它来显示存储在数据库中的多个标记。