Merge pull request #84 from esensar/fix/home-screen-accessibility
Implement accessibility for HomeScreenGrid
This commit is contained in:
commit
c5ea727398
|
@ -23,6 +23,7 @@ import android.os.Handler
|
|||
import android.provider.Telephony
|
||||
import android.telecom.TelecomManager
|
||||
import android.view.*
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.widget.PopupMenu
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
|
@ -139,6 +140,14 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
home_screen_grid.itemClickListener = {
|
||||
performItemClick(it)
|
||||
}
|
||||
|
||||
home_screen_grid.itemLongClickListener = {
|
||||
performItemLongClick(home_screen_grid.getClickableRect(it).left.toFloat(), it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findFirstEmptyCell(): Rect? {
|
||||
|
@ -241,6 +250,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
refetchLaunchers()
|
||||
}
|
||||
}
|
||||
|
||||
REQUEST_ALLOW_BINDING_WIDGET -> mActionOnCanBindWidget?.invoke(resultCode == Activity.RESULT_OK)
|
||||
REQUEST_CONFIGURE_WIDGET -> mActionOnWidgetConfiguredWidget?.invoke(resultCode == Activity.RESULT_OK)
|
||||
REQUEST_CREATE_SHORTCUT -> {
|
||||
|
@ -403,6 +413,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
window.navigationBarColor = resources.getColor(R.color.semitransparent_navigation)
|
||||
home_screen_grid.fragmentExpanded()
|
||||
home_screen_grid.hideResizeLines()
|
||||
fragment.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
}
|
||||
|
||||
private fun hideFragment(fragment: View) {
|
||||
|
@ -433,12 +444,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
mIgnoreMoveEvents = true
|
||||
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
||||
if (clickedGridItem != null) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
main_holder.performHapticFeedback()
|
||||
}
|
||||
|
||||
val anchorY = home_screen_grid.sideMargins.top + (clickedGridItem.top * home_screen_grid.cellHeight.toFloat())
|
||||
showHomeIconMenu(x, anchorY, clickedGridItem, false)
|
||||
performItemLongClick(x, clickedGridItem)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -450,6 +456,11 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
home_screen_grid.hideResizeLines()
|
||||
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
||||
if (clickedGridItem != null) {
|
||||
performItemClick(clickedGridItem)
|
||||
}
|
||||
}
|
||||
|
||||
private fun performItemClick(clickedGridItem: HomeScreenGridItem) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON) {
|
||||
launchApp(clickedGridItem.packageName, clickedGridItem.activityName)
|
||||
} else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
|
@ -466,6 +477,14 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun performItemLongClick(x: Float, clickedGridItem: HomeScreenGridItem) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
main_holder.performHapticFeedback()
|
||||
}
|
||||
|
||||
val anchorY = home_screen_grid.sideMargins.top + (clickedGridItem.top * home_screen_grid.cellHeight.toFloat())
|
||||
showHomeIconMenu(x, anchorY, clickedGridItem, false)
|
||||
}
|
||||
|
||||
fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) {
|
||||
|
|
|
@ -15,8 +15,12 @@ import android.text.TextUtils
|
|||
import android.util.AttributeSet
|
||||
import android.util.Size
|
||||
import android.util.SizeF
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
import androidx.customview.widget.ExploreByTouchHelper
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.helpers.isSPlus
|
||||
|
@ -58,7 +62,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
|||
val appWidgetHost = MyAppWidgetHost(context, WIDGET_HOST_ID)
|
||||
private val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null
|
||||
var itemLongClickListener: ((HomeScreenGridItem) -> Unit)? = null
|
||||
|
||||
init {
|
||||
ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this))
|
||||
|
||||
textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
color = Color.WHITE
|
||||
textSize = context.resources.getDimension(R.dimen.smaller_text_size)
|
||||
|
@ -706,4 +715,60 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
|||
|
||||
return null
|
||||
}
|
||||
|
||||
private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) {
|
||||
override fun getVirtualViewAt(x: Float, y: Float): Int {
|
||||
val item = isClickingGridItem(x.toInt(), y.toInt())
|
||||
|
||||
return if (item != null) {
|
||||
item.id?.toInt() ?: INVALID_ID
|
||||
} else {
|
||||
INVALID_ID
|
||||
}
|
||||
}
|
||||
|
||||
override fun getVisibleVirtualViews(virtualViewIds: MutableList<Int>?) {
|
||||
val sorted = gridItems.sortedBy { it.top * 100 + it.left }
|
||||
sorted.forEachIndexed { index, homeScreenGridItem ->
|
||||
virtualViewIds?.add(index, homeScreenGridItem.id?.toInt() ?: index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPopulateNodeForVirtualView(virtualViewId: Int, node: AccessibilityNodeInfoCompat) {
|
||||
val item = gridItems.firstOrNull { it.id?.toInt() == virtualViewId } ?: throw IllegalArgumentException("Unknown id")
|
||||
|
||||
node.text = item.title
|
||||
|
||||
val viewLocation = IntArray(2)
|
||||
getLocationOnScreen(viewLocation)
|
||||
|
||||
val viewBounds = getClickableRect(item)
|
||||
val onScreenBounds = Rect(viewBounds)
|
||||
onScreenBounds.offset(viewLocation[0], viewLocation[1])
|
||||
node.setBoundsInScreen(onScreenBounds)
|
||||
node.setBoundsInParent(viewBounds)
|
||||
|
||||
node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK)
|
||||
node.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK)
|
||||
node.setParent(this@HomeScreenGrid)
|
||||
}
|
||||
|
||||
override fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, arguments: Bundle?): Boolean {
|
||||
val item = gridItems.firstOrNull { it.id?.toInt() == virtualViewId } ?: throw IllegalArgumentException("Unknown id")
|
||||
when (action) {
|
||||
AccessibilityNodeInfoCompat.ACTION_CLICK -> itemClickListener?.apply {
|
||||
invoke(item)
|
||||
return true
|
||||
}
|
||||
|
||||
AccessibilityNodeInfoCompat.ACTION_LONG_CLICK -> itemLongClickListener?.apply {
|
||||
invoke(item)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue