ViewPager在首个Fragment加载完成后调用setUserVisibleHint方法

44
在我的应用程序中,我有一个ViewPager,其中包含许多带有Fragment的可滑动选项卡。 我使用setUserVisibleHint方法来检测Fragment何时出现在屏幕上。 当用户在选项卡之间切换时,这很有效,但是在第一次加载时不起作用。 必须向左滑动然后返回到第一个Fragment,因为setUserVisibleHint方法在onCreateView方法之前调用才能运行该方法中的代码。
您有什么想法,如何在第一个Fragment可见后运行此代码? ViewPager中是否有一种方法或其他方法可以解决此问题?

当我尝试做类似的事情(检测viewpager中哪个片段是当前可见页面)时,我遇到了完全相同的问题。我尝试的每个解决方案都是一个hack,而且从来没有完全正确。 - Karakuri
6个回答

66

你不能(也不应该)依赖 setUserVisibleHint 来达到这个效果。相反,你应该使用一个 ViewPager.OnPageChangeListener 来获取当页面变为可见时的回调。例如:

viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        // do your work
    } 
});

注意: 如果您不需要监听所有回调,可以使用 ViewPager.SimpleOnPageChangeListener

更新

setOnPageChangeListener 方法现在已过时,请改用 addOnPageChangeListener

viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        // do your work
    } 
});

如果您想在片段更改时重新创建ActionBar菜单,应该像@paul所说的那样在OnPageChangeListener上实现它。 - savepopulation
谢谢。有时候onCreateView和setUserVisibleHint会从其他地方调用...这个方法确保在两者都被调用后再执行。 - ilovett
12
保罗:我该如何在第一次使用时让第一页正常工作? - Arjun Mathew Dan
1
使用 addOnPageChangeListener 替代 setOnPageChangeListener。https://dev59.com/dl0Z5IYBdhLWcg3w8kP3#30867886 - CrandellWS
1
同意这个对于第一页加载根本不起作用。 - AngryDuck

4
以下方法适用于我:
请创建一个像这样的全局视图:
View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {
        //inflate view layout
        view =inflater.inflate(R.layout.your_fragment, container, false);

        // return view
        return view;
    }

使用这个

 @Override
        public void setUserVisibleHint(boolean isUserVisible)
        {
            super.setUserVisibleHint(isUserVisible);
           // when fragment visible to user and view is not null then enter here.
                if (isUserVisible && view != null)
                {
                   onResume();
                }

        }

在OnResume方法中

@Override
         public void onResume() { 
         super.onResume();   
            if (!getUserVisibleHint()) {
            return;
          }
      //do your stuff here
   }

为什么要踩?如果有人发现任何问题,请让我知道。 - Rahul
可能是因为使用了全局变量? - Jose_GD
@Jose_GD 全局变量有什么问题吗? - Rahul
请查看此评论:https://dev59.com/LGkw5IYBdhLWcg3wmruH#bKygEYcBWogLw_1beoMM - Coli

3
您需要在根活动/片段的onCreateView方法中手动调用mViewPagerListener.onPageSelected(0);

0

我不太明白你需要什么,但是你可以通过调用ViewPager.getCurrentItem来检测当前片段的页面,它会返回一个整数。

希望能有所帮助。

祝好运。


-1

嗯,这只是一个变通方法,也许更好的方法是设置OnPageChangeListener,但对我来说它有效。任务是确定当前片段在创建时是否可见。您可以使用菜单来完成此操作。在您的片段中:

 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true); // set current fragment has its own options menu
    } 

和这个

 @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
     ...

            if(isMenuVisible()) { // menu should be visible if current fragment is visible right now
                setUserVisibleHint(true); // manually set value to true
            }
     ...
    return view;

也许有人会发现它有用。这对我很有效。


-6
我检查了您的问题,但是我发现在调用setUserVisibleHint方法之前,onCreateView方法已经被调用了。
enter code here

因为 setUserVisibleHint 方法在 onCreateView 方法之前被调用。

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