Итерация элементов в флаттерной карте - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь получить массив элементов во флаттере с пакетом карты.

Я прочитал этот учебник, чтобы увидеть, как я могу показать более одной координаты в флаттере.Этот урок добавить элементы вручную, мне нужно добавить с API отдыха.

Я создал 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])));
      }
    });
  }

Но вернуть 'итератор получателя был вызван наноль'.Данные имеют этот json

 this: MapsPageState
 data: null

Внутри это У меня есть массив списков и координаты, но ¿как я могу получить?

ОБНОВЛЕНИЕ 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 голосов
/ 21 ноября 2018

Используйте ответ от @ user8518697 и затем сделайте следующее.

- инициализировать маркеры как List<Marker> markers = new List();
-использовать for(int i = 0; i < (responseJson.length); i++) вместо for(Map user in responseJson)

Я также хочу сказать спасибо за ваш код. Я смог использовать его для отображения нескольких маркеров, хранящихся в базе данных.

0 голосов
/ 20 ноября 2018

Таким образом, основная причина listado.length равна нулю, когда вы пытаетесь выполнить итерацию, потому что вы не ожидали, пока метод fetchPost(); завершит свое выполнение.Вы объявили fetchPost(); как будущее, что означает, что оно выполняется асинхронно.

Что нужно сделать, чтобы к тому времени, когда вы попытаетесь выполнить итерацию по listado, будет выполняться итерация в методе обратного вызова на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() будет запущен метод обратного вызова, и `listado 'будет иметь самые последние данные.

IСоветую также ввести состояние isLoadingData, которое вы устанавливаете на true при каждом вызове fetchPost() и false в конце метода обратного вызова.Точно так же вы можете сообщить пользователю, что вы выполняете какую-то обработку в фоновом режиме, и ему не нужно смотреть на пустую страницу без какой-либо обратной связи о происходящем.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...