2012-05-05 5 views
1

В качестве состояний состояний я пытаюсь реализовать swipable вкладки с помощью фрагментов и ActionBar. Я успешно использовал ActionBarSherlock и код из примеров с классом TabsAdapter (подкласс к FragmentPageAdapter). Некоторые фрагменты должны иметь возможность отображать новую вкладку в одной и той же вкладке spor, и именно здесь возникает проблема. Я действительно не могу понять, как заменить фрагмент в пейджере новым. Я googled и пробовал много вещей.Замещаемые и заменяемые вкладки, фрагменты и ActionBar

Я могу заменить фрагмент во внутренней коллекции, содержащей классы фрагментов внутри FragmentPageAdapter, тем самым делая новый фрагмент доступным для метода getItem, но это не делает, поскольку я не могу понять, как обновить пейджер чтобы показать новый фрагмент. Даже после перехода на другую вкладку и возврата я все еще получаю старый фрагмент, который, я полагаю, кэшируется где-то в пейджере. Итак, есть ли способ сообщить об обновлении пейджера?

Возможно, мне стоит просто забыть использовать FragmentPageAdapter? В таком случае, каков правильный способ получить всю эту функциональность?

P.S. Если вы хотите, чтобы мой код дал мне знать, но это в основном то же самое, что и в примерах, и проблема более общая. Я думаю, что

ответ

0

Когда вы используете ViewPager, он сохраняет видимую страницу/фрагмент в памяти в дополнение к страницам/фрагменты, к которым вы можете перейти. В дополнение к этому, если ViewPager использует FragmentPagerApdapter, он сохраняет взгляды в памяти за всю жизнь.

Я ответил на аналогичный пост выше, удалив фрагмент, который можно найти здесь. Ваш случай является расширением этого, удалением и добавлением чего-то еще.

https://stackoverflow.com/a/10399127/629555

В принципе, вы должны использовать FragmentStatePagerAdapter, переопределить метод getItemPosition вернуть PagerAdapter.POSITION_NONE и убедитесь, что вы звоните .notifyDataSetChanged(); на адаптере, когда вы хотите, она изменилась.

Ответ на приведенную выше ссылку охватывает это более подробно и предоставляет пример кода.

+0

Спасибо, я попробовал его и он работает! Но использует ли FragmentStatePagerAdapter значение, что фрагменты получают перезагрузку каждый раз, когда я переключаю/прокручиваю между ними или они все еще хранятся в памяти и просто перезагружаются при вызове notifyDataSetChanged? – user1293081

+0

'FragmentStatePagerAdapter' будет выгружать/загружать каждый раз, когда вы садитесь. Это компромисс между вычислительной мощностью и памятью с помощью 'PagerAdapter' от Fragment. – Louth

+0

Итак, нет способа использовать FragmentPageAdapter и просто вручную принудительно перезагрузить? Предпочитал бы, чтобы сделать его более плавным. – user1293081

0

Что касается сохранения ссылки на фрагменты в адаптере с помощью FragmentStatePagerAdapter? Затем я их сохранил в памяти, но также имел полный контроль над удалением. Есть ли что-то плохое, чего я не вижу при таком подходе, и я буду сталкиваться с проблемами позже? Кроме того, я изменил так, что фрагменты передаются как объекты, а не классы, что оставляет инициацию вне пейджера. Любые проблемы с этим?

Прикрепление моего кода адаптера:

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<Fragment> mTabs = new ArrayList<Fragment>(); 


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

    public void addTab(ActionBar.Tab tab, Fragment fragment) {   
     tab.setTag(fragment); 
     tab.setTabListener(this); 
     mTabs.add(fragment); 
     mActionBar.addTab(tab); 


     notifyDataSetChanged(); 
    }   

    public void replaceTab(ActionBar.Tab tab, Fragment fragment, int position) { 

     tab.setTag(fragment); 
     tab.setTabListener(this); 
     mTabs.set(position, fragment); 
     notifyDataSetChanged(); 
    } 

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

    @Override 
    public Fragment getItem(int position) { 
     return mTabs.get(position); 
    } 

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

    @Override 
    public int getItemPosition(Object object){ 
     return PagerAdapter.POSITION_NONE; 
    } 
} 
+0

Если вы добавляете новую информацию к своему вопросу, вы должны отредактировать свой вопрос, а не добавить новый ответ. – BoltClock

+0

На самом деле я не видел это как один и тот же вопрос. Первый вопрос задает решения, во-вторых, это решение (на что я хотел бы ответить). – user1293081

Смежные вопросы