vtmap_gl 5.0.0-dev.3 copy "vtmap_gl: ^5.0.0-dev.3" to clipboard
vtmap_gl: ^5.0.0-dev.3 copied to clipboard

A Flutter plugin for integrating Mapbox Maps inside a Flutter application on Android, iOS and web platfroms.

example/lib/main.dart

import 'dart:async' show unawaited;

import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:vtmap_gl/vtmap_gl.dart';

// Page system
import 'page.dart';

// Basics examples
import 'examples/basics/full_map_example.dart';
import 'examples/basics/multi_style_switch.dart';
import 'examples/layers/various_sources.dart';
import 'examples/basics/get_map_state.dart';
import 'examples/basics/gps_location_page.dart';

// Camera examples
import 'examples/camera/camera_controls_example.dart';
import 'examples/camera/camera_bounds_example.dart';

// Interaction examples
import 'examples/interaction/map_controls_example.dart';
import 'examples/interaction/map_gestures_example.dart';
import 'examples/interaction/hover_effect_example.dart';

// Annotations examples
import 'examples/annotations/annotations_example.dart';
import 'examples/annotations/annotation_order_example.dart';
import 'examples/annotations/annotation_properties_example.dart';
import 'examples/annotations/custom_marker.dart';
import 'examples/annotations/edit_annotation_animated.dart';
import 'examples/annotations/edit_annotation_draggable.dart';

// Layers examples
import 'examples/layers/circle_layer_example.dart';
import 'examples/layers/cluster_properties_example.dart';
import 'examples/layers/fill_layer_example.dart';
import 'examples/layers/line_layer_example.dart';
import 'examples/layers/symbol_layer_example.dart';
import 'examples/layers/edit_style_layer_animated.dart';
import 'examples/layers/edit_style_layer_draggable.dart';

// Advanced examples
import 'examples/advanced/offline_regions.dart';
import 'examples/advanced/pmtiles.dart';
import 'examples/advanced/translucent_full_map.dart';
import 'examples/advanced/map_snapshot.dart';

void main() {
  if (kIsWeb) {
    print(
      'Running with WASM: $kIsWasm, in ${kReleaseMode
          ? "release"
          : kProfileMode
          ? "profile"
          : "debug"} mode',
    );
  }

  runApp(const MapLibreExampleApp());
}

class MapLibreExampleApp extends StatelessWidget {
  const MapLibreExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MapLibre Examples',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF1976D2),
          brightness: Brightness.light,
        ),
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF1976D2),
          brightness: Brightness.dark,
        ),
      ),
      themeMode: ThemeMode.system,
      home: const MapsDemo(),
    );
  }
}

final List<ExamplePage> _allPages = <ExamplePage>[
  // Basics
  const FullMapExample(),
  const MultiStyleSwitchPage(),
  const VariousSources(),
  const GpsLocationPage(),
  const GetMapInfoPage(),

  // Camera
  const CameraControlsExample(),
  const CameraBoundsExample(),

  // Interaction
  const MapControlsExample(),
  const MapGesturesExample(),
  if (kIsWeb) const HoverEffectExample(),

  // Annotations
  const AnnotationsExample(),
  const AnnotationPropertiesExample(),
  const AnnotationOrderExample(),
  const CustomMarkerPage(),
  const EditAnnotationAnimatedExample(),
  const EditAnnotationDraggableExample(),

  // Layers
  const SymbolLayerExample(),
  const CircleLayerExample(),
  const ClusterPropertiesExample(),
  const FillLayerExample(),
  const LineLayerExample(),
  const EditStyleLayerAnimatedExample(),
  const EditStyleLayerDraggableExample(),

  // Advanced
  const PMTilesPage(),
  // Offline regions are Android/iOS only — MapLibre GL JS has no offline API.
  if (!kIsWeb) const OfflineRegionsPage(),
  const TranslucentFullMapPage(),
  const MapSnapshotPage(),
];

class MapsDemo extends StatefulWidget {
  const MapsDemo({super.key});

  @override
  State<MapsDemo> createState() => _MapsDemoState();
}

class _MapsDemoState extends State<MapsDemo> {
  @override
  void initState() {
    super.initState();
    unawaited(initHybridComposition());
  }

