Замена фрагмента, содержащего ViewPager

У меня есть действие, содержащее контейнер фрагментов (FrameLayout), в который я помещаю фрагмент во время Activity.onCreate(). Фрагмент содержит ViewPager, который содержит кучу фрагментов. Все это работает нормально. Отображается содержимое страниц, и я могу легко прокручивать страницы, даже видя действия на панели действий, когда страницы, вносящие вклад, становятся видимыми.

Теперь я заменяю фрагмент, содержащий ViewPager, другим фрагментом:

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content, new NewFragment(), tag);
transaction.addToBackStack(null);
transaction.commit();

Замена работает нормально. Отображается новый Фрагмент. Проблема возникает, когда я нажимаю кнопку «Назад», которая помещает фрагмент с ViewPager обратно в представление контейнера. При использовании обычного FragmentPagerAdapter я получаю следующее исключение:

FATAL EXCEPTION: main                                                                                  
java.lang.IllegalStateException: Recursive entry to executePendingTransactions                         
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1403)        
    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431) 
    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)         
    at android.support.v4.view.ViewPager.populate(ViewPager.java:895)                                  
    at android.support.v4.view.ViewPager.populate(ViewPager.java:772)                                  
    at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:380)                                
    at com.domain.app.MyFragment.onViewCreated(MyFragment.java:39)    
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)                
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083)               
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635)                            
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431)        
    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431) 
    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)         
    at android.support.v4.view.ViewPager.populate(ViewPager.java:895)                                  
    at android.support.v4.view.ViewPager.populate(ViewPager.java:772)                                  
    at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:380)                                
    at com.domain.app.MyFragment.onViewCreated(MyFragment.java:39)    
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)                
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083)               
    at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:712)               
    at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1480)         
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:447)      
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:166)                
    at android.app.Activity.onKeyUp(Activity.java:2099)

Как видно, MyFragment.onViewCreated() выполняется дважды, при этом во втором проходе генерируется исключение. Я попытался выполнить код ViewPager и FragmentManager, но это непростое дело.

Кроме того, я заменил FragmentPagerAdapter на FragmentStatePagerAdapter, которому фактически удается воссоздать фрагмент, содержащий ViewPager, но не сам ViewPager. Содержимое страниц не видно, хотя некоторые страницы кажутся на пейджере. Пролистывание непредсказуемо в отношении обратного вызова onPageSelected, и иногда можно увидеть действия на панели действий, которые вносятся из фрагмента В ViewPager. Но все это довольно эпизодически.

Любая помощь будет принята с благодарностью. Спасибо.


person Moritz    schedule 10.09.2012    source источник
comment
Фрагмент содержит ViewPager, который содержит кучу фрагментов — фрагменты внутри фрагментов не поддерживаются. stackoverflow.com/questions/6847460/fragments-within-fragments/< /а>   -  person CommonsWare    schedule 11.09.2012
comment
@CommonsWare Я бы согласился, но он работает при первом создании.   -  person Moritz    schedule 11.09.2012
comment
Цитируя г-жу Хакборн: Попытка поместить фрагмент в пользовательский интерфейс другого фрагмента приведет к неопределенному и, вероятно, нарушенному поведению. Я предлагаю вам последовать совету г-жи Хакборн, либо заставив ViewPager использовать нефрагмент PagerAdapter, либо не помещая ViewPager во фрагмент.   -  person CommonsWare    schedule 11.09.2012
comment
@CommonsWare Я читал ее комментарий раньше, но я надеялся, что это уже изменилось. Швы, я был неправ :( Спасибо за подсказку. Попробую реализовать свой собственный PagerAdapter без фрагментов.   -  person Moritz    schedule 11.09.2012
comment
Вряд ли изменится, просто потому, что у них нет возможности изменить реализацию в прошлых версиях Android. Вполне возможно, что они могли бы внести изменения и посоветовать людям дольше использовать бэкпорт поддержки Android (например, через API уровня 17 или что-то в этом роде). Впрочем, я этого не ожидаю.   -  person CommonsWare    schedule 11.09.2012


Ответы (2)


Проблема должна быть помечена как неразрешимая, поскольку фрагменты внутри фрагментов по-прежнему не поддерживаются мисс Хакборн.

person Moritz    schedule 10.09.2012

Попробуй это

 FragStartCalculation FragStartCalculation = new FragStartCalculation();
    FragmentTransaction ft = root.getSupportFragmentManager().beginTransaction();
    ft.addToBackStack(FragStartCalculation.class.getName());
    ft.replace(R.id.fragContainner, FragStartCalculation, FragStartCalculation.class.getName());
    ft.commit();
person Bipin Bharti    schedule 08.12.2016
comment
здесь fragContainner — ваш контейнер, в котором вы выполняете транзакцию - person Bipin Bharti; 08.12.2016