2015-07-28 3 views
0

хорошо я знаю, что есть другие questions, что на первый взгляд сделать это один выглядит как дубликат, но ни один из этих ответов не работает в моем случае,Handling фрагмент backstack в панели навигации

Что я хочу это первый фрагмент отображается чтобы быть похожим на основную активность в отношении того, как работает кнопка «Назад», мне нужен какой-то фрагмент, который я выбираю из своего навигационного ящика, чтобы вернуться к первому фрагменту, когда нажата кнопка «Назад», после чего пользователь покинет приложение, снова нажав его.

Итак, я попытался использовать addToBackStack, и когда я перейду к другому фрагменту, если я нажму кнопку «Назад», он вернется к моему первому фрагменту (точно так, как я хочу), но нажатие кнопки «Назад» снова оставляет меня с белым экраном (я удивляюсь если это связано с анимацией транзакций im, с помощью которой я включил ниже), чтобы обойти это, я попытался переопределить кнопку «Назад» и бросить вызов на финиш(); но это приводит к тому, что какой-то фрагмент im in заканчивается, а не возвращаться к первому фрагменту, ive попробовал несколько обходных решений из вышеупомянутой ссылки и многих других, но не может найти достойное решение каких-либо предложений?

вот мой Основная деятельность DisplayView

private void displayView(int position) { 
    // update the main content by replacing fragments 
    Fragment fragment = null; 

    switch (position) { 
     case 0: 
      fragment = new FirstFragment(); 

      break; 

     case 1: 
      fragment = new glideFrag(); 
      break; 
     case 2: 
      fragment = new secondGlideFrag(); 
      break; 
     case 3: 
      fragment = new thirdGlideFrag(); 
      break; 
     case 4: 
      fragment = new forthGlideFrag(); 
      break; 

     case 5: 
      fragment = new lgFrag(); 
      break; 
     case 6: 
      fragment = new cyanFrag(); 
      break; 
     case 7: 
      fragment = new sonyFrag(); 
      break; 
     case 8: 
      fragment = new SecondFragment(); 
      break; 

     default: 
      break; 
    } 

    if (fragment != null) { 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter,R.anim.pop_exit); 

     //fragmentManager.beginTransaction() 
       fragmentTransaction.replace(R.id.frame_container, fragment).addToBackStack("first Fragment").commit(); 

     // update selected item and title, then close the drawer 
     mDrawerList.setItemChecked(position, true); 
     mDrawerList.setSelection(position); 
     setTitle(navMenuTitles[position]); 
     mDrawerLayout.closeDrawer(mDrawerList); 
    } else { 
     // error in creating fragment 
     Log.e("MainActivity", "Error in creating fragment"); 
    } 

я нашел это, что выглядит как отличный способ вокруг него

private boolean popNext = false; 

    if(popNext){ 
     if(position == INITIAL_POSITION){ 
      onBackPressed(); 
      mDrawerLayout.closeDrawer(mDrawerList); 
      popNext = false; 
      return; 
     } 
     getSupportFragmentManager().popBackStackImmediate(); 
    } 
    else{ 
     if(position == INITIAL_POSITION){ 
      mDrawerLayout.closeDrawer(mDrawerList); 
      return; 
     } 
     popNext=true; 
    } 

, но им все еще достаточно новое для андроид, и им не уверен, что установить INITIAL_POSITION , я попытался

private static final INITIAL_POSITION = 0; 

, но без удачи

+1

Это задает много раз. Пожалуйста, ищите SO. –

+0

Я знаю, я читал их, я даже ссылался на один –

ответ

3

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

Edit: Вот объяснение этой проблемы, так что вы можете выяснить, как это исправить:

