Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/206.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android ViewPager setCurrentItem在onResume之后不工作_Android_Methods_Android Viewpager_Onresume - Fatal编程技术网

Android ViewPager setCurrentItem在onResume之后不工作

Android ViewPager setCurrentItem在onResume之后不工作,android,methods,android-viewpager,onresume,Android,Methods,Android Viewpager,Onresume,我遇到了一个奇怪的问题,ViewPager的setCurrentItem(position,false)工作得非常好,然后我切换到另一个活动,在我返回到第一个活动后,ViewPager总是在第一个项目上结束。即使我将setCurrentItem添加到onResume方法中,它仍然会忽略它。当我试图将项设置为越界索引时,它甚至不会抛出任何异常。 虽然稍后我调用此方法时,当点击“下一步”按钮时,它的工作方式与预期相同。 对我的代码进行了10次检查,查看是否存在对setCurrentItem(0)或其

我遇到了一个奇怪的问题,
ViewPager
setCurrentItem(position,false)
工作得非常好,然后我切换到另一个活动,在我返回到第一个活动后,
ViewPager
总是在第一个项目上结束。即使我将
setCurrentItem
添加到
onResume
方法中,它仍然会忽略它。当我试图将项设置为越界索引时,它甚至不会抛出任何异常。 虽然稍后我调用此方法时,当点击“下一步”按钮时,它的工作方式与预期相同。
对我的代码进行了10次检查,查看是否存在对
setCurrentItem(0)
或其他任何可能的调用,但它根本不在那里。

我这样做是为了还原当前项目:

@Override
protected void onSaveInstanceState(Bundle outState) {

    if (mViewPager != null) {
        outState.putInt(STATE_PAGE_NO, mViewPager.getCurrentItem());
    }

    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {

    if (savedInstanceState != null) {
        mCurrentPage = savedInstanceState.getInt(STATE_PAGE_NO, 0);
    }

    super.onRestoreInstanceState(savedInstanceState);
}

@Override
protected void onRestart() {
    mViewPager.setCurrentItem(mCurrentPage);
         super.onRestart();
}

我不能确切地回答为什么会发生这种情况,但是如果您将setCurrentItem调用延迟几毫秒,它应该可以工作。我猜这是因为在恢复过程中还没有渲染过程,而ViewPager需要一个或类似的过程

private ViewPager viewPager;

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

        @Override
        public void run() {
            viewPager.setCurrentItem(pos);
        }
    }, 100);
}
更新:故事时间

因此,今天我遇到了一个问题,viewpager忽略了我的setCurrentItem操作,我搜索stackoverflow以寻找解决方案。我发现有人有同样的问题和解决办法;我实施了修复,但它不起作用。哇!返回stackoverflow以否决该错误修复提供程序,然后

是我。我实现了自己的错误非修复,这是我第一次遇到问题时提出的(后来被遗忘)。我现在不得不对自己提供的坏消息投反对票


我最初的“修复”工作的原因不是因为“渲染过程”;问题是寻呼机的内容是由旋转器控制的。微调器和寻呼机状态都在恢复时恢复,因此在下一个事件传播周期中调用了微调器选定的侦听器,这确实重新填充了viewpager-这次使用了不同的默认值。
在初始状态恢复期间删除并重置侦听器修复了该问题

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


更新2:我不能否决我自己的帖子。我想,尊敬的塞普库是唯一剩下的选择。

我找到了一个非常简单的解决方法:

    if (mViewPager.getAdapter() != null)
        mViewPager.setAdapter(null);
    mViewPager.setAdapter(mPagerAdapter);
    mViewPager.setCurrentItem(desiredPos);
如果这不起作用,您可以将其放入处理程序中,但不需要定时延迟:

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                mViewPager.setCurrentItem(desiredPos);
            }
        });

您需要在pager.setAdapter(buildAdapter())之后调用pager.setCurrentItem(activePage)


我有同样的问题,我编辑

@Override
public int getCount() { return NUM_PAGES; }

我将
NUM\u PAGES
设置为1 only。

我在创建活动时遇到了类似的问题。 适配器设置了正确的计数,并且 将适配器设置为后应用了setCurrentItem 然而,ViewPager将返回超出范围的索引。我想在我设置当前项时,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);
        }
    });

这是一个生命周期问题,正如这里的几张海报所指出的。然而,我发现发布
Runnable
的解决方案是不可预测的,而且可能容易出错。这似乎是一种通过将问题发布到未来来忽略问题的方法

我并不是说这是最好的解决方案,但它肯定不使用
Runnable
。我在
片段
中保留了一个单独的整数,该片段具有
查看页面
下一步调用
onResume
时,此整数将保留我们要设置为当前页面的页面。
整数的值可以在任何点设置,因此可以在
碎片事务之前或恢复活动时设置。还要注意,所有成员都是在
onResume()
中设置的,而不是在
onCreateView()中设置的

