Skip to Content
Accessibility

Accessibility Guide

The Lazarillo Maps Flutter plugin is designed to be accessible to all users, including those using screen readers and other assistive technologies. This guide explains the accessibility features available in the plugin and how to customize them.

Overview

The plugin provides accessibility support for all interactive map UI elements:

  • Zoom In Button: Increases the map zoom level
  • Zoom Out Button: Decreases the map zoom level
  • Current Location Button: Centers the map on the user’s current location
  • Floor Selector: Allows users to select which building floor to display
  • Compass Button: Resets the map bearing to North

All UI elements have proper accessibility attributes that are read by screen readers (TalkBack on Android, VoiceOver on iOS) to describe the purpose of each control.

Configuration

Both iOS and Android support the same accessibility configuration approach through MapAccessibilityConfig. This provides a consistent API across platforms.

All accessibility settings are configured when creating the map using the accessibility parameter in MapConfiguration.

Default Accessibility Texts

By default, the SDK uses the following accessibility descriptions:

UI ElementDefault Text
Zoom In Button”Zoom in on the map”
Zoom Out Button”Zoom out on the map”
Current Location Button”Center map on your current location”
Floor Selector”Select building floor to display”
Compass Button”Reset map bearing to North”

These default texts are provided by the native SDKs and are in English. They follow accessibility best practices by being concise yet descriptive.

Customizing Accessibility

You can customize accessibility settings directly from Flutter code using the MapAccessibilityConfig class. This works on both iOS and Android:

import 'package:lazarillo_maps/lazarillo_maps.dart'; final mapConfig = MapConfiguration( latitude: 40.7128, longitude: -74.0060, zoom: 18, accessibility: MapAccessibilityConfig( zoomIn: AccessibilityConfig( label: 'Acercar mapa', hint: 'Aumenta el nivel de zoom del mapa', isAccessible: true, ), zoomOut: AccessibilityConfig( label: 'Alejar mapa', hint: 'Disminuye el nivel de zoom del mapa', isAccessible: true, ), userLocation: AccessibilityConfig( label: 'Mi ubicación', hint: 'Centra el mapa en tu ubicación actual', isAccessible: true, ), floorSelector: AccessibilityConfig( label: 'Selector de piso', hint: 'Toca para elegir un piso', isAccessible: true, ), compass: AccessibilityConfig( label: 'Brújula', hint: 'Restablecer la orientación del mapa al norte', isAccessible: true, ), ), );

AccessibilityConfig Properties

  • isAccessible: Whether the element is accessible to screen readers (default: true). Set to false to hide from screen readers while keeping it visible and functional.
  • label: The accessibility label that screen readers read when the element is focused. If null, the default label from the native SDK is used.
  • hint: Additional context about what the element does. If null, the default hint from the native SDK is used.

All properties are optional. If not provided, the SDK uses its default values.

Accessibility Best Practices

When customizing accessibility texts, follow these guidelines:

  1. Be Clear and Concise: Keep descriptions short but informative (ideally under 50 characters)
  2. Describe the Action: Focus on what the control does, not just what it is
  3. Use Action Verbs: Start with verbs like “Zoom”, “Center”, “Select”
  4. Avoid Redundancy: Don’t repeat information that screen readers already announce (like “Button”)
  5. Match Your App’s Language: Use the same language and tone as the rest of your application

Good Examples

✅ “Increase map zoom level”
✅ “Center map on current location”
✅ “Select floor to display”
✅ “Zoom in on map”

Avoid

❌ “Zoom in button” (redundant - screen reader already says “button”)
❌ “Click here” (not descriptive of the action)
❌ “Zoom” (too vague)

Screen Reader Visibility Control

You can control whether UI elements are accessible to screen readers while keeping them visible and functional. This is useful for:

  • Blind users: Hide controls that provide only visual feedback (they can’t see the map changes)
  • Low vision users: Keep controls accessible (they can see the visual feedback)

How It Works

When an element is hidden from screen readers:

  • ✅ Element remains visible on screen
  • ✅ Element remains functional (clickable)
  • ❌ Screen readers will skip these elements during navigation

Configuring Screen Reader Visibility

Use the isAccessible property in AccessibilityConfig:

