Skip to content

Commit e389af9

Browse files
pengdevgithub-actions[bot]
authored andcommitted
Add setContentDescription API to AttributionPlugin for accessibility (#4896)
Fixes https://mapbox.atlassian.net/browse/MAPSAND-2183 * Add setContentDescription() method to AttributionPlugin and AttributionView interfaces with default implementations for backward compatibility * Implement setContentDescription() in AttributionPluginImpl and AttributionViewImpl to support programmatic accessibility content description setting * Set default content description "Powered by Mapbox Maps" for attribution button to improve screen reader experience cc @mapbox/maps-android GitOrigin-RevId: 223903afed0e3e84ca2b266e112d301324dda800
1 parent 6dd56cb commit e389af9

File tree

11 files changed

+88
-0
lines changed

11 files changed

+88
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
Mapbox welcomes participation and contributions from everyone.
44

55
# main
6+
# 11.14.0-rc.1
7+
## Features ✨ and improvements 🏁
8+
* Added `setContentDescription()` method to `AttributionPlugin` and `AttributionView` interfaces to programmatically set accessibility content description for the attribution button.
69

710
# 11.14.0-beta.1 July 02, 2025
811

app/src/main/java/com/mapbox/maps/testapp/examples/CustomAttributionActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class CustomAttributionActivity : AppCompatActivity() {
4646
checkedTextView.setOnClickListener { checkedTextView.toggle() }
4747
}
4848
val attributionPlugin = binding.mapView.attribution
49+
// set custom content description for the attribution plugin.
50+
attributionPlugin.setContentDescription("Show Mapbox Attributions")
4951
binding.customAttributionFab.setOnClickListener {
5052
Toast.makeText(this, R.string.custom_attribution_custom, Toast.LENGTH_LONG).show()
5153
val config = AttributionParserConfig(

plugin-attribution/api/plugin-attribution.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public final class com/mapbox/maps/plugin/attribution/AttributionViewImpl : andr
1616
public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;I)V
1717
public synthetic fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
1818
public fun setAttributionMargins (IIII)V
19+
public fun setContentDescription (Ljava/lang/CharSequence;)V
1920
public fun setEnable (Z)V
2021
public fun setGravity (I)V
2122
public fun setIconColor (I)V

plugin-attribution/src/main/java/com/mapbox/maps/plugin/attribution/AttributionPluginImpl.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ internal class AttributionPluginImpl(
5858
dialogManager.showAttribution(mapAttributionDelegate)
5959
}
6060

61+
/**
62+
* Set the content description for the attribution view.
63+
*
64+
* @param contentDescription the content description text
65+
*/
66+
override fun setContentDescription(contentDescription: CharSequence?) {
67+
if (::attributionView.isInitialized) {
68+
attributionView.setContentDescription(contentDescription)
69+
}
70+
}
71+
6172
/**
6273
* Set a custom AttributionDialogManager that is invoked when the attribution view is clicked.
6374
*/

plugin-attribution/src/main/java/com/mapbox/maps/plugin/attribution/AttributionViewImpl.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class AttributionViewImpl @JvmOverloads constructor(
2727
ViewGroup.LayoutParams.WRAP_CONTENT,
2828
ViewGroup.LayoutParams.WRAP_CONTENT
2929
)
30+
// Set default content description for accessibility
31+
contentDescription = context.getString(R.string.mapbox_attributionsDialogTitle)
3032
}
3133

3234
/**
@@ -79,6 +81,15 @@ class AttributionViewImpl @JvmOverloads constructor(
7981
}
8082
}
8183

84+
/**
85+
* Set the content description for accessibility.
86+
*
87+
* @param contentDescription the content description text
88+
*/
89+
override fun setContentDescription(contentDescription: CharSequence?) {
90+
super<AppCompatImageView>.setContentDescription(contentDescription)
91+
}
92+
8293
/**
8394
* Set an [View.OnClickListener] to AttributionView
8495
*/

plugin-attribution/src/test/java/com/mapbox/maps/plugin/attribution/AttributionPluginImplImplTest.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,17 @@ class AttributionPluginImplImplTest {
105105
fun mapAttributionDelegate() {
106106
assertEquals(mapAttributionDelegate, attributionPlugin.getMapAttributionDelegate())
107107
}
108+
109+
@Test
110+
fun setContentDescription() {
111+
val customDescription = "Custom attribution content description"
112+
attributionPlugin.setContentDescription(customDescription)
113+
verify { attributionView.setContentDescription(customDescription) }
114+
}
115+
116+
@Test
117+
fun setContentDescriptionWithNull() {
118+
attributionPlugin.setContentDescription(null)
119+
verify { attributionView.setContentDescription(null) }
120+
}
108121
}

plugin-attribution/src/test/java/com/mapbox/maps/plugin/attribution/AttributionViewImplTest.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,24 @@ class AttributionViewImplTest {
7272
attributionView.setViewOnClickListener(mockk())
7373
assertTrue(attributionView.hasOnClickListeners())
7474
}
75+
76+
@Test
77+
fun setContentDescription() {
78+
val customDescription = "Custom attribution description"
79+
attributionView.setContentDescription(customDescription)
80+
assertEquals(customDescription, attributionView.contentDescription)
81+
}
82+
83+
@Test
84+
fun setContentDescriptionWithNull() {
85+
attributionView.setContentDescription(null)
86+
assertNull(attributionView.contentDescription)
87+
}
88+
89+
@Test
90+
fun defaultContentDescription() {
91+
// Default content description should be set from string resource
92+
assertNotNull(attributionView.contentDescription)
93+
assertTrue(attributionView.contentDescription.isNotEmpty())
94+
}
7595
}

