问题:在片段实际可见之前,会触发 ViewPager
中的片段 onResume()
.
例如,我有2个片段 ViewPager
和 FragmentPagerAdapter
. 第二个片段仅供授权用户使用,我需要让用户在片段可见时登录(使用警告对话框) .
但是,当第一个片段可见时, ViewPager
会创建第二个片段,以便缓存第二个片段,并在用户开始滑动时使其可见 .
因此, onResume()
事件在第二个片段变为可见之前就被触发了 . 那个's why I'm试图找到一个事件,当第二个片段变得可见时,该事件会在适当的时刻显示一个对话框 .
如何才能做到这一点?
21 回答
为此覆盖Fragment.onHiddenChanged() .
覆盖
FragmentPagerAdapter
子类中的setPrimaryItem()
. 我使用这种方法,效果很好 .另一个解决方案posted here overriding setPrimaryItem in the pageradapter by kris larson几乎对我有用 . 但是每种设置都会多次调用此方法 . 此外,我从片段中的视图等获得了NPE,因为在调用此方法的前几次没有准备好 . 通过以下更改,这对我有用:
我遇到过同样的问题 .
ViewPager
执行其他片段生命周期事件,我无法改变该行为 . 我使用片段和可用的动画编写了一个简单的寻呼机 . SimplePagerUPDATE :Android支持库(第11版)终于fixed the user visible hint issue,现在如果您使用片段支持库,那么您可以安全地使用
getUserVisibleHint()
或覆盖setUserVisibleHint()
来捕获gorn的答案所描述的更改 .UPDATE 1 这是
getUserVisibleHint()
的一个小问题 . 默认情况下,此值为true
.因此,在调用
setUserVisibleHint()
之前尝试使用它时可能会出现问题 . 作为一种解决方法,您可以像这样在onCreate
方法中设置值 .过时的答案:
在大多数用例中,
ViewPager
一次只显示一个页面,但如果在Android Support Library pre-r11
中使用FragmentStatePagerAdapter
,则预缓存的片段也会置于"visible"状态(实际上不可见) .我覆盖:
捕获片段的焦点状态,我认为这是最适合“可见性”的状态,因为ViewPager中只有一个片段实际上可以将其菜单项与父活动的项目放在一起 .
要检测
ViewPager
中的Fragment
可见,我确定 only usingsetUserVisibleHint
是不够的 .这是我的检查片段可见的解决方案,第一次启动viewpager时不可见,在页面之间切换,转到另一个活动/片段/背景/前景
EXPLANATION 你可以仔细检查下面的logcat然后我想你可能知道为什么这个解决方案会起作用
First launch
Go to page2
Go to page3
Go to background:
Go to foreground
DEMO project here
希望它有所帮助
我们有一个MVP的特例,其中片段需要通知演示者视图已变为可见,并且演示者由Dagger在
fragment.onAttach()
中注入 .setUserVisibleHint()
是不够的,我们已经检测到需要解决的3种不同情况(提及onAttach()
以便您知道演示者何时可用):我们只希望可见性提示一次到达演示者,所以我们这样做:
在片段内添加以下代码
我用过它,它有效!
这似乎可以恢复您期望的正常行为 . 它可以很好地按下主页键离开应用程序,然后重新进入应用程序 .
onResume()
不会连续两次调用 .setUserVisibleHint()
有时会被调用 beforeonCreateView()
,有时会导致麻烦 .要解决这个问题,您需要检查
isResumed()
以及setUserVisibleHint()
方法 . 但在这种情况下,我意识到setUserVisibleHint()
被称为 only 如果Fragment被恢复并且可见,而不是在创建时 .因此,如果您想在Fragment为
visible
时更新某些内容,请将更新功能放在onCreate()
和setUserVisibleHint()
中:UPDATE: 我仍然意识到
myUIUpdate()
有时被调用两次,原因是,如果你有3个标签并且这个代码在第二个标签上,当你第一个打开第一个标签时,第二个标签也会被创建,即使它不可见而且myUIUpdate()
被调用 . 然后当您滑动到第二个选项卡时,myUIUpdate()
从if (visible && isResumed())
被调用,因此,myUIUpdate()
可能会在一秒钟内被调用两次 .另一个问题是
setUserVisibleHint
中的!visible
被调用1)当你离开片段屏幕时2)在它创建之前,当你第一次切换到片段屏幕时 .Solution:
Explanation:
fragmentResume
,fragmentVisible
:确认onCreateView()
中的myUIUpdate()
是仅在片段创建且可见时调用,而不是在恢复时调用 . 当您处于第一个选项卡时,它也解决了问题,即使它不可见,也会创建第二个选项卡 . 这解决了这个问题,并在onCreate
时检查片段屏幕是否可见 .fragmentOnCreated
:确保片段不可见,并且在第一次创建片段时不会调用 . 所以现在这个if子句只有在你滑出片段时才被调用 .Update 您可以将所有这些代码放在
BaseFragment
code like this并覆盖方法 .请注意,在活动/片段停止时不会调用
setUserVisibleHint(false)
. 你仍然需要检查启动/停止正确register/unregister
任何听众/等 .此外,如果您的片段以不可见状态开始,您将获得
setUserVisibleHint(false)
;你不想在那里unregister
,因为在那种情况下你从未注册过 .这是使用
onPageChangeListener
的另一种方式:我发现
onCreateOptionsMenu
和onPrepareOptionsMenu
方法仅在片段真正可见的情况下调用 . 我找不到任何行为与此类似的方法,我也试过OnPageChangeListener
但它不适用于这种情况,例如,我需要在onCreate
方法中初始化的变量 .因此,这两种方法可以用作此问题的解决方法,特别适用于小型和短期工作 .
我认为,这是更好的解决方案,但不是最好的解决方案 . 我将使用它,但同时等待更好的解决方案 .
问候 .
您可以通过覆盖
Fragment
中的setUserVisibleHint
来执行以下操作:使用
FragmentStatePagerAdapters
和3个选项卡时遇到了同样的问题 . 每当点击第一个标签时我都必须显示Dilaog,并在点击其他标签时隐藏它 .单独覆盖
setUserVisibleHint()
并没有帮助找到当前可见的片段 .从第3个选项卡单击----->第1个选项卡时 . 它为第二个片段和第一个片段触发了两次 . 我将它与isResumed()方法结合起来 .
当我试图在viewpager中的片段在屏幕上供用户查看时,我试图触发计时器时遇到了这个问题 .
计时器始终在用户看到片段之前启动 . 这是因为在我们可以看到片段之前调用片段中的
onResume()
方法 .我的解决方案是检查
onResume()
方法 . 当片段8是视图寻呼机当前片段时,我想调用某个方法'foo()' .希望这可以帮助 . 我已经看到这个问题出现了很多 . 这似乎是我见过的最简单的解决方案 . 许多其他人与较低的API等不兼容 .
Detecting by focused view!
这对我有用
我重写了相关FragmentStatePagerAdapter的Count方法,并让它返回总计数减去要隐藏的页数:
因此,如果最初将3个片段添加到ViewPager中,并且只有前2个才会显示,直到满足某些条件,则通过将TrimmedPages设置为1来覆盖页面计数,它应该只显示前两个页面 .
这对于最后的页面非常有用,但对于开头或中间的页面来说它们确实没什么用处(尽管有很多方法可以做到这一点) .
试试这个,这对我有用: