[Android] Accessibility: create an accessible SeekBar

Nicolas Pomepuy git at videolan.org
Fri Jun 3 11:30:22 UTC 2022


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Jun  1 09:20:41 2022 +0200| [5faed077617033b31537a223730c9343596db7f0] | committer: Nicolas Pomepuy

Accessibility: create an accessible SeekBar

> https://code.videolan.org/videolan/vlc-android/commit/5faed077617033b31537a223730c9343596db7f0
---

 .../resources/src/main/res/values/strings.xml      |  1 +
 .../org/videolan/vlc/gui/view/AccessibleSeekBar.kt | 71 ++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/application/resources/src/main/res/values/strings.xml b/application/resources/src/main/res/values/strings.xml
index 7cbce2d3e..e29f7236f 100644
--- a/application/resources/src/main/res/values/strings.xml
+++ b/application/resources/src/main/res/values/strings.xml
@@ -1017,6 +1017,7 @@
     <string name="downloaded">Downloaded</string>
     <string name="not_downloaded">Not downloaded</string>
     <string name="downloading">Downloading</string>
+    <string name="talkback_out_of">%s out of %s</string>
 
 
 </resources>
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/view/AccessibleSeekBar.kt b/application/vlc-android/src/org/videolan/vlc/gui/view/AccessibleSeekBar.kt
new file mode 100644
index 000000000..7f963ba6a
--- /dev/null
+++ b/application/vlc-android/src/org/videolan/vlc/gui/view/AccessibleSeekBar.kt
@@ -0,0 +1,71 @@
+package org.videolan.vlc.gui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.util.Log
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import androidx.appcompat.widget.AppCompatSeekBar
+import org.videolan.resources.BuildConfig
+import org.videolan.vlc.R
+import org.videolan.vlc.gui.helpers.TalkbackUtil
+
+class AccessibleSeekBar : AppCompatSeekBar {
+
+    private val customAccessibilityDelegate = object : View.AccessibilityDelegate() {
+        var force = false
+            set(value) {
+                field = value
+                if( value) sendAccessibilityEventUnchecked(this at AccessibleSeekBar, AccessibilityEvent.obtain().apply { eventType = AccessibilityEvent.TYPE_VIEW_SELECTED })
+            }
+
+
+        /**
+         * If the slider changes, it won't send the AccessibilityEvent TYPE_WINDOW_CONTENT_CHANGED
+         * because it reads the percentages, so in that way it will read the sliderText.
+         * On Android 10 and 9, the view got selected when it changes, so the TYPE_VIEW_SELECTED
+         * event is controlled.
+         *
+         * @param host the view selected
+         * @param event the accessibility event to send
+         */
+        override fun sendAccessibilityEventUnchecked(host: View?, event: AccessibilityEvent) {
+            if (BuildConfig.DEBUG) Log.d(this::class.java.simpleName, "sendAccessibilityEventUnchecked: ${event.eventType}")
+            this at AccessibleSeekBar.contentDescription = context.getString(R.string.talkback_out_of, TalkbackUtil.millisToString(context, progress.toLong()), TalkbackUtil.millisToString(context, max.toLong()) )
+            if (event.eventType != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                    && event.eventType != AccessibilityEvent.TYPE_VIEW_SELECTED) {
+                super.sendAccessibilityEventUnchecked(host, event)
+            } else if (force) {
+                super.sendAccessibilityEventUnchecked(host, event)
+                force = false
+            }
+        }
+
+    }
+
+    constructor(context: Context) : super(context) {
+        initialize()
+    }
+
+    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
+        initialize()
+    }
+
+    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
+        initialize()
+    }
+
+    private fun initialize() {
+        accessibilityDelegate = customAccessibilityDelegate
+    }
+
+    fun forceAccessibilityUpdate() {
+        customAccessibilityDelegate.force = true
+    }
+
+
+
+
+
+
+}
\ No newline at end of file



More information about the Android mailing list