最近,我的团队面临一个问题,当我们点击一个按钮切换到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
答案 0 :(得分:0)
我找到了一个解决方案,将setPrimaryItem()
作为适当的时间滚动回来,下面是关键代码:
@Override
public void setPrimaryItem(..., int position, ...) {
if (position == 2) {
ViewPager.scrollTo(0, 0);
}
}
整个解决方案都在github演示项目中。 仍然,我相信我可以找到最好的地方向后滚动如果只有我控制下的源代码。
如果您有更好的解决方案或我犯了一些错误,请提前指出。