Let\'s say I have a custom ViewGroup which is focusable and has some child views which are focusable as well (A custom vertical menu for Android set-top-boxes which should react
I have the similar problem. In our android TV application we wanna select the last focused position of our custom menu (it is custom vertical LinearLayout).
Your should override method addFocusables(views: ArrayList
. This method is called when ViewRootImpl searches all available focusable views. Flags FOCUS_AFTER_DESCENDANTS and FOCUS_BEFORE_DESCENDANTS are only determine position of insertion parent view into focusable views. In case of FOCUS_BEFORE_DESCENDANTS your custom view will be added before your child. In case of FOCUS_AFTER_DESCENDANTS your custom view will be added after your child.
The logic of overriding is to add only your custom view in the list, when your didn't have focused child before.
override fun addFocusables(views: ArrayList, direction: Int, focusableMode: Int) {
// if we did have focused child before, we must add only parent view
// otherwise our child already has focus, and we don't wont to change focus behavior
if (focusedChild == null) {
views.add(this)
} else {
super.addFocusables(views, direction, focusableMode)
}
}
You also must override requestFocus(direction: Int, previouslyFocusedRect: Rect)
because you mast pass focus into you child or decide that your cannot do it.
override fun requestFocus(direction: Int, previouslyFocusedRect: Rect): Boolean =
getViewToFocus()?.requestFocus() ?: false
In this example getViewToFocus() returns the child which I want to be focused or null if we don't have any child
private fun getViewToFocus() =
when {
lastSelectedPos in 0..childCount -> getChildAt(lastSelectedPos)
isNotEmpty() -> getChildAt(0)
else -> null
}
I use Kotlin in examples, but your can use java as well. Enjoy!