1
0
Fork 0

Fixes #1186: Add AccessibilityActions to quick action sheet's handle

Adding the 'click' action allows the user to activate the button with a
default action (double tap in TalkBack). This is instead of
conditionally setting up a click listener if TalkBack is enabled. This
is a more generalized solution that accomodates other ATs besides
TalkBack.

Adding an expand or collapse action also tells TalkBack what the current
state of the sheet is, and reports it to the user. So they will
initially hear "collapsed, quick actions, button". When they double tap,
they will hear "expanded". Adding those actions also allows TalkBack and
other AT users to explicitly call those actions on that element with a
menu or a gesture binding.
master
Eitan Isaacson 2019-03-27 11:14:36 -07:00 committed by Sawyer Blatz
parent c807f84b98
commit f9ea856b34
1 changed files with 52 additions and 13 deletions

View File

@ -15,7 +15,9 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import mozilla.components.browser.toolbar.BrowserToolbar
import org.mozilla.fenix.R
import android.animation.ValueAnimator
import android.view.accessibility.AccessibilityManager
import android.os.Bundle
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import org.mozilla.fenix.utils.Settings
@ -39,23 +41,13 @@ class QuickActionSheet @JvmOverloads constructor(
val handle = findViewById<AppCompatImageButton>(R.id.quick_action_sheet_handle)
val linearLayout = findViewById<LinearLayout>(R.id.quick_action_sheet)
val quickActionSheetBehavior = BottomSheetBehavior.from(linearLayout.parent as View) as QuickActionSheetBehavior
val accessibilityManager = context
.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
if (accessibilityManager.isTouchExplorationEnabled) {
linearLayout.setOnClickListener {
quickActionSheetBehavior.state = when (quickActionSheetBehavior.state) {
BottomSheetBehavior.STATE_EXPANDED -> BottomSheetBehavior.STATE_COLLAPSED
else -> BottomSheetBehavior.STATE_EXPANDED
}
}
return
}
handle.setOnClickListener {
bounceSheet(quickActionSheetBehavior)
}
handle.setAccessibilityDelegate(HandleAccessibilityDelegate(quickActionSheetBehavior))
val settings = Settings.getInstance(context)
if (settings.shouldAutoBounceQuickActionSheet) {
settings.incrementAutomaticBounceQuickActionSheetCount()
@ -87,6 +79,53 @@ class QuickActionSheet @JvmOverloads constructor(
}
}
class HandleAccessibilityDelegate(
private val quickActionSheetBehavior: QuickActionSheetBehavior
) : View.AccessibilityDelegate() {
private var finalState = BottomSheetBehavior.STATE_COLLAPSED
get() = when (quickActionSheetBehavior.state) {
BottomSheetBehavior.STATE_EXPANDED,
BottomSheetBehavior.STATE_HIDDEN,
BottomSheetBehavior.STATE_COLLAPSED -> {
quickActionSheetBehavior.state
}
else -> field
}
set(value) {
field = value
quickActionSheetBehavior.state = value
}
override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
when (action) {
AccessibilityNodeInfo.ACTION_CLICK -> {
finalState = when (quickActionSheetBehavior.state) {
BottomSheetBehavior.STATE_EXPANDED -> BottomSheetBehavior.STATE_COLLAPSED
else -> BottomSheetBehavior.STATE_EXPANDED
}
}
AccessibilityNodeInfo.ACTION_COLLAPSE ->
finalState = BottomSheetBehavior.STATE_COLLAPSED
AccessibilityNodeInfo.ACTION_EXPAND ->
finalState = BottomSheetBehavior.STATE_EXPANDED
else -> return super.performAccessibilityAction(host, action, args)
}
host?.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED)
return true
}
override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfo?) {
super.onInitializeAccessibilityNodeInfo(host, info)
info?.addAction(when (finalState) {
BottomSheetBehavior.STATE_COLLAPSED,
BottomSheetBehavior.STATE_HIDDEN -> AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND
else -> AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE
})
}
}
companion object {
const val demoBounceAnimationLength = 600L
const val bounceAnimationLength = 400L