1

Я пытаюсь заменить фрагменты в ViewPager, но я столкнулся с проблемой, которую не удалось исправить в течение нескольких дней. Соответствующий код и конкретная проблема, как я понимаю, описаны ниже:ViewPager не обновляет фрагменты

public class ViewPageAdapter extends FragmentStatePagerAdapter { 
int mNumOfTabs; 
FragmentManager mFragmentManager; 
Fragment0 currentFragment0; 
Fragment1 currentFragment1; 
Fragment2 currentFragment2; 
boolean getItemNeverCalled = true; 

public ViewPageAdapter(FragmentManager fm, int numOfTabs){ 
    super(fm); 
    mFragmentManager = fm; 
    this.mNumOfTabs = numOfTabs; 
} 

@Override 
public Fragment getItem(int position){ 
    switch (position){ 
     case 0: 
      if(currentFragment0 == null){ 
       Fragment0 tab0 = new Fragment0(); 
       currentFragment0 = tab0; 
       return currentFragment0; 

      } 
      else { 
       mFragmentManager.beginTransaction().remove(currentFragment0).commit(); 
       int value = selectedPlant.getMoistureFrag().getStat().getOptimalLevel(); 
       currentFragment0 = Fragment0.newInstance(key0, value); 
       notifyDataSetChanged(); // calls getItem(0). 

       return currentFragment0; 
      } 
     case 1: 
      if(currentFragment1 == null){ 
       LightFragment tab1 = new Fragment1(); 
       currentFragment1 = tab1; 

       return currentFragment1; 
      } 
      else { 
       mFragmentManager.beginTransaction().remove(currentFragment1).commit(); 
       int value = selectedPlant.getLightFrag().getStat().getOptimalLevel(); 
       currentFragment1 = currentFragment1.newInstance(key1, value); 
       notifyDataSetChanged(); 

       return currentFragment1; 
      } 
     case 2: 
      if(currentFragment2 == null){ 
       Fragment2 tab2 = new Fragment2(); 
       currentFragment2 = tab2; 

       return currentFragment2; 
      } 
      else { 
       mFragmentManager.beginTransaction().remove(currentFragment2).commit(); 
       int value = selectedPlant.getTempFrag().getStat().getOptimalLevel(); 
       currentFragment2 = Fragment2.newInstance(key2, value); 
       notifyDataSetChanged(); 

       return currentFragment2; 
      } 

     default: 
      return null; 
    } 
} 



@Override 
public int getCount(){ 
    return mNumOfTabs; 
} 

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

Я переопределен метод getItemPosition(Object object) всегда возвращать POSITION_NONE, и называется notifyDataSetChanged(), когда это необходимо (я думаю). Что происходит, так это то, что notifyDataSetChanged() вызывает getItem(0), который вызывает `notifyDataSethanged() ... и так далее. Это вызывает TransactionTooLargeException и приводит к сбою приложения.

Для того, чтобы дать описание флага if/else в каждом случае: if предназначен для загрузки на экран чистого фрагмента Moisture/Light/etc. Это должно произойти при запуске. Оператор else выполняется, когда пользователь нажимает на элемент в навигационном ящике, который имеет некоторые данные. Эти данные затем извлекаются и устанавливаются в качестве аргументов для фрагментов, предназначенных для замены исходного пустого фрагмента.

Я искренне ценю любую помощь. Эта проблема сводит меня с ума.

ответ

1

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

+0

Первоначально возникали проблемы (до того, как я знал, что этот метод существует), поэтому я последовал за http://stackoverflow.com/questions/7723964/replace-fragment-inside-a-viewpager и несколькими другими сообщениями, которые предлагали то же самое , Я дам вам знать, как оно идет. –

+0

Кстати, поскольку вы всегда сохраняете один и тот же класс фрагмента в каждой позиции, и вы держитесь за фрагмент, тогда вы должны перепроектировать код. Вы не должны заменять фрагмент, просто измените фрагмент, который вы держите, чтобы показать новые значения. Код, который вы используете, необходим только в том случае, если вы хотите изменить разные классы фрагментов для позиции. – lionscribe

+0

Хорошо, я вижу. Означает ли это, что я не должен использовать метод getItem после инициализации вкладок при запуске? –

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