屏幕旋转后ViewPager重新实例化项目无序 [英] ViewPager re-instantiates items out of order after screen rotation

查看:136
本文介绍了屏幕旋转后ViewPager重新实例化项目无序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 ViewPager 包含多个列表视图,随着答案的无限viewPager 。这个想法是有类似的谷歌日历应用日视图(其来源似乎是不可用;只有默认的日历应用程序的不过是它使用了 ViewSwitcher ) - 我想让它看起来喜欢的用户可以刷卡无限左右,但实际上有只有3项 ViewPager ,当用户点击页面0或2,我们设定1作为当前页并相应地更新

I'm using a ViewPager that contains several ListViews, with code similar to that in the answer for Infinite ViewPager. The idea is to have something like the day view for the Google Calendar app (whose source seems to be unavailable; only the default calendar app's is but it uses a ViewSwitcher) - I want to make it seem like the user can swipe infinitely left and right, but there are actually only 3 items in the ViewPager, and when the user hits page 0 or 2, we set 1 as the current page and update accordingly.

现在,这一切的作品。然而,奇怪的是,当手机被旋转,并且活动重建(我使用的是避免 configChanges 现在),在应用程序的页面再次实例化,但出来的订购。取而代之的0-> 1> 2的顺序为1-> 0-> 2,这螺丝了在应用程序的页面顺序。

Now, this all works. However, strangely, when the phone is rotated and the activity is rebuilt (I'm avoiding using configChanges for now), the pages in the app are instantiated again, but out of order. Instead of 0->1->2, the order is 1->0->2, and this screws up the order of the pages in the app.

我的片段,在 onActivityCreated()

My Fragment, in onActivityCreated():

mPagerAdapter = new ContinuousPagerAdapter(R.layout.my_listview, this);

// set the adapter
mViewPager = (ViewPager) getView().findViewById(R.id.agendaViewPager);
mViewPager.setOffscreenPageLimit(3);
mViewPager.setOnPageChangeListener(this);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setSaveEnabled(false);
// ...
mViewPager.setCurrentItem(1, false);
loadData();

寻呼机适配器:

import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;

public class ContinuousPagerAdapter extends PagerAdapter {

    OnPageInstantiatedListener pListener;
    ViewPager container;
    int childLayoutResId;

    @SuppressWarnings("unused")
    private ContinuousPagerAdapter() {
    }

    /**
     * @param childLayoutResId Layout resource ID of the children to be inflated
     */
    public ContinuousPagerAdapter(int childLayoutResId, OnPageInstantiatedListener pListener) {
        this.childLayoutResId = childLayoutResId;
        this.pListener = pListener;
    }

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

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(View container, int position) {
        this.container = (ViewPager) container;

        // inflate a new child view
        LayoutInflater li = (LayoutInflater) container.getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        View childView = li.inflate(childLayoutResId, null, false);

        // add it to the view pager and return
        int count = this.container.getChildCount();
        int actualPos = count > position ? position : count;
        this.container.addView(childView, actualPos);
        pListener.onPageInstantiated(actualPos); // sometimes use 0 instead of actualPos, with different but still inconsistent results
        return childView;
    }

    @Override
    public void destroyItem(View container, int position, Object object) {
        ((ViewPager) container).removeViewAt(position);
    }

    public static interface OnPageInstantiatedListener {
        public void onPageInstantiated(int position);
    }

    /**
     * Needed to ensure all the items are instantiated
     */
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    @Override
    public void finishUpdate(View container) {
    }
}

我不明白为什么页面旋转后在1-> 0-> 2阶实例化。我不节能状态无论是。任何见解,这将是有益的。

I don't understand why the pages are instantiated in the 1->0->2 order after rotation. I'm not saving state either. Any insights into this would be helpful.

推荐答案

精心调试应用程序,并通过 ViewPager 来源看后,我发现这个问题。

After meticulously debugging the app and looking through the ViewPager source, I found the problem.

第一次应用程序启动和 mViewPager.setAdapter(mPagerAdapter)被调用时,页面会立即启动和应用程序的工作,因为它应该。但是,当手机旋转时,调用 setAdapter()推迟实例化的页面,因为 getWindowToken()返回null作为窗口还没有准备好。实例化被延迟,直到连的之后 onResume()被称为在某些循环。

The first time the app starts and mViewPager.setAdapter(mPagerAdapter) is called, the pages are instantly initiated and the app works as it should. However, when the phone is rotated, calling setAdapter() postpones instantiating the pages because getWindowToken() returns null as the window is not ready yet. Instantiating is delayed until even after onResume() is called in some loop.

调用 setCurrentItem(1,假)使第一页的主页,并且作为结果,可以在其他网页之前实例化,从而导致在一怪1-> 0-> 2的实例化。

Calling setCurrentItem(1, false) makes the first page the primary page, and as a result it is instantiated before the other pages, resulting in the at-first strange 1->0->2 instantiation.

解决方案?使用处理程序来运行 setCurrentItem()和负载其他页面后,数据被实例化:

The solution? Use a Handler to run the setCurrentItem() and load data after the other pages have been instantiated:

new Handler().post(new Runnable() {
    @Override
    public void run() {
        mViewPager.setCurrentItem(1, false);
        cleanupAndShowData();
    }
});

虽然我通常要避免使用处理程序 S,看来这是迄今为止我发现的唯一选择,是因为自己在添加页面尺蠖。

Though I'd normally want to avoid using Handlers, it seems this is the only option I've found thus far, because the pages themselves are added in a looper.

修改:即使上面有一些问题。最后我打电话 mViewPager.setCurrentItem(1,FALSE)只有在所有页面都被实例化(在 onPageInstantiated () )。

EDIT: Even the above had some issues. I ended up calling mViewPager.setCurrentItem(1, false) only after all pages have been instantiated (in onPageInstantiated()).

这篇关于屏幕旋转后ViewPager重新实例化项目无序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