ste*_*wpf 5 android focus onresume android-lifecycle
在我Fragment的一个s 中,我正在注册OnFocusChangeListener一个EditTextin onResume():
override fun onResume() {
super.onResume()
editText.setOnFocusChangeListener {
// do something here
}
}
Run Code Online (Sandbox Code Playgroud)
我正在注册侦听器,onResume()因为如果我将它设置在较早的生命周期方法中,它将在每次配置更改时触发。将其设置为onResume()确保在注册侦听器之前已经恢复配置更改之前存在的焦点,因此在配置更改/焦点恢复后侦听器不会自动触发。
现在我担心我注册这个监听器可能太晚了。所以我的问题是:在onResume()执行之前或执行时,用户交互是否已经导致对元素的关注?(这意味着,我会失去这个焦点事件,因为我在 期间设置了监听器onResume())。或者更一般的:onResume()在执行时是否已经可以进行用户交互?Fragment文档说onResume():
当片段对用户可见并正在运行时调用。
“对用户可见”是什么意思很清楚,但“主动运行”究竟是什么意思?这是否已经意味着接受用户输入?还是在onResume()完成后首先接受用户输入?
焦点恢复是在 Activity 中完成的onRestoreInstanceState(),这与 Fragment 恢复其自己的 View 状态(在 Fragment 中onViewStateRestored())时分开完成。
根据onRestoreInstanceState()文档,它在 Activity 之间调用onStart()(onPostCreate()它在 Fragment 获取回调onResume()之前运行)。onPostResume()onPostResume()onResume()
onResume()这意味着您是正确的,因为在调用该方法之前正确设置焦点之前,片段级别没有可用的回调。
话虽这么说,是的,用户可以在片段达到恢复状态之前与片段进行交互。例如,ViewPager2(以及使用时的 ViewPager 1 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)将未选定的片段(即不在屏幕中间的片段)保留在状态中STARTED。通过多点触控的功能,用户可以稍微拖动页面,然后用另一根手指点击部分可见的视图。setMaxLifecycle()如果您自己使用Lifecycle.State.STARTED(这就是那些人在幕后所做的事情),您会看到相同的行为- 片段是可交互的,但不能恢复。
但是,在大多数情况下,如果您不使用上述任何 API,则 Fragment 生命周期通常会与 Activity 生命周期匹配。根据ActivityThread 源代码,活动确实以相同的handleStartActivity()方法运行其更新。
应该注意的是,每次 Activity 被销毁时,当 View 从 Activity 中删除时,您都会收到一个回调(这总是会失去 View 的焦点)OnFocusChangeListener。这种情况发生在保存状态之后,视图的焦点状态实际上并没有丢失,这只是您已经需要在回调中处理的事情,通常通过在保存状态后检查并忽略焦点丢失并检查是否手动删除/ 替换Fragment(即通过执行操作)。hasFocusfalseisStateSaved()isRemoving()replace()
鉴于您已经必须在侦听器中具有逻辑来避免处理hasFocus销毁后的错误事件,处理获得焦点的 100% 正确情况将涉及将您自己的焦点状态(即特定视图的 true 或 false)保存在您保存的实例状态,并且仅在hasFocus与您已保存的状态发生变化时才运行您的逻辑。这意味着您可以在片段生命周期的早期恢复保存的实例状态(例如,在onViewStateRestored()片段提供的方法中)并在其中添加侦听器。然后,您的逻辑可以安全地忽略具有相同焦点的回调:
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
// Restore your member variable of focus
focused = savedInstanceState?.getBoolean("HAS_FOCUS", false) ?: false
editText.setOnFocusChangeListener { _, hasFocus ->
if (focused == hasFocus) {
// ignore
return
}
focused = hasFocus
if (hasFocus) {
// We gained focus
} else if (!isStateSaved() && !isRemoving()) {
// We lost focus
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
330 次 |
| 最近记录: |