Remplacement d'un fragment par un autre fragment à l'intérieur du groupe d'activités

137

J'ai un fragment dans une activité de groupe et je souhaite le remplacer par un autre fragment:

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

Cela fonctionne bien quand cela est fait en tant que projet séparé sans utiliser de groupe d'activités, tout fonctionne bien dans log cat car le contrôle entre dans getview (), mais aucune vue n'est visible, aucune exception ne se produit, je veux que le fragment de détail du livre soit être remplacé par un fragment de détail de coupe.

Le XML du fragment de détail de livre a l'ID book_description_fragment et le xml pour le fragment de description de section a l'ID section_description_fragment.

Le code ci-dessus est dans la méthode onClick d'un élément, je veux que lorsque l'utilisateur appuie sur un élément en mode défilement horizontal, le fragment change.

cœur de Lion
la source

Réponses:

250

Les fragments codés en dur en XML ne peuvent pas être remplacés. Si vous avez besoin de remplacer un fragment par un autre, vous devez d'abord les avoir ajoutés dynamiquement.

Remarque: R.id.fragment_container est une mise en page ou un conteneur de votre choix dans l'activité à laquelle vous apportez le fragment.

// 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
la source
8
qu'est-ce que le R.id.fragment_container dans ce cas?
Guy
4
@Guy, il peut s'agir de n'importe quelle mise en page dans laquelle vous souhaitez charger le fragment.
Subin Sebastian
1
quel devrait être le nom du fragment dans un fichier xml? Je veux ajouter un fragment dynamiquement et ne veux pas de fragment statique.
Rajat Mehra
1
@RajatMehra Si vous souhaitez ajouter des fragments de manière dynamique, vous n'avez pas du tout à spécifier le fragment à l'intérieur du XML. Vous pouvez utiliser une vue conteneur. Veuillez relire la réponse.
Subin Sebastian
4
@Ahmed La raison est que, par architecture, le système remplace chaque balise <fragment> par la vue (groupe) fournie par les fragments correspondants ' onCreateView(). Ainsi, comme vous pouvez le supposer, toute référence au fragment est en fait perdue au niveau de la vue. Ainsi, vous ne pouvez pas remplacer un fragment, mais vous pouvez plutôt supprimer manuellement les vues maintenant présentes dans le conteneur et y placer un fragment à la place si nécessaire.
Subin Sebastian
35

S'il vous plaît voir cette question

Vous ne pouvez remplacer qu'un " fragment ajouté dynamiquement ".

Donc, si vous souhaitez ajouter un fragment dynamique, consultez cet exemple.

Sana
la source
1
Salut . J'ai découvert la solution, en fait je ne plaçais pas le contenu du fragment dans une mise en page au lieu d'utiliser un autre fragment pour le contenu du fragment précédent
Lion Heart
Non, ici je cherchais à remplacer le fragment entier par un nouveau fragment.
Sana le
1
@Lion Heart, pourriez-vous élaborer la solution que vous avez trouvée s'il vous plaît?
Namratha
Le lien est mort: /
Neon Warge
8

J'ai fait l'essentiel de LA méthode parfaite pour gérer le remplacement des fragments et le cycle de vie .

Il remplace uniquement le fragment actuel par un nouveau, s'il n'est pas le même et s'il n'est pas en backstack (dans ce cas, il le fera apparaître).

Il contient plusieurs options comme si vous souhaitez que le fragment soit enregistré dans la backstack.

=> Voir Gist ici

En utilisant ceci et une seule activité, vous souhaiterez peut-être l'ajouter à votre activité:

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

    super.onBackPressed();
}
Hugo Gresse
la source
1
@ RémiP le lien fonctionne comme prévu. Vous pouvez vérifier celui-ci qui pourrait être mieux IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io
Hugo Gresse
8

Utilisez le code ci-dessous dans 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
la source
4

Utilisez ce code en utilisant la 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
la source
3

j'espère que vous allez bien. quand j'ai commencé à travailler avec, Android Fragmentsj'avais aussi le même problème alors j'ai lu sur 1- Comment changer de fragment avec d'autres. 2- Comment ajouter un fragment s'il Fragment containern'a aucun fragment.

puis après quelques R&D, j'ai créé une fonction qui m'aide dans de nombreux projets jusqu'à présent et j'utilise toujours cette fonction simple.

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

profitez de votre temps de code :)

John Smith
la source
3

Utilisez ViewPager. C'est du travail pour moi.

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
la source
1

Vous pouvez utiliser ce code

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

ou vous pouvez utiliser ce code

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

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

Dans kotlin, vous pouvez faire:

// 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
la source
0

vous pouvez utiliser un code simple son travail pour la transaction

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

Je change le fragment dynamiquement en code à une seule ligne
Cela fonctionne dans n'importe quelle version du SDK et androidx
J'utilise la navigation commeBottomNavigationView

    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();
    }
Safari Mahdi
la source