ti-enxame.com

Existe uma maneira de obter o fragmento do topo da pilha?

Eu tenho um ListFragment na minha MainActivity. Aqui está como eu defino meu objeto de fragmento.

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

O problema é quando o usuário pressiona o botão de volta, eu tenho que, pelo menos, alterar a barra de ação e menu chamando

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

Eu tenho que saber que tipo de fragmento está mostrando atualmente, para que eu saiba como definir a barra de ação. Eu armazeno a opção de configuração no fragmento como argumentos.

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

Eu pesquiso a questão relacionada, e percebi que poderia pegar o fragmento chamando 

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

No entanto, tenho que armazenar toda a tag em uma pilha personalizada e chamar pop () everytime quando o usuário pressiona o botão Voltar em onBackPressed().

Então, minha pergunta é queexiste uma maneira de obter o fragmento visível atual diretamente da pilha?

Nota: Tenha em mente que os tipos de fragmento são diferentes, não apenas MyFragment.

35
Dragon warrior

Alguma coisa assim deve ajudar sua atividade a descobrir isso na contrapressão:

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();
}

Espero que isto ajude.

64
petey
FragmentManager.findFragmentById(fragmentsContainerId) 

function retorna o link para o topo Fragment no backstack. Exemplo de uso:

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

EDITAR: agora em 2018 existe o método getFragments em FragmentManager que retorna List<Fragment>. De docs: The order of the fragments in the list is the order in which they were added or attached. Então, parece que podemos pegar o último fragmento dessa lista:

     List<Fragment> list = fragmentManager.getFragments();
     //get last one 
     Fragment topFragment = list.get(list.size() - 1);
25
ashakirov

Já existe uma resposta marcada como correta e minhas informações adicionais não serão Diferentes. MAS, eu me meti em problemas ao usar um receptor e tentar descobrir Se o fragmento de onde o receptor é é o fragmento atual de topo Na pilha. Você pode facilmente executar um monte de NPE e Index fora dos limites. Portanto, eu escrevi isso, talvez ajude alguém.

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;
    }

Observe que isso funciona bem para uma atividade com alguns fragmentos. Esteja ciente de que você está usando Usando ViewPager um childfragmentmanager.

E não se esqueça de definir o fragmentName em FragmentTransaction.addToBackStack(fragmentName)

1
JacksOnF1re

Parece que alguma coisa mudou para melhor, porque o código abaixo funciona perfeitamente para mim, mas eu não o encontrei em respostas já fornecidas nem aqui, nem em perguntas de vizinhos.

Kotlin:

supportFragmentManager.fragments[supportFragmentManager.fragments.size - 1]

Java:

getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1)
0
Vasily Kravchenko

este método auxiliar obtém fragmentos do topo da pilha:

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