TappablePolyline не может быть изменен в flutter_map - PullRequest
0 голосов
/ 15 марта 2020

Я получаю List<LatLng> назад от отслеженного маршрута и отображаю его на карте, используя его в параметре points:. Поскольку я хочу иметь возможность нажать на него и вызвать нижний лист, чтобы очистить экран от ломаной линии, я использую плагин flutter_map_tappable_polyline и TappablePolyline вместо Polyline. TappablePolyline отображается правильно, но не может быть изменено. Я перепробовал все комбинации ордеров с параметрами слоя, и ничего не изменилось. Полилиния никогда не может быть изменена MarkerClusterGroupLayerOptions.

, поэтому я также реализовал плагин flutter_map_marker_cluster и закомментировал MarkerLayerOptions, передав вместо него параметр List<Markers> alertsMarkers в MarkerClusterLayerOptions markers:. У меня сейчас две проблемы. 1ST: TappablePolyline все еще не может быть изменено, но я предположил, так как я не вижу ни одного параметра polylines: в MarkerClusterLayerOptions, поэтому я не понимаю, как управлять им с помощью MarkerClusterLayerOptions. 2ND: теперь List<Markers> alertsMarkers, который обновляется с состоянием, больше не обновляет маркеры на экране.

Что мне не хватает для реализации ?? Большое спасибо. Это код для моего экрана:

class MapScreen extends StatefulWidget {
  final User user;
  MapScreen({Key key, this.user}) : super(key: key);

  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  //alerts
  List<Marker> alertsMarkers = [];
  List<UserAlert> alerts;
  String alertType;
  // user location
  LatLng userLocation;
  // tracking
  bool isTracking = false;
  String routeName;
  List<LatLng> route = [];
  // route polyline
  List<Polyline> routePolyline = [];
//  String userName = widget.userName;

