FragmentStatePagerAdapter перестает работать после обновления до ADT 22? - программирование
Подтвердить что ты не робот

FragmentStatePagerAdapter перестает работать после обновления до ADT 22?

Я использую FragmentStatePagerAdapter в одном из своих приложений в течение многих месяцев, и он работал безупречно. Недавно я переключился на IntelliJ IDEA и обновился до ADT 22, и теперь Adapter заставляет приложение принудительно закрываться, когда приложение пытается уничтожить вкладки и создавать новые.

При правильной работе Activity загрузит серию вкладок. Пользователь может пронести между ними. Все это работает правильно.

Приложение должно уничтожать эти вкладки и создавать новые, когда пользователь выбирает кнопку в меню. Обычно это работает отлично, но теперь он внезапно перестает работать. Вот код:

/** TabsAdapter - Make Tabs Swipe-Able, Handle Fragments */
public static class TabsAdapter extends FragmentStatePagerAdapter 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;
        }
    } // end TabInfo

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    } // end TabsAdapter

    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();
    } // end addTab

    public void removeTab(ActionBar.Tab tab) {
        mTabs.remove(tab.getTag());
        mActionBar.removeTab(tab);
        notifyDataSetChanged();
    }

    @Override
    public int getItemPosition(Object object) {
        return TabsAdapter.POSITION_NONE;
    }

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

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

    @Override
    public void onPageScrolled(int position, float positionOffest, int postionOffsetPixels){

    } // end onPageScrolled

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

    @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);
            }
        }
    } // end onTabSelected

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

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

    @Override
    public void onPageScrollStateChanged(int arg0) {}

} // end TabsAdapter

Во время onCreate() я вызываю метод, позволю ему CreateTabs1(), и он успешно создает вкладки, и пользователь может пронести по экрану. Это происходит только тогда, когда пейджер пытается уничтожить вкладки и создавать новые, которые теперь не выполняются внезапно, даже если я снова вызову CreateTabs1(). Опять же, это всегда срабатывало безупречно.

Вот журнал:

05-25 23:41:24.857: ERROR/AndroidRuntime(27290): FATAL EXCEPTION: main
    java.lang.IllegalStateException: The application PagerAdapter changed the adapter contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 11, found: 10 Pager id: com.######:id/pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.#####.######.#####$TabsAdapter
    at android.support.v4.view.ViewPager.populate(ViewPager.java:959)
    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:548)
    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:507)
    at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:488)
    at com.#####.#####.#####$TabsAdapter.onTabSelected(#####.java:215)
    at com.actionbarsherlock.internal.app.ActionBarWrapper$TabWrapper.onTabSelected(ActionBarWrapper.java:356)
    at com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:570)
    at com.android.internal.app.ActionBarImpl.removeTabAt(ActionBarImpl.java:544)
    at com.android.internal.app.ActionBarImpl.removeTab(ActionBarImpl.java:520)
    at com.actionbarsherlock.internal.app.ActionBarWrapper.removeTab(ActionBarWrapper.java:409)
    at com.#####.#####.#####$TabsAdapter.removeTab(#####.java:181)
    at com.#####.#####.#####.tabDrop(#####.java:381)
    at com.#####.#####.#####.onOptionsItemSelected(#####.java:459)
    at android.support.v4.app.Watson.onMenuItemSelected(Watson.java:118)
    at com.actionbarsherlock.ActionBarSherlock.callbackOptionsItemSelected(ActionBarSherlock.java:603)
    at com.actionbarsherlock.internal.ActionBarSherlockNative.dispatchOptionsItemSelected(ActionBarSherlockNative.java:93)
    at com.actionbarsherlock.app.SherlockFragmentActivity.onMenuItemSelected(SherlockFragmentActivity.java:205)
    at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:980)
    at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
    at com.android.internal.view.menu.SubMenuBuilder.dispatchMenuItemSelected(SubMenuBuilder.java:81)
    at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
    at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
    at com.android.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:156)
    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
    at android.widget.AbsListView$1.run(AbsListView.java:3423)
    at android.os.Handler.handleCallback(Handler.java:725)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5041)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    at dalvik.system.NativeStart.main(Native Method)
4b9b3361

Ответ 1

После ADT 22 PagerAdapter получил очень строгую информацию о вызове notifyDataSetChanged() перед вызовом getCount(). Очевидно, он отслеживает, что, по его мнению, должен быть счет, и если это не то же самое, что возвращает getCount(), это исключает это исключение. Таким образом, решение просто вызывает notifyDataSetChanged() на адаптере каждый раз, когда изменяется размер данных.

В моем случае у меня есть фоновая задача, которая создает массив данных. После заполнения массива я вызываю notifyDataSetChanged() в onPostExecute(). Когда у меня был путь в onPostExecute(), который не вызывал notifyDataSetChanged(), я получал исключение.

Ответ 2

размещение метода notifyDataSetChanged(); непосредственно под методом добавления/удаления страницы на пейджер действительно сработало. Спасибо @Ninjalan

Ответ 3

Вы можете вызвать ViewPager.setAdapter(null) прямо перед всеми вашими логиками добавления/удаления вкладок и в конце переназначить обновленный адаптер. Решила мои проблемы.

mPager.setAdapter(null);
mTabHost.clearAllTabs();
mTabHost.addTab(...);
mTabHost.addTab(...);
mTabHost.addTab(...);
mPager.setAdapter(YOUR_UPDATED_ADAPTER_HERE);

Ответ 4

Youtry set Кодирование myViewPagerAdapter.notifyDataSetChanged();

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    feedItemComics = (FeedItemComics) getArguments().getSerializable( DESCRIBABLE_KEY);
    feedItemComics.getTitle();
    feedItemComics.getLast_modified();

    sceneNo.setText(feedItemComics.getScene_no());
    title.setText(feedItemComics.getTitle());
  //  Logger.Log("feedItemComics.getThumbnail", feedItemComics.getLast_modified());
    Logger.Log("feedItemComics.getTitle", feedItemComics.getTitle());

    itemComicses = (ArrayList<FeedItemComics>) getArguments().getSerializable("images");
   // feedItemList = (ArrayList<FeedItemComics>) getArguments().getSerializable("images");
    selectedPosition = getArguments().getInt("position");

   Logger.Log("itemComicses size", String.valueOf(itemComicses.size()));
    Logger.Log("selectedPosition", String.valueOf(selectedPosition));

    myViewPagerAdapter.notifyDataSetChanged();

    clickPrevious.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(viewPager.getCurrentItem()-1 < itemComicses.size()+1 ){
                viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
                Logger.Log("position " , String.valueOf(viewPager.getCurrentItem()-1));
            }
        }
    });


    clickNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if(viewPager.getCurrentItem()+1 < itemComicses.size() ){
                viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
                Logger.Log("position " , String.valueOf(viewPager.getCurrentItem()+1));
            }

        }
    });

}