2012-04-04 7 views
0

Я использую ViewPager с 4 страницами, и я ищу эффективный способ замены/переключения между фрагментами на каждой странице.Заменить фрагмент в ViewPager с помощью FragmentPagerAdapter

Это модель взаимодействия, которые я пытаюсь создать:

  1. Пользователь нажимает кнопку на странице, которая в настоящее время занимает фрагмент
  2. Фрагмент А выгружена для некоторого нового фрагмента B
  3. пользователь делает некоторую работу в фрагменте B, а затем нажимает кнопку, когда он/она делается
  4. фрагмент B удаляется и заменяется фрагментом а (исходный фрагмент)

Я нашел способ сделать это, но он, похоже, имеет значительные недостатки. Решение включает в себя удаление исходного фрагмента, а затем переопределение getItemPosition (по существу, способ, описанный в этом related question):

//An array to keep track of the currently visible fragment in each page 
private final Fragment[] activeFragments= new Fragment[4]; 

public void openFragmentB(ViewPager pager, int position) { 

    startUpdate(pager); 

    //Remove the original fragment 
    FragmentTransaction transaction = fragmentManager.beginTransaction(); 
    transaction.remove(activeFragments[position]); 
    transaction.commit(); 

    //Create a new tile search fragment to replace the original fragment 
    activeFragments[position] = FragmentB.newInstance(); 
    pageStates[position] = PageState.STATE_B; 

    finishUpdate(pager); 
    notifyDataSetChanged(); 
} 

@Override 
public int getItemPosition(Object object) { 

    //If the main fragment is not active, return POSITION_NONE 
    if(object instanceof FragmentA) { 
     FragmentA a = (FragmentA) object; 
     if(pageStates[a.getPosition()] != PageState.STATE_A) { 
      return POSITION_NONE; 
     } 
    } 

    //If the secondary fragment is not active, return POSITION_NONE 
    if(object instanceof FragmentB) { 
     FragmentB b = (FragmentB) object; 
     if(pageStates[b.getPosition()] != PageState.STATE_B) { 
      return POSITION_NONE; 
     } 
    } 

    return POSITION_UNCHANGED; 
} 

Этот метод работает, но имеет нежелательные побочные эффекты. Удаление фрагмента и установка его позиции на POSITION_NONE приводит к уничтожению фрагмента. Поэтому, когда пользователь заканчивает использование FragmentB, мне нужно будет создать новый экземпляр FragmentA вместо повторного использования исходного фрагмента. Основные фрагменты пейджера (FragmentA в этом примере) будут содержать относительно большие резервные копии базы данных, поэтому я хочу избежать их воссоздания, если это возможно.

По сути, я просто хочу сохранить ссылки на мои 4 основных фрагмента и поменять их на и из страниц, не создавая их каждый раз. Есть идеи?

+0

«Фрагменты» также являются «Представлениями», вы можете создать макет с помощью «Фрагментов», которые вам нужно поменять местами, а затем просто используйте 'setVisibility()' для их удаления и добавления. – adneal

ответ

1

Простым способом избежать повторного создания фрагментов является сохранение их в качестве переменных-членов в вашей деятельности. Я делаю это в любом случае вместе с onRetainCustomNonConfigurationInstance(), чтобы сохранить мои фрагменты во время изменений конфигурации (в основном, при вращении экрана). Я сохраняю свои фрагменты в объекте «Сохранить», поскольку onRetainCustomNonConfigurationInstance возвращает только один объект.

В вашем случае вместо вызова Fragment.newInstance() все время просто проверьте, не осталось ли фрагментов, содержащихся в объекте-хранителе, до создания нового. Если он не является нулевым, просто повторно используйте предыдущий экземпляр. Эта проверка должна выполняться в методе getItem (int) вашего адаптера ViewPager.

Фактически, это означает, что вы обрабатываете, будут ли возвращены фрагменты при вызове getItem и переопределение метода getItemPosition (Object), чтобы всегда возвращать POSITION_NONE, когда для соответствующих сегментов.

1

FragmentPagerAdapter предоставляет способ отмены, который называется getItemId, который поможет вам здесь.

Если вы назначаете уникальное длинное значение для каждого фрагмента в своей коллекции и возвращаете его в этом методе, это заставит ViewPager перезагрузить страницу, когда она замечает, что идентификатор изменен.

Лучше поздно, чем никогда, я надеюсь, что это поможет кому-то!

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