sdk-base/api/Release/metalava.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,12 +1748,14 @@ package com.mapbox.maps.plugin.attribution {
17481748

17491749
public interface AttributionPlugin extends com.mapbox.maps.plugin.ViewPlugin com.mapbox.maps.plugin.attribution.generated.AttributionSettingsInterface com.mapbox.maps.plugin.LifecyclePlugin {
17501750
method public com.mapbox.maps.plugin.delegates.MapAttributionDelegate getMapAttributionDelegate();
1751+
method public default void setContentDescription(CharSequence? contentDescription);
17511752
method public void setCustomAttributionDialogManager(com.mapbox.maps.plugin.attribution.AttributionDialogManager dialogManager);
17521753
}
17531754

17541755
public interface AttributionView {
17551756
method public void requestLayout();
17561757
method public void setAttributionMargins(@Px int left, @Px int top, @Px int right, @Px int bottom);
1758+
method public default void setContentDescription(CharSequence? contentDescription);
17571759
method public void setEnable(boolean enabled);
17581760
method public void setGravity(int gravity);
17591761
method public void setIconColor(@ColorInt int color);

sdk-base/api/sdk-base.api

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,7 @@ public final class com/mapbox/maps/plugin/attribution/AttributionParserConfig {
17901790

17911791
public abstract interface class com/mapbox/maps/plugin/attribution/AttributionPlugin : com/mapbox/maps/plugin/LifecyclePlugin, com/mapbox/maps/plugin/ViewPlugin, com/mapbox/maps/plugin/attribution/generated/AttributionSettingsInterface {
17921792
public abstract fun getMapAttributionDelegate ()Lcom/mapbox/maps/plugin/delegates/MapAttributionDelegate;
1793+
public abstract fun setContentDescription (Ljava/lang/CharSequence;)V
17931794
public abstract fun setCustomAttributionDialogManager (Lcom/mapbox/maps/plugin/attribution/AttributionDialogManager;)V
17941795
}
17951796

@@ -1800,17 +1801,23 @@ public final class com/mapbox/maps/plugin/attribution/AttributionPlugin$DefaultI
18001801
public static fun onPluginView (Lcom/mapbox/maps/plugin/attribution/AttributionPlugin;Landroid/view/View;)V
18011802
public static fun onStart (Lcom/mapbox/maps/plugin/attribution/AttributionPlugin;)V
18021803
public static fun onStop (Lcom/mapbox/maps/plugin/attribution/AttributionPlugin;)V
1804+
public static fun setContentDescription (Lcom/mapbox/maps/plugin/attribution/AttributionPlugin;Ljava/lang/CharSequence;)V
18031805
}
18041806

18051807
public abstract interface class com/mapbox/maps/plugin/attribution/AttributionView {
18061808
public abstract fun requestLayout ()V
18071809
public abstract fun setAttributionMargins (IIII)V
1810+
public abstract fun setContentDescription (Ljava/lang/CharSequence;)V
18081811
public abstract fun setEnable (Z)V
18091812
public abstract fun setGravity (I)V
18101813
public abstract fun setIconColor (I)V
18111814
public abstract fun setViewOnClickListener (Landroid/view/View$OnClickListener;)V
18121815
}
18131816

1817+
public final class com/mapbox/maps/plugin/attribution/AttributionView$DefaultImpls {
1818+
public static fun setContentDescription (Lcom/mapbox/maps/plugin/attribution/AttributionView;Ljava/lang/CharSequence;)V
1819+
}
1820+
18141821
public abstract interface class com/mapbox/maps/plugin/attribution/OnAttributionClickListener {
18151822
public abstract fun onAttributionClick ()V
18161823
}

sdk-base/src/main/java/com/mapbox/maps/plugin/attribution/AttributionPlugin.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ interface AttributionPlugin : ViewPlugin, LifecyclePlugin, AttributionSettingsIn
1515
*/
1616
fun setCustomAttributionDialogManager(dialogManager: AttributionDialogManager)
1717

18+
/**
19+
* Set the content description for the attribution view.
20+
*
21+
* @param contentDescription the content description text
22+
*/
23+
fun setContentDescription(contentDescription: CharSequence?) {
24+
// Default empty implementation for backward compatibility
25+
}
26+
1827
/**
1928
* Get the instance of MapAttributionDelegate
2029
*/

0 commit comments

Comments
 (0)