ViewPager中的setCurrentItem不会立即滚动到正确的位置

时间:2012-08-17 15:29:57

标签: android scroll android-viewpager

我使用PagerAdapter。我有很多元素,所以我不会在同一时间加载所有元素。我重新加载适配器,我通过新元素更改旧元素。例如,我有4个元素,当我到达最后一个元素时,我重新加载元素,我调用setCurentItem(1)以便能够在第一个位置显示viewpager。我做了很多测试。我说:

viewPager.setCurrentItem(1,false); //But not scroll, put drastically the new page.
viewPager.setCurrentItem(1);

我试图修改onPageScrollStateChanged(int arg0),我只有3个观点并且总是在中间位置。

if (arg0 == ViewPager.SCROLL_STATE_DRAGGING) {
    if(focusedPage==2) {
        //Modify adapter
        viewPager.setCurrentItem(1,false);   

    }else if(focusedPage==0){
        //Modify adapter
        viewPager.setCurrentItem(1,false);
    } 

我尝试修改onPageSelected(int arg0)

focusedPage=arg0;

使用最后一个示例我立即滚动视图,但始终位于最后一页。 任何人都知道如何滑动。

谢谢

2 个答案:

答案 0 :(得分:44)

我可以更多地了解您想要完成的背景吗?

无论如何,根据我的理解,你试图让“无限”ViewPager从最后一个到第一个,反之亦然(如果我错了,请纠正我)。并且您希望ViewPager转到第一页但滚动 - 而不仅仅是从不知情地出现。

好吧,如果您禁用平滑滚动(第二个参数),那么它将直接转到您想要的页面而没有滚动动作(并且不会“改变”到途中的其他页面),如果您启用平滑滚动然后它将遍历所有视图,因此您将看到它不是下一个视图而是第一个视图。

    /*No swipe animation, and no onPageChanged for the page in the middle*/
    mPager.setCurrentItem(1, false); 

    /*The same as if you do not add the second parameter*/
    mPager.setCurrentItem(1, true);

    /*Your ViewPager scrolls through all the needed views until it arrives at that view.*/
    mPager.setCurrentItem(1);

考虑到这一点,我可以向您推荐的是,您可以尝试在位置0和“最后”添加“虚拟”视图,位置0中的视图与位置“最后 - 1”相同“最后”视图与位置“1”相同。所以你会做一切正常的事情,除了在OnPageChangeListener上,你将检查当前页面是否是位置“0”或“最后”,如果是,你将调用setCurrentItem(“1”,false)或setCurrentItem(“last - 1“,false)取决于你现在的位置。通过这种方式,您将在完成所需内容的同时保持“页面更改”效果。

我希望这可以帮助您解决问题。

注意: 到达新位置后,它可能会有一个滞后的变化,因为它必须加载当前,下一个和最后一个视图的视图(或者如果你在4.0以上,那么它将只加载实际位置)。

<强>更新

如果您更改确定ViewPager内容的列表/数组的内容,则需要致电:

ViewPager mPager = new ViewPager();
mPager.getAdapter().notifyDataSetChanged();  //This notify that you need to recreate the views

/*This is if you want to change the data and then go to a specific position
If you do not do this you will have a very Buggy Behavior*/
new Handler().post(new Runnable() {
@Override
public void run() {
    mPager.setCurrentItem(2); //Where "2" is the position you want to go
    }
});

更新2:

为什么不将所有元素添加到ViewPagerViewPager已经有处理这些案例的优化,在我的情况下,我有很多元素,它就像一个魅力。

另一件事,在你的代码中我看到你每次页面“安定”时都会切换到中间页面。但是你真的没有显示左右视图,为什么你有它们呢?

最后,当您更改数据集时,需要调用上面提到的“notifyDataSetChanged”方法,然后在处理程序中调用“setCurrentItem”方法。如果不这样做,您的应用将无法按预期工作。

更新3:

嗯,我唯一能推荐的是有一个List,你可以不断添加从数据库中添加的新对象,然后只要你继续将对象插入List的末尾就没有问题了。如果你想在中间或开头添加对象,那么你需要调用notifyDataSetChanged,但这会有点慢,因为它会再次生成视图。我们这样做,它工作得很好,我们甚至从服务器下载信息,数据不是本地的(实际上我们将信息添加到列表的结尾和开头)。

如果您对如何实现这一点有任何其他疑问,请不要犹豫。

更新4:

万一有人实际上正在寻找一个循环ViewPager,我添加了一个可以重复使用的proof of concept code。它没有问题,我使用了复杂的视图,但仍然没有任何延迟。

答案 1 :(得分:3)

没有postDelayed它没有用,请尝试使用以下代码:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);