  /// Determine the android version of the phone and turn off HybridComposition
  /// on older sdk versions to improve performance for these
  ///
  /// !!! Hybrid composition is currently broken do no use !!!
  Future<void> initHybridComposition() async {
    if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
      final androidInfo = await DeviceInfoPlugin().androidInfo;
      final sdkVersion = androidInfo.version.sdkInt;
      if (sdkVersion >= 29) {
        VTMap.useHybridComposition = true;
      } else {
        VTMap.useHybridComposition = false;
      }
    }
  }

  Future<void> _pushPage(BuildContext context, ExamplePage page) async {
    if (!kIsWeb && page.needsLocationPermission) {
      final location = Location();
      final hasPermissions = await location.hasPermission();
      if (hasPermissions != PermissionStatus.granted) {
        await location.requestPermission();
      }
    }
    if (context.mounted) {
      Navigator.of(context).push(
        MaterialPageRoute<void>(
          builder:
              (_) =>
                  Scaffold(appBar: AppBar(title: Text(page.title)), body: page),
        ),
      );
    }
  }

  Map<ExampleCategory, List<ExamplePage>> _groupByCategory() {
    final grouped = <ExampleCategory, List<ExamplePage>>{};
    for (final page in _allPages) {
      grouped.putIfAbsent(page.category, () => []).add(page);
    }
    return grouped;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final groupedPages = _groupByCategory();

    return Scaffold(
      body: CustomScrollView(
        slivers: [
          const SliverAppBar.large(
            title: Text('MapLibre Examples'),
            floating: true,
            snap: true,
          ),
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.only(
                left: 16.0,
                right: 16.0,
                bottom: 16.0,
              ),
              child: Card(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Icon(
                            Icons.info_outline,
                            color: theme.colorScheme.primary,
                          ),
                          const SizedBox(width: 12),
                          Expanded(
                            child: Text(
                              'Explore ${_allPages.length} interactive examples',
                              style: theme.textTheme.titleMedium?.copyWith(
                                fontWeight: FontWeight.w600,
                              ),
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 8),
                      Text(
                        'Learn how to use MapLibre GL with Flutter through categorized examples.',
                        style: theme.textTheme.bodyMedium?.copyWith(
                          color: theme.colorScheme.onSurfaceVariant,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate((context, index) {
              const categories = ExampleCategory.values;
              if (index >= categories.length) {
                // About tile at the end
                return const Padding(
                  padding: EdgeInsets.symmetric(
                    horizontal: 16.0,
                    vertical: 8.0,
                  ),
                  child: AboutListTile(
                    icon: Icon(Icons.info),
                    applicationName: "MapLibre GL Flutter",
                    aboutBoxChildren: [
                      Text(
                        'MapLibre GL Flutter is an open-source Flutter plugin for embedding interactive maps using the MapLibre GL Native library.',
                      ),
                      SizedBox(height: 8),
                      Text(
                        'This example app showcases various features and capabilities of the MapLibre GL Flutter plugin through interactive examples.',
                      ),
                    ],
                  ),
                );
              }

              final category = categories[index];
              final pages = groupedPages[category] ?? [];

              if (pages.isEmpty) return const SizedBox.shrink();

              return Padding(
                padding: const EdgeInsets.symmetric(
                  horizontal: 16.0,
                  vertical: 4.0,
                ),
                child: Card(
                  clipBehavior: Clip.antiAlias,
                  child: ExpansionTile(
                    leading: Icon(
                      category.icon,
                      color: theme.colorScheme.primary,
                    ),
                    title: Text(
                      category.label,
                      style: theme.textTheme.titleMedium?.copyWith(
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    subtitle: Text('${pages.length} examples'),
                    children:
                        pages
                            .map(
                              (page) => ListTile(
                                leading: page.leading,
                                title: Text(page.title),
                                trailing: const Icon(Icons.chevron_right),
                                onTap: () => _pushPage(context, page),
                              ),
                            )
                            .toList(),
                  ),
                ),
              );
            }, childCount: ExampleCategory.values.length + 1),
          ),
          const SliverPadding(padding: EdgeInsets.only(bottom: 16)),
        ],
      ),
    );
  }
}
7
likes
140
points
206
downloads

Documentation

API reference

Publisher

verified publisherviettelmaps.vn

Weekly Downloads

A Flutter plugin for integrating Mapbox Maps inside a Flutter application on Android, iOS and web platfroms.

License

BSD-2-Clause (license)

Dependencies

flutter, vtmap_gl_platform_interface

More

Packages that depend on vtmap_gl

Packages that implement vtmap_gl