final mapConfig = MapConfiguration( latitude: 40.7128, longitude: -74.0060, zoom: 18, accessibility: MapAccessibilityConfig( zoomIn: AccessibilityConfig( label: 'Acercar mapa', isAccessible: false, // Hide from screen readers ), zoomOut: AccessibilityConfig( label: 'Alejar mapa', isAccessible: false, // Hide from screen readers ), userLocation: AccessibilityConfig( label: 'Mi ubicación', isAccessible: true, // Keep accessible ), floorSelector: AccessibilityConfig( label: 'Selector de piso', isAccessible: true, // Keep accessible ), compass: AccessibilityConfig( label: 'Brújula', isAccessible: true, // Keep accessible ), ), );

Location Button Click Listener

The current location button provides a callback with detailed information about the operation result, allowing you to display custom messages or handle the result appropriately.

Setting Up the Listener

You can set up a listener to be notified when the user taps the location button on the map:

import 'package:lazarillo_maps/lazarillo_maps.dart'; import 'package:lazarillo_maps/src/lazarillo_maps_platform_interface.dart'; // Set up the listener after the map is ready await LazarilloMapsPlatform.instance.setOnLocationButtonClickListener( mapId, (result) { if (result.success && result.location != null) { final location = result.location!; print('Map centered at: ${location.latitude}, ${location.longitude}'); // Show success message ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Map centered at: ${location.latitude.toStringAsFixed(6)}, ' '${location.longitude.toStringAsFixed(6)}', ), backgroundColor: Colors.green, ), ); } else { print('Error: ${result.error}'); // Show error message ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error: ${result.error ?? "Unknown error"}'), backgroundColor: Colors.red, ), ); } }, );

Removing the Listener

To remove the listener when it’s no longer needed:

await LazarilloMapsPlatform.instance.removeLocationButtonClickListener(mapId);

LocationButtonClickResult

The callback receives a LocationButtonClickResult object with the following properties:

PropertyTypeDescription
successboolWhether the location was successfully obtained and the map was centered
locationLzLocation?The location that was used to center the map (null if operation failed)
errorString?Error message if the operation failed (null if operation succeeded)

Error Scenarios

The callback will be invoked with success = false in the following cases:

  • No location available: Location provider couldn’t obtain a valid location within 5 seconds
  • No repository: Location repository was not set via setLocationProvider() (Android only)
  • Exception occurred: An error occurred while trying to get the location

Compass Button Click Listener

The compass button provides a callback when clicked, which is useful for tracking user interactions or performing additional actions when the user resets the map orientation.

Setting Up the Listener

await LazarilloMapsPlatform.instance.setOnCompassClickListener( mapId, (bearing) { print('Compass clicked! Previous bearing: $bearing'); // The map automatically resets to North (0) }, );

Removing the Listener

await LazarilloMapsPlatform.instance.removeCompassClickListener(mapId);

Complete Example

import 'package:flutter/material.dart'; import 'package:lazarillo_maps/lazarillo_maps.dart'; import 'package:lazarillo_maps/src/lazarillo_maps_platform_interface.dart'; class MapExample extends StatefulWidget { @override _MapExampleState createState() => _MapExampleState(); } class _MapExampleState extends State<MapExample> { String? mapId; final lazarilloMaps = LazarilloMaps('your-api-key'); @override void initState() { super.initState(); _initializeMap(); } Future<void> _initializeMap() async { await lazarilloMaps.initialize(); final mapWidget = lazarilloMaps.getLazarilloMapWidget( MapConfiguration( latitude: 40.7128, longitude: -74.0060, zoom: 15, ), (id) { mapId = id; _setupLocationButtonListener(id); }, ); } Future<void> _setupLocationButtonListener(String mapId) async { await LazarilloMapsPlatform.instance.setOnLocationButtonClickListener( mapId, (result) { if (result.success && result.location != null) { final location = result.location!; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('📍 Map centered successfully!'), Text('Lat: ${location.latitude.toStringAsFixed(6)}'), Text('Lng: ${location.longitude.toStringAsFixed(6)}'), if (location.floorId != null) Text('Floor: ${location.floorId}'), ], ), backgroundColor: Colors.green, duration: Duration(seconds: 3), ), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('❌ Error: ${result.error ?? "Unknown error"}'), backgroundColor: Colors.red, ), ); } }, ); } @override Widget build(BuildContext context) { // Return your map widget return Container(); } @override void dispose() { if (mapId != null) { LazarilloMapsPlatform.instance.removeLocationButtonClickListener(mapId!); } super.dispose(); } }

Testing Accessibility

Testing on iOS

  1. Enable VoiceOver: Go to Settings > Accessibility > VoiceOver and enable it
  2. Navigate the Map: Swipe through the map controls and listen to the announcements
  3. Verify Descriptions: Ensure all controls have meaningful descriptions
  4. Test Custom Texts: Verify your custom accessibility texts are being used

Testing on Android

  1. Enable TalkBack: Go to Settings > Accessibility > TalkBack and enable it
  2. Navigate the Map: Swipe through the map controls and listen to the announcements
  3. Verify Descriptions: Ensure all controls have meaningful descriptions
  4. Test Custom Texts: Verify your custom accessibility texts are being used

UI Elements Overview

Zoom Controls

The zoom controls are ImageButton elements positioned on the right side of the map:

  • Zoom In: Increases map zoom by 1 level (up to maxZoom)
  • Zoom Out: Decreases map zoom by 1 level (down to minZoom)

Both buttons are visible by default but can be hidden using showZoomIn: false and showZoomOut: false in MapConfiguration.

Current Location Button

The current location button is positioned in the top-right corner of the map. When clicked:

  • It centers the map on the user’s current location
  • Uses a zoom level of 17.0
  • Animates the camera movement smoothly
  • Provides a callback with operation result (success/failure and location data)

The button can be hidden using showZoomToLocation: false in MapConfiguration.

Listener Example:

await LazarilloMapsPlatform.instance.setOnLocationButtonClickListener( mapId, (result) { if (result.success && result.location != null) { // Handle successful location centering final location = result.location!; print('Centered at: ${location.latitude}, ${location.longitude}'); } else { // Handle error case print('Error: ${result.error}'); } }, );

Floor Selector

The floor selector is a Spinner positioned in the bottom-left corner of the map. It:

  • Allows users to select which building floor to display
  • Shows only floors available for the current place
  • Automatically filters map layers based on the selected floor

The floor selector can be hidden using showFloorSelector: false in MapConfiguration.

Compass Button

The compass button appears in the top-right corner when the map is rotated (bearing is not 0). When clicked:

  • It resets the map bearing to 0 (North) with a smooth animation
  • It disappears once the map is oriented North
  • It provides a callback with the previous bearing

The compass button appearance can be customized using compassIcon in MapConfiguration.

Support

If you encounter accessibility issues or need help customizing accessibility texts, please contact support at lazarillo.app .

Last updated on