  List<TaggedPolyline> tapPolyline = [];
  MapController _mapController = MapController();
  TextEditingController _textEditingController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return MultiBlocListener(
      listeners: [
        BlocListener<LocationBloc, LocationState>(
            listener: (BuildContext context, LocationState state) {
          if (state is LocationStream) {
            setState(() {
              userLocation = (state).location;
//              print(
//                  ' @@@@ MapBloc actual user location from stream  is : $userLocation');
            });
          }
          if (state is MapCenter) {
            userLocation = (state).location;
//            print(' @@@@ MapBloc initial center location is : $userLocation');
            _mapController.move(userLocation, 16);
          }
        }),
        BlocListener<TrackingBloc, TrackingState>(
//              bloc: TrackingBloc(),
            listener: (BuildContext context, TrackingState state) {
//      userLocation = (state as LocationStream).location;
          if (state is TrackedRoute) {
            List<LatLng> route = (state).trackedRoute;
            print('TrackingListener route is : $route');
//            BlocProvider.of<DirectionsBloc>(context).add(GetDirections(route));

            // TODO Delete mockRoute and BlocProvider after it and re activate the BlocProvider above here once finished with route coding.

            List<LatLng> mockRoute = [
              LatLng(44.501224, 11.335855),
              LatLng(44.500714, 11.335623),
              LatLng(44.50054, 11.335546),
              LatLng(44.500518, 11.335627),
              LatLng(44.500492, 11.335626),
              LatLng(44.500471, 11.335714),
              LatLng(44.500469, 11.335778),
              LatLng(44.500472, 11.335865),
              LatLng(44.50047, 11.335934),
              LatLng(44.500466, 11.336009),
              LatLng(44.500459, 11.336087),
              LatLng(44.500448, 11.336169),
              LatLng(44.500429, 11.336243),
              LatLng(44.500413, 11.336312),
              LatLng(44.500373, 11.336488),
              LatLng(44.500305, 11.336641),
              LatLng(44.500207, 11.336797),
              LatLng(44.500187, 11.336866),
              LatLng(44.50071, 11.337171),
              LatLng(44.50078, 11.337216),
              LatLng(44.500824, 11.337253),
              LatLng(44.500888, 11.33712)
            ];
            BlocProvider.of<DirectionsBloc>(context)
                .add(GetDirections(mockRoute));
          }
        }),
        BlocListener<DirectionsBloc, DirectionsState>(
//              bloc: TrackingBloc(),
            listener: (BuildContext context, DirectionsState state) {
          if (state is SnappedDirections) {
            //adding polyline for tracked route.
            setState(() {
              route.clear();
//              print('route at SnappedDirection count is : ${route.length}');
//              print(
//                  'DirectionsListener directionRoute from state count is: ${(state).directionsRoute.length}');
//              print(
//                  'DirectionsListener directionRoute from state  is: ${(state).directionsRoute}');
              route = (state).directionsRoute;
//              print(
//                  'route with locations form (state).directionsRoute count is : ${route.length}');
//              print(
//                  'route with locations form (state).directionsRoute is : $route');
//
//              routePolyline.clear();
              tapPolyline.clear();

//              print(
//                  'routePolyline resetted and count is now :${routePolyline.length}');

//              routePolyline.add(
//                new Polyline(
//                  points: route,
//                  strokeWidth: 4.0,
////                  color: Colors.greenAccent,
//                  gradientColors: [
//                    Colors.greenAccent,
//                    Colors.lightGreenAccent,
//                    Colors.redAccent
//                  ],
//                ),
//              );
              tapPolyline.add(TaggedPolyline(
                tag: routeName,
                points: route,
                strokeWidth: 4.0,
//                  color: Colors.greenAccent,
                gradientColors: [
                  Colors.greenAccent,
                  Colors.lightGreenAccent,
                  Colors.redAccent
                ],
              ));

//              print(
//                  'total polylines in routePolyline are: ${routePolyline.length}');
//              print(
//                  'first routePolyline points count after adding Polyline is: ${routePolyline[0].points.length}');
            }); // setState
          }
        }),
        BlocListener<AlertBloc, AlertState>(
            listener: (BuildContext context, AlertState state) {
          if (state is AlertLoaded) {
            setState(() {
//              alerts = (state).alerts;
              alertsMarkers = (state).alerts;
//              print(
//                  '######### AlertListener userAlerts are: ${alerts.toString()} and total alerts are : ${alerts.length}');
            });
          }
        }),
      ],
      child: Scaffold(
        key: _scaffoldKey,
        drawerScrimColor: Colors.red[50],
        drawerEdgeDragWidth: 20,
//        endDrawer: ,
        drawer: Drawer(
//        semanticLabel: ,
          child: Center(
            child: Container(
              width: 400,
              color: Colors.redAccent,
              child: Column(
                children: <Widget>[
                  SizedBox(height: 50),
                  CircleAvatar(
                    radius: 70,
//                    minRadius: 60,
//                    maxRadius: 100,
                    backgroundImage: NetworkImage('${widget.user.photoUrl}'),
                  ),
                  Text(
                    '${widget.user.name}',
                    style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.w300,
                        fontSize: 35),
                  ),
                  Text(
                    '${widget.user.email}',
                    style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.w200,
                        fontSize: 15),
                  ),
                  SizedBox(height: 15),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Scheduler button.png'),
                        tooltip: 'Route check scheduler',
                        color: Colors.white,
                        iconSize: 55,
                        onPressed: () {
//              BlocProvider.of<AuthenticationBloc>(context).add(
//                LoggedOut(),
//              );
                        },
                      ),
                      SizedBox(width: 20),
                      Text(
                        'Check scheduler',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Shop button.png'),
                        color: Colors.white,
                        tooltip: 'Bike shop',
                        iconSize: 55,
                        onPressed: () {
//              BlocProvider.of<AuthenticationBloc>(context).add(
//                LoggedOut(),
//              );
                        },
                      ),
                      SizedBox(width: 20),
                      Text(
                        'Bike shop',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Orders button.png'),
                        tooltip: 'My orders',
                        color: Colors.orange,
                        iconSize: 55,
                        onPressed: () {
//              BlocProvider.of<AuthenticationBloc>(context).add(
//                LoggedOut(),
//              );
                        },
                      ),
                      SizedBox(width: 20),
                      Text(
                        'My orders',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Bookings button.png'),
                        tooltip: 'My bookings',
                        color: Colors.orange,
                        iconSize: 55,
                        onPressed: () {
//              BlocProvider.of<AuthenticationBloc>(context).add(
//                LoggedOut(),
//              );
                        },
                      ),
                      SizedBox(width: 20),
                      Text(
                        'My bookings',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Routes button.png'),
                        tooltip: 'My routes',
                        iconSize: 55,
                        color: Colors.redAccent,
                        onPressed: () {
//              BlocProvider.of<AuthenticationBloc>(context).add(
//                LoggedOut(),
//              );
                        },
                      ),
                      SizedBox(width: 20),
                      Text(
                        'My routes',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Settings button.png'),
                        tooltip: 'Settings',
                        color: Colors.white,
                        iconSize: 55,
                        onPressed: () {
//              BlocProvider.of<AuthenticationBloc>(context).add(
//                LoggedOut(),
//              );
                        },
                      ),
                      SizedBox(width: 20),
                      Text(
                        'Settings',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(width: 20),
                      IconButton(
                        icon: Image.asset('assets/Logout button.png'),
                        tooltip: 'Logout',
                        color: Colors.white,
                        iconSize: 60,
                        onPressed: () {
                          BlocProvider.of<AuthenticationBloc>(context).add(
                            LoggedOut(),
                          );
                        },
                      ),
                      SizedBox(width: 15),
                      Text(
                        'Logout',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 18,
                            fontWeight: FontWeight.w400),
                      )
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
        appBar: AppBar(
          backgroundColor: Colors.transparent,
          elevation: 0,
//          title: Text(
//            'Home',
//            style: TextStyle(color: Colors.orangeAccent, fontSize: 40),
//          ),
          leading: IconButton(
              icon: Icon(
                Icons.menu,
                color: Colors.redAccent,
                size: 30,
              ),
              onPressed: () {
                //TODO: open drawer
//                if (_scaffoldKey.currentState != null &&
//                    _scaffoldKey.currentState.isDrawerOpen == true)
//                  Navigator.pop(context);
                _scaffoldKey.currentState?.openDrawer();
//                Scaffold.of(context).openDrawer();
              }),
        ),
        backgroundColor: Colors.white,
        body: SafeArea(
          minimum: EdgeInsets.symmetric(horizontal: 20),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Container(
                  height: 600,
                  width: 350,
                  child: FlutterMap(
                    options: MapOptions(
                      center: userLocation,
                      minZoom: 5.0,
                      maxZoom: 19.0,
                      interactive: true,
                      plugins: [
                        MarkerClusterPlugin(),
                        TappablePolylineMapPlugin(),
                      ],
                    ),
                    mapController: _mapController,
                    layers: [
                      TileLayerOptions(
                          urlTemplate:
                              'https://api.openrouteservice.org/mapsurfer/{z}/{x}/{y}.png?api_key=5b3ce3597851110001cf62484c4b65d85bc844eca3a2c6b9f300ddf4',
//                              urlTemplate:
//                                  'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                          subdomains: ['a', 'b', 'c'],
                          keepBuffer: 20),

                      new MarkerLayerOptions(
                        markers: [
                          Marker(
                            anchorPos: AnchorPos.align(AnchorAlign.center),
                            point: userLocation,
                            height: 70,
                            width: 70,
                            builder: (context) => IconButton(
                              icon: Icon(Icons.directions_bike),
                              color: Colors.red,
                              iconSize: 50,
                              onPressed: () {
                                print('icon tapped');
                              },
                            ),
                          ),
                        ],
                      ),
                      new TappablePolylineLayerOptions(
                        polylines:
                            tapPolyline, //TODO polyline IS NOT tappable!!
//                        onTap: (TaggedPolyline polyline) => print(polyline.tag),
                        onTap: (BuildContext context) {
//                          print('${polyline.tag}');
                          final action = CupertinoActionSheet(
                            title: Text(
                              'Percorso $routeName',
                              style: TextStyle(
                                  fontSize: 25,
                                  color: Colors.black,
                                  fontWeight: FontWeight.w400),
                            ),
                            message: Text(
                              'Il percorso $routeName è stato salvato, scegli ok per non visuallizzarlo sullo schermo.',
                              style: TextStyle(
                                  fontSize: 18,
                                  color: Colors.black,
                                  fontWeight: FontWeight.w400),
                            ),
                            actions: <Widget>[
                              CupertinoActionSheetAction(
                                child: Text('Ok'),
                                isDefaultAction: true,
                                isDestructiveAction: false,
                                onPressed: () {
                                  print("Action 1 is been clicked");
                                  setState(() {
                                    routeName = null;
                                    tapPolyline.clear();
                                    route.clear();
                                  });
                                },
                              )
                            ],
                            cancelButton: CupertinoActionSheetAction(
                              child: Text("Cancella"),
                              onPressed: () {
                                Navigator.pop(context);
                              },
                            ),
                          );
                          showCupertinoModalPopup(
                              context: context, builder: (context) => action);
                        },
                      ),
//                      new PolylineLayerOptions(
//                        polylines: routePolyline,
//                      ),

                      MarkerClusterLayerOptions(
                        maxClusterRadius: 120,
                        size: Size(40, 40),
                        fitBoundsOptions: FitBoundsOptions(
                          padding: EdgeInsets.all(50),
                        ),
                        markers:
                            alertsMarkers, // TODO alertsMarkers DON'T update with new state!!
                        polygonOptions: PolygonOptions(
                            borderColor: Colors.blueAccent,
                            color: Colors.black12,
                            borderStrokeWidth: 3),
                        builder: (context, markers) {
                          return FloatingActionButton(
                            child: Text(markers.length.toString()),
                            onPressed: null,
                          );
                        },
                      ),
//                      new MarkerLayerOptions(
//                        markers: alertsMarkers, //TODO alertsMakers DO update with new state.
//                      ),
                    ],
                  ),
                ),
//                SizedBox(
//                  height: 10,
//                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    CustomImageButton(
                      onPressed: () {
                        print('alertButton pressed');

                        //TODO call the card to display alert details
                        final action = CupertinoActionSheet(
                          title: Text(
                            'Nuovo cloud avviso',
                            style: TextStyle(fontSize: 25),
                          ),
                          actions: <Widget>[
                            CupertinoActionSheetAction(
                                child: Text("Senza immagine"),
                                isDefaultAction: true,
                                onPressed: () async {
                                  print("Action 1 is been clicked");
                                  Navigator.pop(context);
                                  String alertType = await Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (context) =>
                                          AlertSelectionScreen(),
                                    ),
                                  );
                                  if (alertType != null) {
                                    BlocProvider.of<AlertBloc>(context).add(
                                        AddAlert(
                                            widget.user.name,
                                            alertType,
                                            userLocation.latitude.toString(),
                                            userLocation.longitude.toString()));
                                  }
                                }),
                            CupertinoActionSheetAction(
                              child: Text("Con immagine"),
                              isDestructiveAction: true,
                              onPressed: () {
                                print("Action 2 is been clicked");
                                Navigator.pop(context);
                              },
                            )
                          ],
                          cancelButton: CupertinoActionSheetAction(
                            child: Text("Cancella"),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                        );
                        showCupertinoModalPopup(
                            context: context, builder: (context) => action);
                      },
                      image: 'assets/New alert button.png',
                      height: 60,
                      width: 60,
//                      backgroundColor: Colors.redAccent,
//                      padding: EdgeInsets.all(5),
                    ),
                    CustomImageButton(
                      onPressed: () {
                        print('New route button pressed');
//                        BlocProvider.of<TrackingBloc>(context)
//                            .add(StartStopTracking());
                        final action = CupertinoActionSheet(
                          title: Text(
                            'Nuovo percorso',
                            style: TextStyle(
                                fontSize: 25,
                                color: Colors.black,
                                fontWeight: FontWeight.w400),
                          ),
                          message: Text(
                            'Inserisci un nome per il tuo nuovo percorso, e scegli Inizia tracking. Quando sarai arrivato a destinazione premi di nuovo il bottone Tracking e scegli Fine tracking.',
                            style: TextStyle(
                                fontSize: 18,
                                color: Colors.black,
                                fontWeight: FontWeight.w400),
                          ),
                          actions: <Widget>[
                            CupertinoActionSheetAction(
                                child: CupertinoTextField(
                                  controller: _textEditingController,
                                  showCursor: true,
                                  placeholder:
                                      isTracking ? routeName : 'nome percorso',
                                ),
                                isDefaultAction: false,
                                isDestructiveAction: false,
                                onPressed: () async {
                                  print("Action 1 is been clicked");
                                }),
                            CupertinoActionSheetAction(
                              child: Text(isTracking
                                  ? "Fine tracking"
                                  : 'Inizia tracking'),
                              isDefaultAction: true,
                              isDestructiveAction: false,
                              onPressed: () {
                                print("Action 2 is been clicked");
                                routeName = _textEditingController.text;
                                Navigator.pop(context);
                                isTracking = !isTracking;
                                BlocProvider.of<TrackingBloc>(context)
                                    .add(StartStopTracking());
                              },
                            )
                          ],
                          cancelButton: CupertinoActionSheetAction(
                            child: Text("Cancella"),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                        );
                        showCupertinoModalPopup(
                            context: context, builder: (context) => action);
                      },
                      image: 'assets/New route button.png',
                      height: 60,
                      width: 60,
//                      backgroundColor: Colors.redAccent,
//                      padding: EdgeInsets.all(5),
                    ),
                    CustomImageButton(
                      onPressed: () {
                        print('Center map button pressed');
                        _mapController.move(userLocation, 16);
                      },
                      image: 'assets/Center map button.png',
                      height: 60,
                      width: 60,
//                      backgroundColor: Colors.redAccent,
//                      padding: EdgeInsets.all(5),
//                      decoration: BoxDecoration(
//                          borderRadius: BorderRadius.circular(5),
//                          shape: BoxShape.rectangle),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
//      ),
    );
  }
}
```
...