From 4659963174fa08d0895acd2221a91e9f41ed5dad Mon Sep 17 00:00:00 2001 From: JaffaKetchup Date: Sun, 13 Sep 2026 13:10:46 +0100 Subject: [PATCH] Add improved `SimpleAttributionLayer` Deprecate `SimpleAttributionWidget` --- lib/flutter_map.dart | 9 +- .../{ => v1}/rich/animation.dart | 2 +- .../{ => v1}/rich/source.dart | 0 .../{ => v1}/rich/widget.dart | 0 .../attribution_layer/{ => v1}/simple.dart | 17 +++- .../v2/simple/simple_attribution_layer.dart | 86 +++++++++++++++++++ test/full_coverage_test.dart | 9 +- 7 files changed, 113 insertions(+), 10 deletions(-) rename lib/src/layer/attribution_layer/{ => v1}/rich/animation.dart (98%) rename lib/src/layer/attribution_layer/{ => v1}/rich/source.dart (100%) rename lib/src/layer/attribution_layer/{ => v1}/rich/widget.dart (100%) rename lib/src/layer/attribution_layer/{ => v1}/simple.dart (74%) create mode 100644 lib/src/layer/attribution_layer/v2/simple/simple_attribution_layer.dart diff --git a/lib/flutter_map.dart b/lib/flutter_map.dart index 21fa967b3..626c3f23b 100644 --- a/lib/flutter_map.dart +++ b/lib/flutter_map.dart @@ -23,10 +23,11 @@ export 'package:flutter_map/src/gestures/latlng_tween.dart'; export 'package:flutter_map/src/gestures/map_events.dart'; export 'package:flutter_map/src/gestures/multi_finger_gesture.dart'; export 'package:flutter_map/src/gestures/positioned_tap_detector_2.dart'; -export 'package:flutter_map/src/layer/attribution_layer/rich/animation.dart'; -export 'package:flutter_map/src/layer/attribution_layer/rich/source.dart'; -export 'package:flutter_map/src/layer/attribution_layer/rich/widget.dart'; -export 'package:flutter_map/src/layer/attribution_layer/simple.dart'; +export 'package:flutter_map/src/layer/attribution_layer/v1/rich/animation.dart'; +export 'package:flutter_map/src/layer/attribution_layer/v1/rich/source.dart'; +export 'package:flutter_map/src/layer/attribution_layer/v1/rich/widget.dart'; +export 'package:flutter_map/src/layer/attribution_layer/v1/simple.dart'; +export 'package:flutter_map/src/layer/attribution_layer/v2/simple/simple_attribution_layer.dart'; export 'package:flutter_map/src/layer/circle_layer/circle_layer.dart'; export 'package:flutter_map/src/layer/marker_layer/marker_layer.dart'; export 'package:flutter_map/src/layer/overlay_image_layer/overlay_image_layer.dart'; diff --git a/lib/src/layer/attribution_layer/rich/animation.dart b/lib/src/layer/attribution_layer/v1/rich/animation.dart similarity index 98% rename from lib/src/layer/attribution_layer/rich/animation.dart rename to lib/src/layer/attribution_layer/v1/rich/animation.dart index d45f50e9c..fee85e2df 100644 --- a/lib/src/layer/attribution_layer/rich/animation.dart +++ b/lib/src/layer/attribution_layer/v1/rich/animation.dart @@ -1,5 +1,5 @@ import 'package:flutter/widgets.dart'; -import 'package:flutter_map/src/layer/attribution_layer/rich/widget.dart'; +import 'package:flutter_map/src/layer/attribution_layer/v1/rich/widget.dart'; /// Animation provider interface for a [RichAttributionWidget] /// diff --git a/lib/src/layer/attribution_layer/rich/source.dart b/lib/src/layer/attribution_layer/v1/rich/source.dart similarity index 100% rename from lib/src/layer/attribution_layer/rich/source.dart rename to lib/src/layer/attribution_layer/v1/rich/source.dart diff --git a/lib/src/layer/attribution_layer/rich/widget.dart b/lib/src/layer/attribution_layer/v1/rich/widget.dart similarity index 100% rename from lib/src/layer/attribution_layer/rich/widget.dart rename to lib/src/layer/attribution_layer/v1/rich/widget.dart diff --git a/lib/src/layer/attribution_layer/simple.dart b/lib/src/layer/attribution_layer/v1/simple.dart similarity index 74% rename from lib/src/layer/attribution_layer/simple.dart rename to lib/src/layer/attribution_layer/v1/simple.dart index 1624dd552..afe1acd2d 100644 --- a/lib/src/layer/attribution_layer/simple.dart +++ b/lib/src/layer/attribution_layer/v1/simple.dart @@ -2,6 +2,15 @@ import 'package:flutter/material.dart' show Theme; import 'package:flutter/widgets.dart'; import 'package:flutter_map/flutter_map.dart'; +/// DEPRECATED: Use [SimpleAttributionLayer] instead. +/// +/// The new layer looks very similar to this widget, but does not prefix any +/// text by default and is more flexible. It also does not use Material theming, +/// and may require its background color to be set if the map background is not +/// the intended color. +/// +/// --- +/// /// A simple, classic style, attribution layer /// /// Displayed as a padded translucent [backgroundColor] box with the following @@ -11,7 +20,13 @@ import 'package:flutter_map/flutter_map.dart'; /// /// * [RichAttributionWidget], which is dynamic, supports more customization, /// and has a more complex appearance. -@immutable +@Deprecated('''Use `SimpleAttributionLayer` instead. +The new layer looks very similar to this widget, but does not prefix any text by +default and is more flexible. It also does not use Material theming, and may +require its background color to be set if the map background is not the intended +color. This widget will be removed when flutter_map removes its dependency on +Material in a future breaking release. +''') class SimpleAttributionWidget extends StatelessWidget { /// Attribution text, such as 'OpenStreetMap contributors' final Text source; diff --git a/lib/src/layer/attribution_layer/v2/simple/simple_attribution_layer.dart b/lib/src/layer/attribution_layer/v2/simple/simple_attribution_layer.dart new file mode 100644 index 000000000..c752d33e0 --- /dev/null +++ b/lib/src/layer/attribution_layer/v2/simple/simple_attribution_layer.dart @@ -0,0 +1,86 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/widgets.dart'; + +import 'package:flutter_map/src/map/options/options.dart'; +import 'package:flutter_map/src/map/widget.dart'; + +/// A simple attribution box, which mimics the classic style of attribution. +/// +/// This box is best for short attributions, such as to a single source, where +/// the attribution does not require images. +/// +/// A custom child can be passed to the default constructor, or a prebuilt +/// design intended for a single source with optional hyperlink styling and tap +/// detector can be built using the [SimpleAttributionLayer.singleLink] +/// constructor. +class SimpleAttributionLayer extends StatelessWidget { + /// Color of the box containing the [child]. + /// + /// Defaults to [MapOptions.backgroundColor] if this layer is within a + /// [FlutterMap], or the default light gray background colour otherwise. + final Color? backgroundColor; + + /// Alignment of the box relative to the map widget. + /// + /// Defaults to displaying at the bottom right of the map. + final Alignment alignment; + + /// Widget to display within the box. + final Widget child; + + /// A simple attribution box with [child]. + const SimpleAttributionLayer({ + super.key, + required this.child, + this.backgroundColor, + this.alignment = Alignment.bottomRight, + }); + + /// A simple attribution box which displays one line of text, optionally as + /// in a hyperlink style when [onTap] is set. + SimpleAttributionLayer.singleLink({ + super.key, + required String text, + void Function()? onTap, + TextStyle? textStyle, + bool showFlutterMapPrefix = false, + this.backgroundColor, + this.alignment = Alignment.bottomRight, + }) : child = Text.rich( + TextSpan( + children: [ + if (showFlutterMapPrefix) const TextSpan(text: 'flutter_map | '), + TextSpan( + text: text, + style: textStyle ?? + (onTap == null + ? null + : const TextStyle( + color: Color(0xFF3366CC), + decorationColor: Color(0xFF3366CC), + decoration: TextDecoration.underline, + )), + recognizer: onTap == null + ? null + : (TapGestureRecognizer()..onTap = onTap), + ), + ], + ), + ); + + @override + Widget build(BuildContext context) { + return Align( + alignment: alignment, + child: ColoredBox( + color: backgroundColor ?? + MapOptions.maybeOf(context)?.backgroundColor ?? + const Color(0xFFE0E0E0), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6), + child: child, + ), + ), + ); + } +} diff --git a/test/full_coverage_test.dart b/test/full_coverage_test.dart index 1f422fc07..8f85774ec 100644 --- a/test/full_coverage_test.dart +++ b/test/full_coverage_test.dart @@ -8,10 +8,11 @@ import 'package:flutter_map/src/gestures/map_events.dart'; import 'package:flutter_map/src/gestures/map_interactive_viewer.dart'; import 'package:flutter_map/src/gestures/multi_finger_gesture.dart'; import 'package:flutter_map/src/gestures/positioned_tap_detector_2.dart'; -import 'package:flutter_map/src/layer/attribution_layer/rich/animation.dart'; -import 'package:flutter_map/src/layer/attribution_layer/rich/source.dart'; -import 'package:flutter_map/src/layer/attribution_layer/rich/widget.dart'; -import 'package:flutter_map/src/layer/attribution_layer/simple.dart'; +import 'package:flutter_map/src/layer/attribution_layer/v1/rich/animation.dart'; +import 'package:flutter_map/src/layer/attribution_layer/v1/rich/source.dart'; +import 'package:flutter_map/src/layer/attribution_layer/v1/rich/widget.dart'; +import 'package:flutter_map/src/layer/attribution_layer/v1/simple.dart'; +import 'package:flutter_map/src/layer/attribution_layer/v2/simple/simple_attribution_layer.dart'; import 'package:flutter_map/src/layer/circle_layer/circle_layer.dart'; import 'package:flutter_map/src/layer/marker_layer/marker_layer.dart'; import 'package:flutter_map/src/layer/overlay_image_layer/overlay_image_layer.dart';