IllegalStateException异常:应用程序的PagerAdapter改变了适配器的内容,而无需调用PagerAdapter#notifyDataSetChanged [英] IllegalStateException: The application's PagerAdapter changed the adapter's content without calling PagerAdapter#notifyDataSetChanged

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

问题描述

我使用了 ViewPager 例如用动作条从Android文档的>

不幸的是,当我叫 addTab 方法,但以下情况除外应用程序崩溃:

  

IllegalStateException异常:应用程序的PagerAdapter改   适配器的内容,而无需调用PagerAdapter#notifyDataSetChanged!   预计适​​配器项目数0,发现1。

这是 FragmentPagerAdapter code:

 公共静态类TabsAdapter扩展FragmentPagerAdapter
            实现ActionBar.TabListener,ViewPager.OnPageChangeListener {
        私人最终语境mContext;
        私人最终动作条mActionBar;
        私人最终ViewPager mViewPager;
        私人最终的ArrayList< TabInfo> mTabs =新的ArrayList< TabInfo>();

        静态final类TabInfo {
            私人最终类别<> CLSS;
            私人最终捆绑的args;

            TabInfo(类<> _class,捆绑_args){
                CLSS = _class;
                的args = _args;
            }
        }

        公共TabsAdapter(活动活动,ViewPager寻呼机){
            超级(activity.getFragmentManager());
            mContext =活动;
            mActionBar = activity.getActionBar();
            mViewPager =寻呼机;
            mViewPager.setAdapter(本);
            mViewPager.setOnPageChangeListener(本);
        }

        公共无效addTab(ActionBar.Tab选项卡,类<> CLSS,捆绑参数){
            TabInfo信息=新TabInfo(CLSS,参数);
            tab.setTag(信息);
            tab.setTabListener(本);
            mTabs.add(信息);
            mActionBar.addTab(标签);
            notifyDataSetChanged();
        }

        @覆盖
        公众诠释getCount将(){
            返回mTabs.size();
        }

        @覆盖
        公共片段的getItem(INT位置){
            TabInfo信息= mTab​​s.get(位置);
            返回Fragment.instantiate(mContext,info.clss.getName(),info.args);
        }

        @覆盖
        公共无效onPageScrolled(INT位置,浮positionOffset,诠释positionOffsetPixels){
        }

        @覆盖
        公共无效onPageSelected(INT位置){
            mActionBar.setSelectedNavigationItem(位置);
        }

        @覆盖
        公共无效onPageScrollStateChanged(INT状态){
        }

        @覆盖
        公共无效onTabSelected(TAB键,FragmentTransaction英尺){
            对象标记= tab.getTag();
            的for(int i = 0; I< mTab​​s.size();我++){
                如果(mTabs.get(ⅰ)==标签){
                    mViewPager.setCurrentItem(ⅰ);
                }
            }
        }

        @覆盖
        公共无效onTabUnselected(TAB键,FragmentTransaction英尺){
        }

        @覆盖
        公共无效onTabReselected(TAB键,FragmentTransaction英尺){
        }
    }
}
 

我不会改变我的适配器在我的code的任何其他部分,我打电话从主线程的 addTab 法, addTab 方法结束通过调用 notifyDataSetChanged 。由于文档建议做:

  

PagerAdapter支持数据集的变化。数据集的改变必须发生在   主线程必须通过调用notifyDataSetChanged结束()   类似于从BaseAdapter衍生适配器视图适配器。

解决方案

我有一个很难让我的 ViewPager 工作。最后,它似乎在文档中的例子是错误的。

addTab 方法应该如下:

 公共无效addTab(TAB键,类<> CLSS,捆绑参数){
        TabInfo信息=新TabInfo(CLSS,参数);
        tab.setTag(信息);
        tab.setTabListener(本);
        mTabs.add(信息);
        notifyDataSetChanged();
        mActionBar.addTab(标签);
    }
 

注意最后三个操作的顺序。在最初的例子, notifyDataSetChanged mActionBar.addTab 函数之后被调用。

不幸的是,只要您拨打 addTab 动作条,添加的第一个选项卡中自动选择。正因为如此,在 onTabSelected 事件被触发,并尝试检索页面,它trhows的 IllegalStateException异常,因为它注意到预期的项目数和实际一个之间的差异。

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

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

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

This is the FragmentPagerAdapter code:

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) {
        }
    }
}

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 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.

解决方案

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

The addTab method should be as follows:

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);
    }

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

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 trhows the IllegalStateException because it notices a discrepancy between the expected item count and the actual one.

这篇关于IllegalStateException异常:应用程序的PagerAdapter改变了适配器的内容,而无需调用PagerAdapter#notifyDataSetChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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