Suppose I have 5 views (1,2,3,4,5) in a fragment A and each view is focusable. Then, if the current focus in fragment A is at view 3 and clicking that view loads a new fragment, let's say fragment B.
Now, is there any way that when I press back button, the focus is retained on view 3 of fragment A automatically?
Note: I have added those fragments in the backstack. But my fragment contains recycler views. Clicking on an item of recycler view will load another fragment and on back press the Main Activity gets the default focus.
I can implement focusing on recycler view's first item by implementing fragment's onBackPressListener()
method. But I have no idea on how to retain focus on a fragment as it was before.
for those who still searching for the solution, I tested many ways but this one was the best for me (Kotlin): Image
Fragment A
1- block fragment a descendant focusability in onStop() in FRAGMENT A to avoid giving focus to a random button by the activity on BACK
override fun onStop() {
println("**onStop")
(view as ViewGroup?)?.descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
super.onStop()
}
2- make a lambda to do some things on a resume
private var doOnResume: (() -> Unit?)? = null
3- setup the fragment transition
// add a lambda here too
private fun gotoFragment(onResume: () -> Unit) {
//initialize doOnResume here
doOnResume = onResume
(requireActivity() as MainActivity).apply {
supportFragmentManager.commit {
replace(R.id.app_container, DetailsFragment())
addToBackStack(null)
}
}
}
4- I am using leanback RowSupportFragment it automatically set focus t the last item when you request focus to its verticalGridView
listFragment.setOnContentClickedListener {
gotoFragment {
listFragment.verticalGridView.requestFocus()
}
}
note you are able to give focus to any view you want
private fun onPlayButtonClicked() {
binding.playBTN.setOnClickListener {button->
gotoFragment {
button.requestFocus()
}
}
}
5- call your lambda in the onResume
override fun onResume() {
//unblock descendantFocusability again
(view as ViewGroup?)?.descendantFocusability = ViewGroup.FOCUS_AFTER_DESCENDANTS
//avoid crashing app when gridview is not initialized yet or any other reason
try {
doOnResume?.invoke()
} catch (_:Exception) {
}
super.onResume()
}