问题:ViewPager中的Fragment onResume()在片段实际可见之前被激发。
例如,我有2个带有ViewPager和FragmentPagerAdapter的片段。第二个片段仅对授权用户可用,我需要在片段可见时要求用户登录(使用警告对话框)。
但是,当第一个片段可见时,ViewPager创建第二个片段,以便缓存第二个碎片,并在用户开始滑动时使其可见。
因此,onResume()事件在第二个片段可见之前很久就被激发了。这就是为什么我试图找到一个事件,当第二个片段变得可见时,该事件会触发,以便在适当的时候显示对话框。
如何做到这一点?
当视图寻呼机中的片段显示在屏幕上供用户查看时,我试图启动计时器时遇到了这个问题。
计时器总是在用户看到片段之前启动。这是因为片段中的onResume()方法在我们看到片段之前被调用。
我的解决方案是检查onResume()方法。当片段8是视图页面的当前片段时,我想调用某个方法“foo()”。
@Override
public void onResume() {
super.onResume();
if(viewPager.getCurrentItem() == 8){
foo();
//Your code here. Executed when fragment is seen by user.
}
}
希望这有帮助。我经常看到这个问题。这似乎是我见过的最简单的解决方案。其他很多都与较低的API等不兼容。
一种简单的实现方法是在进入片段之前检查用户是否已登录。
在MainActivity中,您可以在onNavigationItemSelected方法中执行类似的操作。
case R.id.nav_profile_side:
if (User_is_logged_in) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new FragmentProfile())
.commit();
}else {
ShowLoginOrRegisterDialog(fragmentManager);
}
break;
然而,如果您使用的是导航抽屉,尽管我们没有转到ProfileFragment,但抽屉中的选择将更改为Profile。
要将选择重置为当前选择,请运行以下代码
navigationView.getMenu().getItem(0).setChecked(true);
更新:Android支持库(rev 11)最终修复了用户可见提示问题,现在如果您将支持库用于片段,那么您可以安全地使用getUserVisibleHint()或重写setUserVisibleHint()来捕获gorn的答案所描述的更改。
UPDATE 1 getUserVisibleHint()有一个小问题。默认情况下,该值为true。
// Hint provided by the app that this fragment is currently visible to the user.
boolean mUserVisibleHint = true;
因此,在调用setUserVisibleHint()之前尝试使用它可能会出现问题。作为解决方法,您可以像这样在onCreate方法中设置值。
public void onCreate(@Nullable Bundle savedInstanceState) {
setUserVisibleHint(false);
过时的答案:
在大多数使用情况下,ViewPager一次只显示一个页面,但如果您在Android支持库r11之前的版本中使用FragmentStatePagerAdapter,则预缓存的片段也会处于“可见”状态(实际上不可见)。
我覆盖:
public class MyFragment extends Fragment {
@Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (visible) {
// ...
}
}
// ...
}
为了捕获片段的焦点状态,我认为这是最适合的“可见性”状态,因为ViewPager中只有一个片段可以将其菜单项与父活动的项放在一起。
我在使用FragmentStatePagerAdapters和3个选项卡时遇到了同样的问题。每当单击第一个选项卡时,我必须显示一个Dilaog,并在单击其他选项卡时隐藏它。
单独重写setUserVisibleHint()无助于查找当前可见片段。
从第三个选项卡单击时----->第一个选项卡。第二个片段和第一个片段触发了两次。我将其与isResumed()方法结合使用。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isVisible = isVisibleToUser;
// Make sure that fragment is currently visible
if (!isVisible && isResumed()) {
// Call code when Fragment not visible
} else if (isVisible && isResumed()) {
// Call code when Fragment becomes visible.
}
}