In today’s mobile development landscape, integrating maps into your app has become increasingly common. Whether you’re building a ride-sharing app, location-based service, or travel application, maps are often an essential feature. However, many developers face the dilemma of how to integrate maps without incurring costs or dealing with complex API keys and restrictions.
In this article, we’ll explore Free Map solutions for Flutter that require no API keys, allowing you to build map-based applications without the hassle of pricing models or API limits.
What is a Free Map Solution in Flutter?
A Free Map solution is a mapping service that allows developers to integrate maps into their mobile applications without requiring an API key, making it cost-effective and simple to implement. These solutions typically offer basic functionalities, such as displaying maps, adding markers, and handling basic map interactions.
In the context of Flutter, this means leveraging libraries and tools that integrate mapping features directly into your Flutter app with minimal setup and no need to connect to third-party APIs like Google Maps, Mapbox, or OpenStreetMap.
In this article, we’ll take a closer look at the free_map
Flutter package, how it works, its key features, and how you can easily integrate it into your app without the need for an API key.
What is the free_map
Package?
The free_map
package is a mapping library designed for Flutter developers who want to display maps without relying on third-party APIs that require authentication or API keys. It leverages open-source and freely available map tiles, making it ideal for developers who want a quick and hassle-free solution for adding maps to their Flutter apps.
The package allows you to easily embed a map into your application and interact with it. You can add markers, set the map’s center, zoom level, and manage user interactions—all without having to worry about dealing with API keys, quotas, or pricing models.
Key Features of free_map
Here are some of the core features that make the free_map
package attractive for Flutter developers:
- No API Key Required: The standout feature of
free_map
is that it doesn’t require any API keys, unlike most popular mapping solutions like Google Maps, Mapbox, or OpenStreetMap, which often demand API keys for authentication. - OpenStreetMap Integration: The
free_map
package uses OpenStreetMap (OSM) tiles for rendering the map. OpenStreetMap is an open-source mapping project, which means developers can freely use its tiles without any licensing or cost concerns. - Basic Map Interaction: The package supports basic map features such as zooming, panning, and rotating. Users can interact with the map by dragging and zooming in or out to explore different regions.
Now let’s dive into the implementation and explore how to use free_map
in your Flutter application!
Step 1: Adding Dependencies
Before we dive into the code, make sure you add the free_map
package to your Flutter project. Open your pubspec.yaml
file and add the following under dependencies
:
yamlCopy codedependencies:
flutter:
sdk: flutter
free_map: ^latest_version
After saving the pubspec.yaml
, run flutter pub get
to install the package.
Step 2: Creating the Location Picker Screen
We’ll create a simple Location Picker Screen that allows users to search for addresses and select one. The selected address will be displayed and passed back to the previous screen. The widget will use FMWidget
from the free_map
package, which renders the map and search field, allowing users to search and select an address.
Here’s the core code for the LocationPickerScreen:
dartCopy codeimport 'package:flutter/material.dart';
import 'package:free_map/free_map.dart';
class LocationView extends StatefulWidget {
@override
_LocationViewState createState() => _LocationViewState();
}
class _LocationViewState extends State<LocationView> {
// Variables to store selected address and search text
String selectedAddress = '';
TextEditingController searchTextController = TextEditingController();
TextEditingController addressController = TextEditingController();
// This function is called when an address is selected from the map
void _onAddressSelected(FMValue value) {
setState(() {
selectedAddress = value.address; // Update the selected address
addressController.text = value.address; // Update the address in the form controller
});
Navigator.pop(context); // Close the current screen
}
// Builder for the search field
TextFormField _searchTextFieldBuilder(
FocusNode focusNode,
TextEditingController controller,
Function(String)? onChanged,
) {
return TextFormField(
focusNode: focusNode,
controller: controller,
onChanged: onChanged,
decoration: InputDecoration(
filled: true,
border: _border,
errorBorder: _border,
enabledBorder: _border,
focusedBorder: _border,
disabledBorder: _border,
hintText: 'Search Address',
focusedErrorBorder: _border,
fillColor: Colors.grey[100],
),
);
}
// Custom input border style
InputBorder get _border => OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.grey),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: const IconThemeData(color: Colors.green),
title: const Text(
'Choose Address',
style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold),
),
centerTitle: true,
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.9,
child: FMWidget(
initialValue: selectedAddress, // Set the initial value to the selected address
searchTextFieldBuilder: _searchTextFieldBuilder, // Provide custom search field builder
onSelected: (FMValue value) {
_onAddressSelected(value); // Handle address selection
},
),
),
),
);
}
}
Explanation of Code:
1. FMWidget:
This is the core widget from the free_map
package that displays the map and enables users to search for addresses. You pass it the initialValue
(the initially selected address), and the onSelected
callback is triggered when the user selects an address from the map.
dartCopy codeFMWidget(
initialValue: selectedAddress, // Set the initially selected address
searchTextFieldBuilder: _searchTextFieldBuilder, // Custom search input field builder
onSelected: (FMValue value) {
_onAddressSelected(value); // Callback for address selection
},
);
2. Search Field:
We’ve customized the search input field with _searchTextFieldBuilder
, which defines the appearance of the search field using TextFormField
. The search field has a hint text (“Search Address”) and custom borders. When the user types, the map updates to show relevant locations.
dartCopy codeTextFormField _searchTextFieldBuilder(
FocusNode focusNode,
TextEditingController controller,
Function(String)? onChanged,
) {
return TextFormField(
focusNode: focusNode,
controller: controller,
onChanged: onChanged,
decoration: InputDecoration(
filled: true,
border: _border,
hintText: 'Search Address',
fillColor: Colors.grey[100],
),
);
}
How It Works
- Initial View: When the user navigates to the
LocationView
, the map and a search field are displayed. The map is initialized with the current selected address (if any). - Address Search: The user types in the search field. As they type, the map updates to show matching places based on the search query.
- Address Selection: When the user selects an address from the map, the
onSelected
callback is triggered. The selected address is updated in the state and passed to theaddressController
, which can be used to update forms or other parts of the app. - Close Screen: After selecting an address, the screen is closed with
Navigator.pop(context)
, and the selected address is passed back to the previous screen.
How It Works
- Initial View: When the user navigates to the
LocationView
, the map and a search field are displayed. The map is initialized with the current selected address (if any). - Address Search: The user types in the search field. As they type, the map updates to show matching places based on the search query.
- Address Selection: When the user selects an address from the map, the
onSelected
callback is triggered. The selected address is updated in the state and passed to theaddressController
, which can be used to update forms or other parts of the app. - Close Screen: After selecting an address, the screen is closed with
Navigator.pop(context)
, and the selected address is passed back to the previous screen.
Benefits of Using free_map
- No API Key: You don’t need to worry about managing API keys or dealing with request quotas.
- Open-Source Data: The map tiles are provided by OpenStreetMap, a community-driven open-source mapping project.
- Simple Integration: The
free_map
package is lightweight and integrates seamlessly into Flutter projects.