2016-08-02 3 views
28

У меня есть деятельность, в которой есть два фрагмента. Действие начинается с отображения загрузчика при загрузке объекта. Загруженный объект затем передается обоим фрагментам в качестве аргументов с помощью методов newInstance и прикрепляются эти фрагменты.FragmentManager уже выполняет транзакции. Когда безопасно инициализировать пейджер после фиксации?

final FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); 
trans.replace(R.id.container1, Fragment1.newInstance(loadedObject)); 
trans.replace(R.id.container2, Fragment2.newInstance(loadedObject)); 
trans.commit(); 

Второй фрагмент содержит android.support.v4.view.ViewPager и вкладки. onResume мы инициализируем это нравится следующим

viewPager.setAdapter(adapter); 
viewPager.setOffscreenPageLimit(adapter.getCount()); //the count is always < 4 
tabLayout.setupWithViewPager(viewPager); 

Проблема андроида затем бросает

java.lang.IllegalStateException: FragmentManager уже выполняется сделок

С помощью этой трассировки стека: (Я взял android.support из имен пакетов только для краткости)

v4.app.FragmentManagerImpl.execSingleAction (FragmentManager.java:1620) на v4.app.BackStackRecord.commitNowAllowingStateLoss (BackStackRecord.java:637) на v4.app.FragmentPagerAdapter.finishUpdate (FragmentPagerAdapter.java: 143) на v4.view.ViewPager.populate (ViewPager.java:1235) в v4.view.ViewPager.populate (ViewPager.java:1083) на v4.view.ViewPager.setOffscreenPageLimit (ViewPager.java:847)

Привод показывает, удалено ли setOffscreenPageLimit(...);. Есть ли другой способ избежать этой проблемы?

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

+2

, по-видимому, андроид 'ViewPager' будет способствовать' 'NullPointerException' внутри onCreateView' фрагмента внутри пейджера в' IllegalStateException: FragmentManager уже выполняется транзакции ... на всякий случай кто-то падает и должен знать – Lovis

ответ

21

Если вы ориентируетесь 24 и SDK выше вы можете использовать:

FragmentTransaction.commitNow() 

вместо commit()

Если вы ориентируетесь старые версии, попробуйте позвонить:

FragmentManager.executePendingTransactions() 

после звонок по телефону commit()

+4

FragmentManager.executePendingTransactions() также вызывает исключение, так как внутри его кода есть вызов execPendingActions() -> makeExecReady (true) -> if (mExecutingActions) { throw new IllegalStateException («FragmentManager уже выполняет транзакции»); } – user2924714

+0

Это не работает для меня. Два метода показывают сбой: java.lang.IllegalStateException: FragmentManager уже выполняет транзакции – thalissonestrela

59

Просто используйте childFragmentManger() для viewpager внутри Fragment

mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager()); 
mPager.setAdapter(mPagerAdapter); 
+4

Чувак! Ты спас мой день! : D Спасибо тонну! Я использовал вложенные фрагменты, и твой трюк «getChildFragmentManager» работал как шарм!^_^ –

+1

Это сработало в случае, когда «back» (через кнопку «Назад») в комью-версию action/fragment также сбой. Хороший звонок. – Justin

+0

Удивительный мужчина! Это действительно помогает! –

18

я имел это исключение, когда быстро замена 2-фрагментов и использование executePendingTransactions(). Не назвав этого, не было никаких исключений.

Что было в моем случае? Я открываю фрагмент A и в его onResume() (при условии) Я прошу операцию заменить фрагмент на фрагмент B. В этот момент возникает исключение.

Моим решением было использовать Handler.post (runnable), который помещает запрос в конец очереди потоков, а не запускает его немедленно. Таким образом мы гарантируем, что новая транзакция будет выполнена после завершения любых предыдущих транзакций.

Так что мое решение было так просто, как:

Handler uiHandler = new Handler(); 
uiHandler.post(new Runnable() 
{ 
    @Override 
    public void run() 
    { 
     openFragmentB(position); 
    } 
}); 
+1

Простой и эффективный. Однако я использовал postDelayed. В моем случае это было еще лучше, так как на этапе инициализации происходит много нового – gorodechnyj