onResume后,Android ViewPager setCurrentItem无法正常工作

Mac*_*uta 28 methods android onresume android-viewpager

我有这个奇怪的问题,ViewPager的setCurrentItem(position,false)工作得很好,然后我切换到另一个活动,并且在我回到第一个活动后,ViewPager总是在第一个项目上结束.即使我已将setCurrentItem添加到onResume方法,它仍然会忽略它.当我试图将项目设置为越界索引时,它甚至没有抛出任何异常.虽然稍后当我调用此方法时,单击按钮"next"时,它会按预期工作.检查我的代码10次,以获得对setCurrentItem(0)或smth的任何可能调用,但它根本就没有.

ste*_*efs 65

我无法回答为什么会发生这种情况,但是如果你将setCurrentItem调用延迟几毫秒就可以了.我的猜测是因为在onResume尚未有渲染过程的时候,ViewPager需要一个或类似的东西.

private ViewPager viewPager;

@Override
public void onResume() {
    final int pos = 3;
    viewPager.postDelayed(new Runnable() {

        @Override
        public void run() {
            viewPager.setCurrentItem(pos);
        }
    }, 100);
}
Run Code Online (Sandbox Code Playgroud)

更新:故事时间

所以今天我遇到了viewpager忽略了我的setCurrentItem动作的问题,我搜索了stackoverflow以寻求解决方案.我找到了一个有同样问题和解决方法的人; 我实现了修复,它没有工作.哇!回到stackoverflow来downvote那个faux-fix-provider,并且......

那是我.我实现了我自己的错误的非修复,我第一次偶然发现问题(后来被遗忘).我现在不得不向自己提供不良信息.


我最初的"修复"工作的原因不是因为"渲染过程"; 问题是寻呼机的内容是由微调器控制的.旋转器和寻呼机状态都在onResume上被恢复,因此在下一个事件传播周期中调用了旋转器onItemSelected侦听器,它确实重新填充了viewpager - 这次使用了不同的默认值.
在初始状态恢复期间移除和重置监听器解决了问题.

上面的修复工作是第一次,因为它在onItemSelected事件触发设置了寻呼机的当前位置.后来,它由于某种原因停止工作(可能应用程序变得太慢 - 在我的实现中我没有使用100毫秒,但10毫秒).然后我在清理周期中删除了postDelayed,因为它没有改变已经存在的错误行为.

更新2:我不能低估自己的帖子.我认为,尊贵的seppuku是唯一的选择.

  • 哇,这个故事值得 Netflix 改编 (4认同)

Mar*_*ice 25

我的活动OnCreate中有类似的问题.适配器设置了正确的计数,我在将适配器设置为ViewPager之后应用了setCurrentItem但是将返回索引超出范围.我认为ViewPager在我设置当前项目时没有加载我的所有片段.通过在ViewPager上发布runnable,我能够解决这个问题.这是一个带有一点上下文的例子.

    // Locate the viewpager in activity_main.xml
    final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);

    // Set the ViewPagerAdapter into ViewPager
    viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));

    viewPager.setOffscreenPageLimit(2);

    viewPager.post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(ViewPagerAdapter.CENTER_PAGE);
        }
    });
Run Code Online (Sandbox Code Playgroud)


san*_*791 18

ViewTreeObserver 可用于避免静态延迟。

科特林:

请随意使用 Kotlin 扩展作为简洁的选项。

view_pager.doOnPreDraw {
    view_pager.currentItem = 1
}
Run Code Online (Sandbox Code Playgroud)

请确保您有 gradle 依赖项:实现 'androidx.core:core-ktx:1.3.2' 或更高版本

爪哇

OneShotPreDrawListener.add(view_pager, () -> view_pager.currentItem = 1);
Run Code Online (Sandbox Code Playgroud)


and*_*per 12

I found a very simple workaround for this:

    if (mViewPager.getAdapter() != null)
        mViewPager.setAdapter(null);
    mViewPager.setAdapter(mPagerAdapter);
    mViewPager.setCurrentItem(desiredPos);
Run Code Online (Sandbox Code Playgroud)

And, if that doesn't work, you can put it in a handler, but there's no need for a timed delay:

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                mViewPager.setCurrentItem(desiredPos);
            }
        });
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,第二种方法解决了我的问题. (3认同)

Mar*_* RS 6

Fragmentor中的现代方法是在 的上下文中Activity调用协程中的函数:ViewPager.setcurrentItem(Int)Dispatchers.Main

lifecycleScope.launch(Dispatchers.Main) {
   val index = 1
   viewPager.setCurrentItem(index)
}
Run Code Online (Sandbox Code Playgroud)


pet*_*umo 5

我在代码中有类似的错误,问题是我在更改数据之前设置了位置。

解决办法很简单,事后设置位置并通知数据改变

notifyDataSetChanged()
setCurrentItem()
Run Code Online (Sandbox Code Playgroud)