2013-02-22 3 views
30

У меня есть ListFragment в моей MainActivity. Вот как я устанавливаю свой объект фрагмента.Есть ли способ получить фрагмент сверху стека?

FragmentManager fragmentManager = activity.getSupportFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
Fragment newFragment = new MyFragment(); 
fragmentTransaction.replace(R.id.framecontainer, newFragment, "tag"); 
fragmentTransaction.addToBackStack(null); 
fragmentTransaction.commit(); 

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

getActionBar().setTitle(title); 
getActionBar().setDisplayHomeAsUpEnabled(isEnabled); 
invalidateOptionsMenu(); 

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

String title = fragment.getArguments().getString("KEY_TITLE"); 
boolean isEnabled = fragment.getArguments().getBoolean("KEY_ISENABLED"); 

я найти соответствующий вопрос, и я понял, что я мог бы получить фрагмент, вызвав

MyFragment fragment = (MyFragment) getSupportFragmentManager() 
     .findFragmentByTag("tag"); 

Однако, я должен хранить все теги в пользовательском стеке и вызвать поп () каждый раз, когда пользователь нажал задний кнопка в onBackPressed().

Итак, мой вопрос в том, что есть ли способ получить текущий видимый фрагмент из стека?

Примечание: Имейте в виду, что типы фрагментов разные, а не только MyFragment.

ответ

52

Некоторые вещи, как это должны помочь вашей деятельности фигуре это на backpress:

private Fragment getCurrentFragment(){ 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); 
    Fragment currentFragment = fragmentManager.findFragmentByTag(fragmentTag); 
    return currentFragment; 
} 

@Override 
public void onBackPressed() { 
    Fragment fragmentBeforeBackPress = getCurrentFragment(); 
    // Perform the usual back action 
    super.onBackPressed(); 
    Fragment fragmentAfterBackPress = getCurrentFragment(); 
} 

Надеется, что это помогает.

+6

кажется, что если я делаю это в вашем пути, я должен установить * * fragmentTransaction.addToBackStack (тег) **; В противном случае я получаю исключение NullPointerException. Итак, ** fragmentManager.getBackStackEntryAt (fragmentManager.getBackStackEntryCount() - 1) .getName(); ** не ссылается на имя тега –

+1

Да ... вам нужно будет проверить наличие нулей и неправильную математику ((getBackStackEntryCount-1)> 0 и такие).Я написал это слишком быстро. Кроме того, фрагменты, добавленные без тега, будут отображаться как null. – petey

+0

будет ли он работать, если я использую addToBackStack (null)? – umerk44

20
FragmentManager.findFragmentById(fragmentsContainerId) 

function возвращает ссылку к началу Fragment в backstack. Пример использования:

fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 
      Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer); 
      if(fr!=null){ 
       Log.e("fragment=", f.getClass().getSimpleName()); 
      } 
     } 
    }); 
+0

Это кажется странным ... но отлично работает для меня :). Документы говорят, что он выполняет поиск в backstack, поэтому, надеюсь, он всегда ищет от вершины стека, во всех версиях Android (скрещенными пальцами). – delrocco

+0

Я так долго искал это. Спасибо, что выяснил, как работает этот слушатель – mikebertiean

1

Существует уже ответ помечается как правильно и моя дополнительная информация нам не будет то, что отличается от этого. НО, у меня возникли проблемы при использовании приемника, пытающегося установить , если фрагмент, из которого находится приемник, является текущим верхним фрагментом в стеке. Вы можете легко запускать много NPE и Index за пределами границ. Поэтому я написал это, возможно, это помогает кому-то.

private boolean isFragmentOnTop(Activity parentActivity, final String fragmentName){ 
     FragmentManager fmManager = parentActivity.getFragmentManager(); 
     if(fmManager.getBackStackEntryCount() == 0){ 
      LOG.i("BackStack entry count is 0: " + this); 
      return false; 
     } 
     String fragmentNameOnStackTop = ""; 
     final FragmentManager.BackStackEntry topEntry = fmManager.getBackStackEntryAt(fmManager.getBackStackEntryCount() -1); 
     if(topEntry != null) { 
      fragmentNameOnStackTop = topEntry.getName(); 
     } 
     LOG.d("Got fragments name: " + fragmentNameOnStackTop); 
     return fragmentNameOnStackTop != null ? fragmentNameOnStackTop.equals(fragmentName) : false; 
    } 

Обратите внимание, что это прекрасно работает для деятельности, имеющей некоторые фрагменты. Имейте в виду, что вы используете , используя ViewPager - childfragmentmanager.

И не забудьте установить fragmentName в FragmentTransaction.addToBackStack(fragmentName)

0

этот вспомогательный метод получить фрагмент из верхней части стека:

public Fragment getTopFragment() { 
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) { 
     return null; 
    } 
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); 
    return getSupportFragmentManager().findFragmentByTag(fragmentTag); 
}