Change the Case of Labels in Flutter
This tutorial shows how to change the text case of map labels — converting to uppercase, lowercase, or title case at runtime.
Prerequisites
Before you begin, ensure you have:
- Completed the Flutter Setup Guide
- A MapMetrics API key and style URL from the MapMetrics Portal
Change Label Text Transform
Use the text-transform layout property to change label casing:
dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';
class LabelCaseScreen extends StatefulWidget {
@override
_LabelCaseScreenState createState() => _LabelCaseScreenState();
}
class _LabelCaseScreenState extends State<LabelCaseScreen> {
MapMetricsController? mapController;
String currentCase = 'none';
final List<Map<String, String>> caseOptions = [
{'value': 'none', 'label': 'Default'},
{'value': 'uppercase', 'label': 'UPPERCASE'},
{'value': 'lowercase', 'label': 'lowercase'},
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Label Case')),
body: Column(
children: [
// Case selector
Container(
padding: EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: caseOptions.map((option) {
return ChoiceChip(
label: Text(option['label']!),
selected: currentCase == option['value'],
onSelected: (selected) {
if (selected) {
setState(() => currentCase = option['value']!);
_applyTextTransform(option['value']!);
}
},
);
}).toList(),
),
),
// Map
Expanded(
child: MapMetrics(
styleUrl:
'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
onMapCreated: (MapMetricsController controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: LatLng(48.8566, 2.3522),
zoom: 12.0,
),
),
),
],
),
);
}
void _applyTextTransform(String textCase) {
// Apply to common label layers in the style
final labelLayers = [
'place-city-label',
'place-town-label',
'road-label',
'poi-label',
];
for (final layer in labelLayers) {
mapController?.setLayoutProperty(layer, 'text-transform', textCase);
}
}
}Custom Label Styling
Combine text case changes with font size and color adjustments:
dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';
class LabelStyleScreen extends StatefulWidget {
@override
_LabelStyleScreenState createState() => _LabelStyleScreenState();
}
class _LabelStyleScreenState extends State<LabelStyleScreen> {
MapMetricsController? mapController;
String activePreset = 'default';
final Map<String, Map<String, dynamic>> presets = {
'default': {
'name': 'Default',
'textTransform': 'none',
'textSize': 1.0,
'textColor': '#333333',
},
'bold_caps': {
'name': 'Bold Caps',
'textTransform': 'uppercase',
'textSize': 1.2,
'textColor': '#1a1a1a',
},
'subtle': {
'name': 'Subtle',
'textTransform': 'lowercase',
'textSize': 0.8,
'textColor': '#999999',
},
'highlight': {
'name': 'Highlight',
'textTransform': 'uppercase',
'textSize': 1.1,
'textColor': '#1565c0',
},
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Label Styling')),
body: Column(
children: [
Container(
padding: EdgeInsets.all(8),
child: Wrap(
spacing: 8,
children: presets.entries.map((entry) {
return ChoiceChip(
label: Text(entry.value['name']),
selected: activePreset == entry.key,
onSelected: (selected) {
if (selected) {
setState(() => activePreset = entry.key);
_applyPreset(entry.value);
}
},
);
}).toList(),
),
),
Expanded(
child: MapMetrics(
styleUrl:
'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
onMapCreated: (MapMetricsController controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: LatLng(48.8566, 2.3522),
zoom: 13.0,
),
),
),
],
),
);
}
void _applyPreset(Map<String, dynamic> preset) {
final layers = ['place-city-label', 'place-town-label', 'road-label'];
for (final layer in layers) {
mapController?.setLayoutProperty(
layer, 'text-transform', preset['textTransform'],
);
mapController?.setPaintProperty(
layer, 'text-color', preset['textColor'],
);
}
}
}Text Transform Options
| Value | Input | Output |
|---|---|---|
none | Paris | Paris |
uppercase | Paris | PARIS |
lowercase | Paris | paris |
Next Steps
- Custom Map Styling — Full style customization
- Change Layer Color — Dynamic color changes
- Building Color by Zoom — Zoom-dependent styling
Tip: Uppercase labels look great on maps at low zoom levels (country/state names), while default casing is better at street level where readability matters more.