2017-02-23 7 views
0

У меня есть XML для активности, и у меня есть android: id = "@ + id/fragment_container" FrameLayout, который я использую для добавления фрагментов.Почему Back on Fragment не работает?

Я в настоящее время есть два фрагмента

[GameManager], [PlayerStatus]

Вот фрагмент из XML с контейнером

<FrameLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fragment_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:padding="10dip" > 

я добавить фрагмент [GameManager], как следует из основного вида деятельности:

 //Start the fragment 
     Fragment gameManager = new GameManager(); 
     fragmentManager.beginTransaction() 
       .replace(R.id.fragment_container,gameManager) 
       .addToBackStack(null) 
       .commit(); 

Из класса GameManager Фрагмент, добавить новый фрагмент в контейнер следующим образом при нажатии кнопки:

public boolean buttonPress(Type button) { 
    boolean canBuild = false; 
    Player player = board.getCurrentPlayer(); 

    switch (button) { 
     case INFO: 
    //INFO IS THE BUTTON THAT IS ALWAYS VISIBLE IN TOP LEFT CORNER 
    Log.d("myTag", "about to launch PLAYER INFO"); 

    PlayerStatus playerStatus = new PlayerStatus(); 

    FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentTransaction.replace(R.id.fragment_container, playerStatus); 
    fragmentTransaction.addToBackStack(null); 
    fragmentTransaction.commit(); 
    break; 
    . 
    . 
    . 

В GameManager I setContentView следующим образом, где localgame.xml является XML цитированной выше:

@Override 
public void onCreate(Bundle state) { 
    super.onCreate(state); 
    setContentView(R.layout.localgame); 

Все работает до такой степени, что я нажимаю кнопку «Назад», чтобы вернуться к первому фрагменту.

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

@Override 
    public void onBackPressed() { 
     Log.d("myTag", "DETECTED BACK"); 
     if (getSupportFragmentManager().getBackStackEntryCount() > 0) { 
      Log.d("myTag", "THERE WAS SOMETHING IN THE FRAGSTACK"); 
      getSupportFragmentManager().popBackStack(); 
      getSupportFragmentManager().beginTransaction().commit(); 
     } else { 
      super.onBackPressed(); 
     } 
    } 
} 

Вопрос заключается в том, что при нажатии на кнопку назад, спина определяется правильно, и я также можно увидеть, что там было что-то поп(), но второй фрагмент не закрывается. Он просто остается видимым. Я хочу, чтобы, когда мы нажимаем кнопку назад из фрагмента [playerStatus], мы возвращаемся к фрагменту [GameManager].

Любые советы приветствуются!

Edit: После внесения изменений, предложенных Мартин, я получаю следующее:

E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: com.settlers.hd, PID: 12710 
        java.lang.IllegalArgumentException: No view found for id 0x7f070025 (com.settlers.hd:id/fragment_container) for fragment GameManager{c2a128d #0 id=0x7f070025 GameManager} 
         at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:930) 
         at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115) 
         at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:764) 
         at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1527) 
         at android.support.v4.app.FragmentManagerImpl$2.run(FragmentManager.java:485) 
         at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478) 
         at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:446) 
         at android.os.Handler.handleCallback(Handler.java:739) 
         at android.os.Handler.dispatchMessage(Handler.java:95) 
         at android.os.Looper.loop(Looper.java:148) 
         at android.app.ActivityThread.main(ActivityThread.java:5551) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
+0

Вам не нужно переопределять 'onBackPressed()' в классе активности. Когда вы нажмете кнопку «Назад», она автоматически поместит фрагмент назад. – arjun

+0

После того, как popBackStack не выполнил эту транзакцию. – azizbekian

+0

@arjun Я также пробовал без переопределения, и он по-прежнему кажется поп, но не закрывает фрагмент. – ProgrammedChem

ответ

0

В методе ButtonPress, сделать изменения:

PlayerStatus playerStatus = new PlayerStatus(); 

FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
fragmentTransaction.replace(R.id.fragment_container, playerStatus,playerStatus.getClass().getSimpleName()); 
fragmentTransaction.addToBackStack(playerStatus.getClass().getSimpleName()); 
fragmentTransaction.commit(); 

Вам нужно добавить третий параметр в замене методы и необходимости дать тег в addToBackStack.

+0

TAG в AddToBackStack не является обязательным, поскольку FragmentManager не нуждается в нем для отмены транзакции. –

+0

@MartinMarconcini проверить это: https://developer.android.com/reference/android/app/FragmentTransaction.html#addToBackStack(java.lang.String) –

+0

Обязательно отменять транзакцию. –

0

Несколько советов.

  1. getSupportFragmentManager().beginTransaction().commit(); не требуется во время вашего onBackPressed.

  2. PlayerStatus playerStatus = new PlayerStatus(); - нет-буено. Делайте то, что Google делает (статический метод в фрагменте обычно называют newInstance(), который возвращает new PlayerStatusFragment();

  3. В вашей первой транзакции, вам не нужно replace просто add, ибо нет ничего, чтобы заменить, и вы, вероятно, не хотят, чтобы первая транзакция в backstack, если вы не пришли откуда-то еще, ваш первый назад в первом фрагменте должен отправить вас обратно через super.onBackPressed();.

  4. Перед добавлением такого фрагмента, вы должны проверить, существует ли он, возможно, у FragmentManager уже есть экземпляр вашего фрагмента. Для достижения этой цели ... использование бирке ... как:

    fragmentTransaction.replace(R.id.fragment_container, playerStatus, "SOME_TAG");

Затем вы можете сделать что-то вроде ...

Fragment f = fm.findFragmentByTag("SOME_TAG"); 
if (f == null) { 
    // The FragmentMananger doesn't have a stored instance… create a new one. 
    f = YourFragment.newInstance(); 
} 

fm.beginTransaction() 
    .replace(R.id.container, f, "SOME_TAG") 
    .addToBackStack(null) 
    .commit(); 
+0

Спасибо за ваш ответ. Я внес изменения, которые вы предложили, но теперь я получаю следующую ошибку: E/FragmentManager: для id 0x7f070025 (com.settlers.hd: id/fragment_container) не обнаружено никакого представления для фрагмента GameManager {c2a128d # 0 id = 0x7f070025 GameManager} – ProgrammedChem

+0

Откуда вы это взяли? Как и какая строка (вывести соответствующую трассировку стека). –

+0

Я добавил следы к моему оригинальному сообщению – ProgrammedChem

0

Удалить ниже линии, когда вы сделки GameManager Фрагмент

Fragment gameManager = new GameManager(); 
     fragmentManager.beginTransaction() 
       .replace(R.id.fragment_container,gameManager) 
       // .addToBackStack(null) remove this line 
       .commit(); 

Вы удалили еще одну строку в onBackPressed()

@Override 
    public void onBackPressed() { 
     Log.d("myTag", "DETECTED BACK"); 
     if (getSupportFragmentManager().getBackStackEntryCount() > 0) { 
      Log.d("myTag", "THERE WAS SOMETHING IN THE FRAGSTACK"); 
      getSupportFragmentManager().popBackStack(); 
      // getSupportFragmentManager().beginTransaction().commit(); remove this line 
     } else { 
      super.onBackPressed(); 
     } 
    } 
0

Попробуйте этот код в головной деятельности

@Override 
    public void onBackPressed() { 
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); 
     if (fragment instanceof FragmentOne) { 
      //here handle fragmentOne backpress 
     }else if (fragment instanceof FragmentTwo) { 
      //here handle fragmentTwo backpress 
     }else { 
      super.onBackPressed();    
     } 
    } 

Надежда это поможет !!!

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