Substituindo um fragmento por outro fragmento dentro do grupo de atividades

136

Eu tenho um fragmento dentro de uma atividade de grupo e quero substituí-lo por outro fragmento:

FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();

Funciona bem quando é feito como um projeto separado sem usar o grupo de atividades, tudo funciona bem no log cat à medida que o controle entra em getview (), mas nenhuma visualização é visível, nem mesmo ocorre qualquer exceção, quero que o fragmento de detalhes do livro seja ser substituído pelo fragmento de detalhe da seção.

O XML do fragmento de detalhes do livro possui o ID book_description_fragment e o XML para o fragmento de descrição da seção possui o ID section_description_fragment.

O código acima está no método onClick de um item. Quero que, quando o usuário tocar em um item na visualização de rolagem horizontal, o fragmento seja alterado.

coração de Leão
fonte

Respostas:

249

Fragmentos codificados em XML não podem ser substituídos. Se você precisar substituir um fragmento por outro, adicione-os dinamicamente, antes de mais nada.

Nota: R.id.fragment_container é um layout ou contêiner de sua escolha na atividade para a qual você está trazendo o fragmento.

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();
Subin Sebastian
fonte
8
qual é o R.id.fragment_container neste caso?
18714 Guy
4
@ Buy, pode ser qualquer layout em que você queira carregar o fragmento.
Subin Sebastian
1
qual deve ser o nome do fragmento no arquivo xml? Quero adicionar fragmento dinamicamente e não quero nenhum fragmento estático.
Rajat Mehra
1
@RajatMehra Se você deseja adicionar fragmentos dinamicamente, não precisa especificar o fragmento dentro do XML. Você pode usar uma exibição de contêiner. Por favor, leia a resposta novamente.
Subin Sebastian
4
@Ahmed O motivo é que, por arquitetura, o sistema substitui cada tag <fragment> pela visualização (grupo) fornecida pelos fragmentos correspondentes ' onCreateView(). Portanto, como você pode supor, qualquer referência ao fragmento é realmente perdida no nível da visualização. Portanto, você basicamente não pode substituir um fragmento, mas pode remover manualmente as visualizações agora presentes no contêiner e colocar um fragmento nele, se necessário.
Subin Sebastian
35

Por favor, veja esta pergunta

Você pode substituir apenas um " fragmento adicionado dinamicamente ".

Portanto, se você deseja adicionar um fragmento dinâmico, consulte este exemplo.

Sana
fonte
1
Oi . Descobri a solução, na verdade eu não estava colocando o conteúdo do fragmento em um layout vez eu estava usando outro fragmento para o conteúdo do fragmento anterior
Coração de Leão
Não, aqui eu estava procurando substituir o fragmento inteiro por um novo.
Sana
1
@Lion Heart, você poderia elaborar a solução que encontrou por favor?
Namratha
O link está morto: /
Neon Warge
8

Eu criei uma essência com o método perfeito para gerenciar a substituição de fragmentos e o ciclo de vida .

Ele apenas substitui o fragmento atual por um novo, se não for o mesmo e se não estiver no backstack (nesse caso, ele será aberto).

Ele contém várias opções como se você deseja que o fragmento seja salvo no backstack.

=> Veja Gist aqui

Usando esta e uma única atividade, você pode adicionar isso à sua atividade:

@Override
public void onBackPressed() {
    int fragments = getSupportFragmentManager().getBackStackEntryCount();
    if (fragments == 1) {
            finish();
            return;
    }

    super.onBackPressed();
}
Hugo Gresse
fonte
1
@ RémiP o link está funcionando como esperado. Você pode verificar este que pode ser melhor IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/...
Hugo Gresse
8

Use o código abaixo em android.support.v4

FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();
Sachin Suthar
fonte
4

Use esse código usando a v4

 ExampleFragment newFragment = new ExampleFragment();     
 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
 // Replace whatever is in the fragment_container view with this fragment,  
 // and add the transaction to the back stack so the user can navigate back   
 transaction.replace(R.id.container, newFragment);
 transaction.addToBackStack(null);  
 // Commit the transaction   
 transaction.commit();
Manish Butola
fonte
3

Espero que você esteja indo bem. Quando comecei a trabalhar Android Fragments, também estava tendo o mesmo problema, e li sobre 1 - Como alternar fragmento para outro. 2- Como adicionar fragmento se Fragment containernão possui fragmento.

depois de alguma pesquisa e desenvolvimento, criei uma função que me ajuda em muitos projetos até agora e ainda estou usando essa função simples.

public void switchFragment(BaseFragment baseFragment) {
    try {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
            ft.add(R.id.home_frame, baseFragment);
        } else {
            ft.replace(R.id.home_frame, baseFragment);
        }
        ft.addToBackStack(null);
        ft.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

aproveite o seu tempo de código :)

John smith
fonte
3

Use o ViewPager. É trabalho para mim.

final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager); 
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        viewPager.setCurrentItem(1);
    }
});
Nikolay
fonte
1

Você pode usar este código

((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();

ou você pode usar este código

YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);

        if (fragments==null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
        }
Diako Hasani
fonte
0

No kotlin você pode fazer:

// instantiate the new fragment
val fragment: Fragment = ExampleFragment()

val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()
Nicola Gallazzi
fonte
0

você pode usar código simples seu trabalho para transação

Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit(); 
Nicola Gallazzi
fonte
0

Eu mudo o fragmento dinamicamente no código de linha única.
É um trabalho em qualquer versão do SDK e no androidx
eu uso a navegação comoBottomNavigationView

    BottomNavigationView btn_nav;
    FragmentFirst fragmentFirst;
    FragmentSecond fragmentSecond;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        fragmentFirst = new FragmentFirst();
        fragmentSecond = new FragmentSecond ();
        changeFragment(fragmentFirst); // at first time load the fragmentFirst
        btn_nav = findViewById(R.id.bottomNav);
        btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                switch(menuItem.getItemId()){
                    case R.id.menu_first_frag:
                        changeFragment(fragmentFirst); // change fragmentFirst
                        break;
                    case R.id.menu_second_frag:
                        changeFragment(fragmentSecond); // change fragmentSecond
                        break;
                        default:
                            Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }
public void changeFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
    }
Mahdi Safari
fonte