getItem方法被调用两次,导致FragmentPagerAdapter中的tab1和tab2都被执行。

4

我有一个带有三个不同片段的滑动选项卡。在FragmentPagerAdapter中的getItem方法被调用两次。我的第一个选项卡加载本地数据,并且与接下来的两个选项卡(选项卡2、选项卡3)具有不同的布局。选项卡2和选项卡3从服务器获取数据并相应地加载。

我的问题是,加载第一次时getItem被调用两次,这会导致选项卡1和选项卡2都被执行。尽管选项卡1只包含本地数据,但由于两次调用,选项卡2被执行并从服务器获取数据。

我不想在选项卡1中执行选项卡2及其功能等。

getItem()代码如下:

@Override public Fragment getItem(int position) { 
    Fragment fragment = null; 
    switch (position) { 
        case 0: fragment = new CommentFragment(); break; 
        case 1: fragment = new AllPostFragment(); break; 
        case 2: fragment = new TodayFragment(); break; 
    } 
    return fragment; 
}

所以,我正在寻找解决方案。如果你能帮忙的话,请给我一些指导。

你能分享一下代码吗? - playmaker420
@Override public Fragment getItem(int position) { Fragment fragment = null; switch (mViewPager.getCurrentItem()) { case 0: fragment = new CommentFragment(); break; case 1: fragment = new AllPostFragment(); break; case 2: fragment = new TodayFragment(); break; } return fragment; }这是我的getItem方法。CommentFragment没有与服务器的交互。但是allPostFragement从服务器获取数据。因此,第一次匹配位置0和1的情况都符合,并执行AllPostFragment并开始从服务器获取数据。 - debug.error
从OP的评论中添加了代码 - Manuel Allenspach
3个回答

12
在ViewPager中,有一个限制,即您的ViewPager将加载多少个屏幕(片段)。 您可以通过调用ViewPagers setOffscreenPageLimit方法来设置此限制。
但是,如果您检查 ViewPagers代码,它会告诉您必须至少加载1个屏幕外页面:
private static final int DEFAULT_OFFSCREEN_PAGES = 1;

public void setOffscreenPageLimit(int limit) {
    if (limit < DEFAULT_OFFSCREEN_PAGES) {
        Log.w(TAG, "Requested offscreen page limit " + limit 
            + " too small; defaulting to " + DEFAULT_OFFSCREEN_PAGES);
        limit = DEFAULT_OFFSCREEN_PAGES;
    }
    // ...
}

底线是:抱歉,我认为您不能仅加载当前片段。
编辑:但是,如果您想在Fragments中仅在用户查看时加载网络数据,则可以执行以下操作:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // Fetch data or something...
    }
}

你的建议听起来不错。这种方法可能有效。我会尝试并告诉你结果。谢谢! - debug.error
这正是我想要的。太棒了解决方案。我不知道这种方法。我花了将近3-4天时间。尝试了许多不同的方法来修复它。setUserVisibleHint方法简单地解决了我的问题。太棒了!非常感谢。 - debug.error

0

当一个标签页中有两个片段时,通常两个片段都会启动并“并行”运行。这是正常的行为。您可以使用某种EventBus或类似的方式手动控制片段的生命周期。


感谢您的回复。是的,两个片段都在同时运行。实际上这是我的问题所在。我不想在第一次加载时从服务器获取Tab2中的数据。我已经看到getItem被调用了两次,并且我已经根据位置在片段之间使用了SWITCH_CASE。而且在第一次CASE匹配为位置0和位置1。虽然Tab1可见,但在Tab2中调用了从服务器获取数据的方法。我会查看您提到的内容。谢谢。 - debug.error
你可以触发一个事件,例如:不要在onCreate / 其他地方调用服务器,而是调用等待第二个选项卡被选择的回调函数。 - webo80
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { // 获取数据或者其他操作... } }这个方法解决了我的问题。vilpe89的答案完美地起作用了。 - debug.error

0

是的。在每个片段中调用此方法,并在其上调用您的方法等:

  override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if(isVisibleToUser)
            loadData() 
    }
  • 不要在第一句话中写它!

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