公共类MyFragment扩展了片段
{
私有视图寻呼机mViewPager;
私人MyPagerAdapter mAdapter;
私人小报;
private int mCurrentItem=0;//用于保留要在onResume()中设置的页面。
@可空
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态)
{
视图=充气机。充气(R.layout.my_布局,容器,假);
mViewPager=(ViewPager)view.findViewById(R.id.my_ViewPager);
mTabLayout=(TabLayout)view.findViewById(R.id.my_TabLayout);
返回视图;
}
@凌驾
恢复时公开作废()
{
super.onResume();
MyActivity MyActivity=(MyActivity)getActivity();
myActivity.getSupportActionBar().setTitle(getString(R.string.my_title));
mAdapter=新的MyPagerAdapter(getChildFragmentManager(),myActivity);
mViewPager.setAdapter(mAdapter);
mViewPager.setOffscreenPageLimit(页面切换、屏幕外页面限制);

mViewPager.setCurrentItem(mCurrentItem);//对于我来说,在设置适配器之后,设置当前项是有效的

viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));

viewPager.setCurrentItem(idx);

pagerSlidingTabStrip.setViewPager(viewPager);// assign viewpager to tabs

当我调用
setCurrentItem()
时,视图即将重新创建。因此,事实上,我为viewpager调用了
setCurrentItem()
,然后系统调用
onCreateView()
,从而创建了一个新的viewpager

这就是为什么我看不到任何更改的原因。这也是为什么
postDelayed()
可能会有所帮助的原因

理论解决方案:推迟调用
setCurrentItem()
直到重新创建视图

实践
public class MyFragment extends Fragment
{
    private ViewPager           mViewPager;
    private MyPagerAdapter      mAdapter;
    private TabLayout           mTabLayout;
    private int                 mCurrentItem = 0; // Used to keep the page we want to set in onResume().

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.my_layout, container, false);
        mViewPager = (ViewPager) view.findViewById(R.id.my_viewpager);
        mTabLayout = (TabLayout) view.findViewById(R.id.my_tablayout);
        return view;
    }

    @Override
    public void onResume()
    {
        super.onResume();

        MyActivity myActivity = (MyActivity) getActivity();
        myActivity.getSupportActionBar().setTitle(getString(R.string.my_title));

        mAdapter = new MyPagerAdapter(getChildFragmentManager(), myActivity);
        mViewPager.setAdapter(mAdapter);
        mViewPager.setOffscreenPageLimit(PagerConstants.OFFSCREEN_PAGE_LIMIT);
        mViewPager.setCurrentItem(mCurrentItem); // <-- Note the use of mCurrentItem here!
        mTabLayout.setupWithViewPager(mViewPager);
    }

    /**
     * Call this at any point before needed, for example before performing a FragmentTransaction.
     */    
    public void setCurrentItem(int currentItem)
    {
        mCurrentItem = currentItem;

        // This should be called in cases where onResume() is not called later,
        // for example if you only want to change the page in the ViewPager
        // when clicking a Button or whatever. Just omit if not needed.
        mViewPager.setCurrentItem(mCurrentItem); 
    }


}
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));

viewPager.setCurrentItem(idx);

pagerSlidingTabStrip.setViewPager(viewPager);// assign viewpager to tabs
notifyDataSetChanged
ViewUtilities.waitForLayout(myViewPager, new Runnable() {
    @Override
    public void run() {
        myViewPager.setCurrentItem(tabIndex , false);
    }
});
public final class ViewUtilities {
    public static void waitForLayout(final View view, final Runnable runnable) {
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //noinspection deprecation
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                runnable.run();
            }
        });
    }
}
removeOnGlobalLayoutListener
       ^^
      ON Global
removeGlobalOnLayoutListener
            ^^
            ON Layout
notifyDataSetChanged()
setCurrentItem()
 if (mViewPager.getAdapter() != null)
    mViewPager.setAdapter(null);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(desiredPos);
class MyActivity : AppCompatActivity() {
    lateinit var mAdapter: MyAdapter
    lateinit var mPager: ViewPager
    // ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.fragment_pager)
        // ...
        mainViewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
        mAdapter = MyAdapter(supportFragmentManager)
        mPager = findViewById(R.id.pager)

        mainViewModel.someData.observe(this, Observer { items ->
            items?.let {
                // first give the data to the adapter
                // this is where the notifyDataSetChanged() happens
                mAdapter.setItems(it) 
                mPager.adapter = mAdapter // assign adapter to pager
                mPager.currentItem = idx // finally set the current page
            }
        })
internal fun setItems(items: List<Item>) {
    this.items = items
    notifyDataSetChanged()
}
lifecycleScope.launch(Dispatchers.Main) {
   val index = 1
   viewPager.setCurrentItem(index)
}
view_pager.doOnPreDraw {
    view_pager.currentItem = 1
}
    if (myXXRecyclerAdapter != null) {
        myXXRecyclerAdapter = new MyXXRecyclerAdapter(myStoredData);
        mRecyclerView.setAdapter(myXXRecyclerAdapter );
        return;
    }