保留上一个碎片的视图焦点

4
假设在片段A中有5个视图(1、2、3、4、5),每个视图都可以聚焦。如果当前的焦点在片段A的第3个视图上,并单击该视图加载一个新片段,比如片段B。
现在,如果我按下返回按钮,是否有办法自动保持焦点在片段A的第3个视图上?
注意:我已将这些片段添加到后退堆栈中。但我的片段包含回收器视图。单击回收器视图的项目会加载另一个片段,按下返回键后,主活动获取默认焦点。 我可以通过实现片段的onBackPressListener() 方法来实现对回收器视图的第一项进行聚焦。但我不知道如何保留以前片段上的焦点。
3个回答

1

对于那些仍在寻找解决方案的人,我尝试了许多方法,但这个(Kotlin)对我来说是最好的:

Image

片段A

1- 在FRAGMENT A的onStop()中阻止片段a后代的焦点性,以避免活动在BACK时将焦点给予随机按钮。

override fun onStop() {
    println("**onStop")
    (view as ViewGroup?)?.descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
    super.onStop()
}

2- 制作一个lambda函数来处理简历上的一些事情

private var doOnResume: (() -> Unit?)? = null

3- 设置片段转换

   // 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- 我正在使用Leanback RowSupportFragment,当您请求将焦点设置到其VerticalGridView时,它会自动将焦点设置为最后一个项目。

listFragment.setOnContentClickedListener {
        gotoFragment {
            listFragment.verticalGridView.requestFocus()
        }
    }

注意,你可以将焦点放在任何你想要的视图上

   private fun onPlayButtonClicked() {
    binding.playBTN.setOnClickListener {button->
        gotoFragment {
            button.requestFocus()
        }

    }

}

5- 在onResume中调用您的Lambda函数

   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()
}

0

您可以随时将这些片段添加到Fragment Manager的backstack中。


感谢您的回复,请检查更新后的问题。 - Nishan Khadka
如果你想保持焦点,你可以在生命周期方法onResume()中做一些操作,我觉得。 - ʌɐɥqıɐʌ

0
如果您在片段A的顶部使用“添加到返回堆栈”添加片段,则按下返回按钮时它将恢复到上次聚焦的项目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接