IllegalStateException:应用程序的 PagerAdapter 在没有调用 PagerAdapter#notifyDataSetChanged 的​​情况下更改了适配器的内容 [英] IllegalStateException: The application's PagerAdapter changed the adapter's content without calling PagerAdapter#notifyDataSetChanged

查看:39
本文介绍了IllegalStateException:应用程序的 PagerAdapter 在没有调用 PagerAdapter#notifyDataSetChanged 的​​情况下更改了适配器的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ViewPager 示例和从 Android 文档 这里.

I'm using the ViewPager example with ActionBar tabs taken from the Android documentation here.

不幸的是,当我调用 addTab 方法时,应用程序崩溃并出现以下异常:

Unfortunately, as soon as I call the addTab method, the application crashes with the following exception:

IllegalStateException:应用程序的 PagerAdapter 更改了适配器的内容而不调用 PagerAdapter#notifyDataSetChanged!预期适配器项计数 0,找到 1.

IllegalStateException: The application's PagerAdapter changed the adapter's content without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count 0, found 1.

这是 FragmentPagerAdapter 代码:

public static class TabsAdapter extends FragmentPagerAdapter
            implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
        private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

        static final class TabInfo {
            private final Class<?> clss;
            private final Bundle args;

            TabInfo(Class<?> _class, Bundle _args) {
                clss = _class;
                args = _args;
            }
        }

        public TabsAdapter(Activity activity, ViewPager pager) {
            super(activity.getFragmentManager());
            mContext = activity;
            mActionBar = activity.getActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }

        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
            TabInfo info = new TabInfo(clss, args);
            tab.setTag(info);
            tab.setTabListener(this);
            mTabs.add(info);
            mActionBar.addTab(tab);
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return mTabs.size();
        }

        @Override
        public Fragment getItem(int position) {
            TabInfo info = mTabs.get(position);
            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            mActionBar.setSelectedNavigationItem(position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            Object tag = tab.getTag();
            for (int i=0; i<mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
        }

        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
        }
    }
}

我没有在代码的任何其他部分修改我的适配器,而是从主线程调用 addTab 方法,addTab 方法以调用 notifyDataSetChanged.正如文档建议的那样:

I'm not modifying my adapter in any other part of my code and I'm calling the addTab method from the main thread, the addTab method ends with a call to notifyDataSetChanged. As the documentation recommends to do:

PagerAdapter 支持数据集更改.数据集更改必须发生在主线程并且必须以调用 notifyDataSetChanged() 结束类似于从 BaseAdapter 派生的 AdapterView 适配器.

PagerAdapter supports data set changes. Data set changes must occur on the main thread and must end with a call to notifyDataSetChanged() similar to AdapterView adapters derived from BaseAdapter.

推荐答案

我很难让我的 ViewPager 正常工作.最后,好像是文档中的例子是错误的.

I had a hard time making my ViewPager working. At the end, it seems that the example in the documentation is wrong.

addTab方法应该如下:

public void addTab(Tab tab, Class<?> clss, Bundle args) {
        TabInfo info = new TabInfo(clss, args);
        tab.setTag(info);
        tab.setTabListener(this);
        mTabs.add(info);
        notifyDataSetChanged();
        mActionBar.addTab(tab);
    }

注意最后三个操作的顺序.在原始示例中,在 mActionBar.addTab 函数之后调用了 notifyDataSetChanged.

Notice the order of the last three operations. In the original example, notifyDataSetChanged was called after the mActionBar.addTab function.

不幸的是,只要您在 ActionBar 上调用 addTab,您添加的第一个选项卡就会被自动选中.因此,onTabSelected 事件被触发,并在尝试检索页面时抛出 IllegalStateException,因为它注意到预期项目数与实际项目数之间存在差异.

Unfortunately, as soon as you call the addTab on the ActionBar, the first tab you add is automatically selected. Because of this, the onTabSelected event is fired and while trying to retrieve the page, it throws the IllegalStateException because it notices a discrepancy between the expected item count and the actual one.

这篇关于IllegalStateException:应用程序的 PagerAdapter 在没有调用 PagerAdapter#notifyDataSetChanged 的​​情况下更改了适配器的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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