ViewPager setCurrentItem和dataSetChanged依次导致即将到来的片段无法显示

时间:2016-12-18 10:22:03

标签: android android-fragments android-viewpager

最近,我的团队面临一个问题,当我们点击一​​个按钮切换到ViewPager中的另一个页面时,该页面的片段由于某种原因最初是一个虚拟片段,因此我们将其替换为实际片段。

首先,当点击按钮时,我们调用setCurrentItem()切换到目标页面。

private void showTTGTab() {
    mFragmentVp.setCurrentItem(2, false);
}

setCurrentItem()会让ViewPager重新调用onPageSelected()来通知页面的移动,这就是我们将虚拟片段替换为实际片段的地方。

@Override
public void onPageSelected(int position) {
    if (position == 2) onTTGSelect();
}

private void onTTGSelect() {
    if (mActualFramgnet == null) {
        mActualFramgnet = new my actual fragment();
        replaceToTTGFragment();
    }
}

private void replaceToTTGFragment() {
    mAdapter.removeFragment(my dummy fragment instance);

    mAdapter.addFragment(my actual fragment, 2);

    mAdapter.notifyDataSetChanged();
}

ViewPager现在显示为空白,无需显示任何内容。

我们本地化ViewPager的源代码,在onLayout上打印定位消息,dataSetChanged()之后的最后结算位置是这样的:

Positioning #0 f=NewsFragment{42408810 #1} left=-1080 width=1080 currentScrollX=2160
Positioning #1 f=MeFragment{42408f70 #3} left=1080 width=1080 currentScrollX=2160
Positioning #2 f=TTGFragment{4242a610 #2} left=0 width=1080 currentScrollX=2160

Note : logs were modified and customized.

我们看到ViewPager的scrollX是2160(每个片段宽度为1080),我们的片段都没有进入其可见区域,这导致没有任何显示。

我们在setCurrentItem()之后追踪并弄清楚它是scrollToItem()滚动 x 到2160,并且随后的布局将#2片段作为主要项目来填充x = 0位置滚动到最后一个setCurrentItem()希望它滚动到的项目。

更改的数据集是否可以实现刚调用的setCurrentItem,并在定位后滚动回0,0?

我发布了我的演示来帮助理解这个问题,请看一下:

https://github.com/vince-styling/viewpager-concurrent-datasetchange

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,将setPrimaryItem()作为适当的时间滚动回来,下面是关键代码:

@Override
public void setPrimaryItem(..., int position, ...) {
    if (position == 2) {
        ViewPager.scrollTo(0, 0);
    }
}

整个解决方案都在github演示项目中。 仍然,我相信我可以找到最好的地方向后滚动如果只有我控制下的源代码。

如果您有更好的解决方案或我犯了一些错误,请提前指出。