2014-12-22 2 views
1

У меня есть два фрагмента, назовем первый фрагмент Fragment A и второй фрагмент Fragment B. Fragment A содержит ViewPager с 2 дочерними фрагментами и Fragment B - это один фрагмент, который каким-то образом получит некоторые точки данных от пользователя. Один из дочерних фрагментов Fragment A содержит RecyclerView, который должен обновить его карту с точкой данных от Fragment B. Оба фрагмента заменяются внутри FrameLayout.Фрагмент A не останавливается, когда вызывается фрагмент B

Проблема в том, что notifiyDatasetChanged никогда не вызывается для Fragment A s RecyclerView, потому что Fragment A is never called. Когда я нажимаю кнопку «Назад» от Fragment B, он не обновляет RecyclerView новыми данными.

Как я могу получить фрагмент A, чтобы приостановить или позвонить onStop, когда я открою Fragment B? Каков наилучший способ обновления RecyclerView? Сделка

фрагмента А в

// ViewPager fragment 
    fm = getSupportFragmentManager(); 
    ft = fm.beginTransaction(); 
    ft.replace(R.id.show_fragment, ViewPagerFragment.newInstance()); 
    ft.commit(); 
транзакции

фрагмента Б

fm = getSupportFragmentManager(); 
      ft = fm.beginTransaction(); 
      ft.replace(R.id.show_fragment, SessionFragment.newInstance()); 
      ft.addToBackStack(null); 
      ft.commit(); 

OnBackPressed

/* 
When a fragment is open allow you to go back to the activity when back button is pressed 
*/ 
@Override 
public void onBackPressed() { 

    FragmentManager fragmentManager = getSupportFragmentManager(); 

    if (onBackPressed(fragmentManager)) { 
     return; 
    } else { 
     super.onBackPressed(); 
     button.setVisibility(View.VISIBLE); 
     button.setEnabled(true); 
    } 

    super.onBackPressed(); 
} 


private boolean onBackPressed(FragmentManager fm) { 
    if (fm != null) { 
     if (fm.getBackStackEntryCount() > 0) { 
      fm.popBackStack(); 
      button.setVisibility(View.VISIBLE); 
      button.setEnabled(true); 
      return true; 
     } 

     List<Fragment> fragList = fm.getFragments(); 
     if (fragList != null && fragList.size() > 0) { 
      for (Fragment frag : fragList) { 
       if (frag == null) { 
        continue; 
       } 
       if (frag.isVisible()) { 
        if (onBackPressed(frag.getChildFragmentManager())) { 
         return true; 
        } 
       } 
      } 
     } 
    } 

    return false; 
} 

______________________ LOG INFO _____________________

12-22 05:38:00.268 18255-18255/? E/InputEventSender﹕ Exception dispatching finished 

signal. 
12-22 05:38:00.268 18255-18255/? E/MessageQueue-JNI﹕ Exception in MessageQueue callback: handleReceiveCallback 
12-22 05:38:00.278 18255-18255/? E/MessageQueue-JNI﹕ java.util.NoSuchElementException 
      at java.util.Vector.lastElement(Vector.java:621) 
      at com.project.ui.MainActivity.onBackPressed(MainActivity.java:267) 
      at com.project.ui.MainActivity.onBackPressed(MainActivity.java:251) 
      at android.app.Activity.onKeyUp(Activity.java:2453) 
      at android.view.KeyEvent.dispatch(KeyEvent.java:2633) 
      at android.app.Activity.dispatchKeyEvent(Activity.java:2704) 
      at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2221) 
      at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3918) 
      at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3880) 
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
      at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578) 
      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476) 
      at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635) 
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476) 
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
      at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3611) 
      at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3772) 
      at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2208) 
      at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1849) 
      at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1840) 
      at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2185) 
      at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) 
      at android.os.MessageQueue.nativePollOnce(Native Method) 
      at android.os.MessageQueue.next(MessageQueue.java:143) 
      at android.os.Looper.loop(Looper.java:122) 
      at android.app.ActivityThread.main(ActivityThread.java:5221) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