Каждый раз, когда вы добавить транзакцию фрагмента к задней стеке, вы позволяете пользователю восстановить его, нажав кнопка «Назад» и «Активность» вернутся к состоянию, которое было до транзакции. Если в задний стек добавлен исходный фрагмент, тогда, когда пользователь нажимает на него, экран становится пустым, поскольку перед добавлением исходного фрагмента ничего не отображается. Вот почему транзакция начального фрагмента, которая добавляет первый видимый фрагмент к вашей Деятельности, не должна добавляться в задний стек. Обычно инициализации начального фрагмента, как это:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(savedInstanceState == null) { 
     Fragment fragment = new FirstFragment(); 
     getSupportFragmentManager().beginTransaction() 
      .add(R.id.frame_container, fragment) 
      .commit(); 
    } 
} 
+0

, поэтому в этом случае, где у меня есть все фрагменты в ящике навигации, где я бы назвал свое первое дополнение к стопке? Должен ли я вместо этого переопределять onBackPress и вызывать активность, или есть метод popstack, который я мог бы назвать? –

+1

Вам не нужно ничего переоценивать. По умолчанию, когда вы нажимаете назад, система будет пытаться выполнить следующие действия: 1) закройте ящик, если он открыт. 2) Положите стопку фрагмента, если он не пуст. 3) Завершите работу. – BladeCoder

+0

Хотелось бы, чтобы мое приложение загрузило фрагмент A, когда оно запустится, если я перейду к фрагменту B или C из ящика навигации, а затем вернусь назад к выходным окнам, я хочу, чтобы он вернулся к фрагменту A –

0

BladeCoders ответ был более пытался сказать мне, как backstack работает, а не отвечая на мой вопрос, я в конечном итоге, не добавляя никаких фрагментов к задней стеке, .addToBackStack (нуль), и опрокинув кнопку в MainActivity назад, чувствует себя немного рубить, но работает отлично

@Override 
public void onBackPressed() { 
    FragmentManager fragmentManager = getSupportFragmentManager(); 

if (fragmentManager.getBackStackEntryCount() < 1){ 
     Fragment fragment = new FirstFragment(); 
     FragmentTransaction fragmentTransaction =  
     getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.setCustomAnimations(R.anim.enter, R.anim.exit, 
     R.anim.pop_enter, R.anim.pop_exit); 

     getSupportActionBar().setTitle(mDrawerTitle); 

     fragmentTransaction.replace(R.id.frame_container, 
     fragment).addToBackStack("first").commit(); 

    }else{ 
     finish(); 
    } 
} 
+1

Для записи, '.addToBackStack (null)' все еще добавляет транзакцию в задний стек, он просто не связан с тегом. И да, ваше решение действительно является ненужным взломом. – BladeCoder

+1

Кроме того, если вы хотите, чтобы заголовок ActionBar синхронизировался с отображаемым в данный момент фрагментом, вы можете установить прослушиватель backstack с помощью 'FragmentManager.addOnBackStackChangedListener()' и изменить заголовок там. – BladeCoder

-1

Вы можете сделать это даже с вне backstack его только моя точка зрения, чтобы упростить таким образом, что он может помочь кто то.

@Override 
public void onBackPressed(){ 

    Fragment f = getSupportFragmentManager().findFragmentById(R.id.container_body); 
    if(f.getClass().getName().equals(HomeFragment.class.getName())){ // here HomeFragment.class.getName() means from which faragment you actually want to exit 
     finish(); 
    }else{ 
     displayView(0); //were you want to go when back button is pressed 
    } 

} 





private void displayView(int position) { 
    Fragment fragment = null; 
    String title = getString(R.string.app_name); 
    switch (position) { 
     case 0: 
      fragment = new HomeFragment(); 
      title = getString(R.string.app_name); 
      break; 
     case 1: 
      fragment = new OffersFragment(); 
      title = getString(R.string.nav_item_offers); 
      break; 
     case 2: 
      fragment = new NotificationFragment(); 
      title = getString(R.string.nav_item_notifications); 
      break; 

     default: 
      break; 
    } 

    if (fragment != null) { 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
     fragmentTransaction.replace(R.id.container_body, fragment); 
     fragmentTransaction.commit(); 

     // set the toolbar title 
     getSupportActionBar().setTitle(title); 
    } 
} 

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

  • Нет связанных вопросов^_^