Sostituzione di un frammento con un altro frammento all'interno del gruppo di attività


137

Ho un frammento all'interno di un'attività di gruppo e voglio sostituirlo con un altro frammento:

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

Funziona bene quando viene fatto come un progetto separato senza usare un gruppo di attività, tutto funziona bene in log cat mentre il controllo va dentro getview (), ma nessuna vista è visibile, nemmeno se si pone alcuna eccezione, voglio che il frammento dei dettagli del libro sia essere sostituito dal frammento di dettaglio della sezione.

L'XML del frammento di dettaglio del libro ha ID book_description_fragment e xml per il frammento di descrizione della sezione ha l'ID section_description_fragment.

Il codice sopra è nel metodo onClick di un elemento, voglio che quando l'utente tocca un elemento nella vista di scorrimento orizzontale, il frammento cambi.

Risposte:


250

I frammenti che sono hard coded in XML, non possono essere sostituiti. Se devi sostituire un frammento con un altro, dovresti averlo aggiunto dinamicamente, prima di tutto.

Nota: R.id.fragment_container è un layout o contenitore a scelta nell'attività a cui si sta portando il frammento.

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

8
che cos'è il R.id.fragment_container in questo caso?
Guy,

4
@Guy, può essere qualsiasi layout in cui desideri caricare il frammento.
Subin Sebastian

1
quale dovrebbe essere il nome del frammento nel file xml? Voglio aggiungere il frammento in modo dinamico e non voglio alcun frammento statico.
Rajat Mehra,

1
@RajatMehra Se si desidera aggiungere frammenti in modo dinamico, non è necessario specificare il frammento all'interno dell'XML. È possibile utilizzare una vista contenitore. Si prega di leggere di nuovo la risposta.
Subin Sebastian

4
@Ahmed Il motivo è che, per architettura, il sistema sostituisce ogni tag <fragment> con la vista (gruppo) fornita dai frammenti corrispondenti ' onCreateView(). Pertanto, come puoi supporre, qualsiasi riferimento al frammento viene effettivamente perso a livello di vista. Quindi, sostanzialmente non è possibile sostituire un frammento, ma piuttosto è possibile rimuovere manualmente le viste ora presenti nel contenitore e inserire un frammento lì, se necessario.
Subin Sebastian

35

Si prega di vedere questa domanda

È possibile sostituire solo un " frammento aggiunto dinamicamente ".

Quindi, se vuoi aggiungere un frammento dinamico, vedi questo esempio.


1
Ciao . Ho scoperto la soluzione, in realtà non stavo posizionando il contenuto del frammento in un layout, ma stavo usando un altro frammento per il contenuto del frammento precedente
Lion Heart,

No, qui stavo cercando di sostituire l'intero frammento con un nuovo frammento.
Sana,

1
@Lion Heart, potresti elaborare la soluzione che hai trovato per favore?
Namratha,

Il collegamento è morto: /
Neon Warge,

8

Ho fatto un'idea con IL metodo perfetto per gestire la sostituzione dei frammenti e il ciclo di vita .

Sostituisce solo il frammento attuale con uno nuovo, se non è lo stesso e se non è nello zaino (in questo caso lo farà scoppiare).

Contiene diverse opzioni come se si desidera salvare il frammento nel backstack.

=> Vedi Gist qui

Utilizzando questa e una singola attività, potresti voler aggiungere questa alla tua attività:

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

    super.onBackPressed();
}

1
@ RémiP il collegamento funziona come previsto. Puoi controllare questo che potrebbe essere meglio IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/…
Hugo Gresse,

8

Usa il codice seguente in 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();

4

Usa questo codice usando 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();

3

spero che tu stia andando bene. Quando ho iniziato a lavorare, Android Fragmentsho avuto anche lo stesso problema, poi ho letto su 1- Come cambiare frammento con altri. 2- Come aggiungere frammento seFragment container non ha frammenti.

poi dopo un po 'di ricerca e sviluppo, ho creato una funzione che mi aiuta in molti progetti fino ad ora e sto ancora usando questa semplice funzione.

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

buon divertimento :)


3

Usa ViewPager. Per me è un lavoro.

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

1

Puoi usare questo codice

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

oppure puoi usare questo codice

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

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

0

In kotlin puoi fare:

// 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()

0

puoi usare un semplice codice per far funzionare la transazione

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

0

Cambio dinamicamente il frammento in un codice a riga singola
Funziona in qualsiasi versione dell'SDK e androidx
utilizzo la navigazione comeBottomNavigationView

    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();
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.