12-22 05:38:00.278 18255-18255/? D/AndroidRuntime﹕ Shutting down VM 
12-22 05:38:00.280 18255-18255/? E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: example.com.project, PID: 18255 
    java.util.NoSuchElementException 
      at java.util.Vector.lastElement(Vector.java:621) 
      at com.project.ui.MainActivity.onBackPressed(MainActivity.java:267) 
      at com.project.ui.MainActivity.onBackPressed(MainActivity.java:251) 
      at android.app.Activity.onKeyUp(Activity.java:2453) 
      at android.view.KeyEvent.dispatch(KeyEvent.java:2633) 
      at android.app.Activity.dispatchKeyEvent(Activity.java:2704) 
      at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2221) 
      at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3918) 
      at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3880) 
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
      at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578) 
      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476) 
      at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635) 
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476) 
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
      at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3611) 
      at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3772) 
      at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2208) 
      at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1849) 
      at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1840) 
      at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2185) 
      at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) 
      at android.os.MessageQueue.nativePollOnce(Native Method) 
      at android.os.MessageQueue.next(MessageQueue.java:143) 
      at android.os.Looper.loop(Looper.java:122) 
      at android.app.ActivityThread.main(ActivityThread.java:5221) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
+1

Вы n чтобы вручную вызвать метод onPause фрагмента перед его заменой. –

+0

Можете ли вы показать мне пример кода? И лучшие практики для этого? – AndyRoid

+0

да, что вы можете сделать это, возьмите стек и нажмите первый фрагмент A .. Когда вам нужно заменить A на B, тогда в этом случае замените нажимайте новый фрагмент B в стек и до этого выберите последний элемент и call onPause –

ответ

0

Объявляем объект стека

Stack<Fragment> fragmentStack = new Stack<Fragment>(); 

Когда фрагмент А заменил первый раз сделать это:

fm = getSupportFragmentManager(); 
ft = fm.beginTransaction(); 
mViewPagerFragment = ViewPagerFragment.newInstance(); 
ft.replace(R.id.show_fragment, mViewPagerFragment); 
fragmentStack.push(mViewPagerFragment); 
ft.commit(); 

Когда вы должны заменить A с B, сделать это:

fm = getSupportFragmentManager(); 
ft = fm.beginTransaction(); 
fragmnetStack.lastElement().onPause(); 
mSessionFragment = SessionFragment.newInstance(); 
ft.replace(R.id.show_fragment, mSessionFragment); 
fragmentStack.push(mSessionFragment); 
ft.addToBackStack(null); 
ft.commit(); 

При вызове кнопку назад, сделать это, чтобы получить фрагмент А назад

fragmentStack.lastElement().onPause(); 
fragmentStack.pop(); 
fm = getSupportFragmentManager(); 
ft = fm.beginTransaction(); 
mViewPagerFragment = fragmentStack.lastElement(); 
mViewPagerFragment.onResume(); 
ft.replace(R.id.show_fragment, mViewPagerFragment); 
ft.commit(); 

EDIT:

Перед добавлением фрагмента б, удалить фрагмент А как это:

fm = getSupportFragmentManager(); 
ft = fm.beginTransaction(); 
ft.remove(fragmentStack.pop()); 
// then add the other code to add fragment B 

вам придется делать то же самое при попытке перемещения из B -> A

+0

проверено, но не работает ошибка: NoSuchElementException – AndyRoid

+0

Угадайте, что уль должен сначала удалить предыдущий фрагмент, подождите проверить редактирование –

+0

Возможно, это была моя ошибка, не объяснив достаточно ясно. Во втором дочернем фрагменте моего viewpager есть recyclerview, который находится в фрагменте A. В активности, которая содержит оба фрагмента A и B, сначала начинается исходный фрагмент A, тогда есть кнопка для раздувания фрагментов B и .replace, моя проблема заключается в том, что значения, полученные в фрагменте B, не сохраняются должным образом в рецикливере фрагмента A. Я проверил записи журнала и onResume не вызывается для какой-то странной причины ?? – AndyRoid

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