How to zoom between two Google map markers in flutter

To zoom between two Lat Lng bounds in google map, you can do as below:

First of all import below library in pubspec.yaml otherwise with the older version, you might not be able to see "getVisibleRegion()" method with google map controller.

google_maps_flutter: ^0.5.12

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  Completer<GoogleMapController> _controller = Completer();
  GoogleMapController mapController;
  LatLng _lastMapPosition = _center;

  static const LatLng _center = const LatLng(45.521563, -122.677433);

  final Set<Marker> _markers = {};

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
    _controller.complete(controller);

    LatLng latLng_1 = LatLng(40.416775, -3.70379);
    LatLng latLng_2 = LatLng(41.385064, 2.173403);
    LatLngBounds bound = LatLngBounds(southwest: latLng_1, northeast: latLng_2);

    setState(() {
      _markers.clear();
      addMarker(latLng_1, "Madrid", "5 Star Rating");
      addMarker(latLng_2, "Barcelona", "7 Star Rating");
    });

    CameraUpdate u2 = CameraUpdate.newLatLngBounds(bound, 50);
    this.mapController.animateCamera(u2).then((void v){
      check(u2,this.mapController);
    });

  }

  void addMarker(LatLng mLatLng, String mTitle, String mDescription){
    _markers.add(Marker(
      // This marker id can be anything that uniquely identifies each marker.
      markerId: MarkerId((mTitle + "_" + _markers.length.toString()).toString()),
      position: mLatLng,
      infoWindow: InfoWindow(
        title: mTitle,
        snippet: mDescription,
      ),
      icon: BitmapDescriptor.defaultMarker,
    ));
  }

  void check(CameraUpdate u, GoogleMapController c) async {
    c.animateCamera(u);
    mapController.animateCamera(u);
    LatLngBounds l1=await c.getVisibleRegion();
    LatLngBounds l2=await c.getVisibleRegion();
    print(l1.toString());
    print(l2.toString());
    if(l1.southwest.latitude==-90 ||l2.southwest.latitude==-90)
      check(u, c);
  }


  void _onCameraMove(CameraPosition position) {
    _lastMapPosition = position.target;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Maps Sample App'),
          backgroundColor: Colors.green[700],
        ),
        body: GoogleMap(
          markers: _markers,
          onMapCreated: _onMapCreated,
          initialCameraPosition: CameraPosition(
            target: _center,
            zoom: 11.0,
          ),
          onCameraMove: _onCameraMove,
        ),
      ),
    );
  }
}

The proposed solution above is good, but LatLngBounds has one important limitation:

LatLngBounds({@required this.southwest, @required this.northeast})
  : assert(southwest != null),
    assert(northeast != null),
    assert(southwest.latitude <= northeast.latitude); // <--

This means that the first coordinate must be lower and to the left of the second coordinate.

I had to modify the method for different coordinates.

    void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
    _controller.complete(controller);

    //offerLatLng and currentLatLng are custom

    final LatLng offerLatLng = LatLng(
    double.parse(widget.coordinates.first.latLongList.first.latitude),
    double.parse(widget.coordinates.first.latLongList.first.longitude));

    LatLngBounds bound;
    if (offerLatLng.latitude > currentLatLng.latitude &&
        offerLatLng.longitude > currentLatLng.longitude) {
      bound = LatLngBounds(southwest: currentLatLng, northeast: offerLatLng);
    } else if (offerLatLng.longitude > currentLatLng.longitude) {
      bound = LatLngBounds(
          southwest: LatLng(offerLatLng.latitude, currentLatLng.longitude),
          northeast: LatLng(currentLatLng.latitude, offerLatLng.longitude));
    } else if (offerLatLng.latitude > currentLatLng.latitude) {
      bound = LatLngBounds(
          southwest: LatLng(currentLatLng.latitude, offerLatLng.longitude),
          northeast: LatLng(offerLatLng.latitude, currentLatLng.longitude));
    } else {
      bound = LatLngBounds(southwest: offerLatLng, northeast: currentLatLng);
    }

    CameraUpdate u2 = CameraUpdate.newLatLngBounds(bound, 50);
    this.mapController.animateCamera(u2).then((void v){
      check(u2,this.mapController);
    });

  }