Ersetzen eines Fragments durch ein anderes Fragment innerhalb der Aktivitätsgruppe

136

Ich habe ein Fragment innerhalb einer Gruppenaktivität und möchte es durch ein anderes Fragment ersetzen:

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

Es funktioniert einwandfrei, wenn es als separates Projekt ohne Verwendung einer Aktivitätsgruppe ausgeführt wird. In log cat funktioniert alles einwandfrei, da die Steuerung in getview () erfolgt. Es ist jedoch keine Ansicht sichtbar, es tritt nicht einmal eine Ausnahme auf. Ich möchte, dass das Buchdetailfragment angezeigt wird durch ein Abschnittsdetailfragment ersetzt werden.

XML des Buchdetailfragments hat die ID book_description_fragment und XML des Abschnittsbeschreibungsfragments hat die ID section_description_fragment.

Der obige Code befindet sich in der onClick-Methode eines Elements. Ich möchte, dass sich das Fragment ändert, wenn der Benutzer in der horizontalen Bildlaufansicht auf ein Element tippt.

Löwenherz
quelle

Antworten:

249

Fragmente, die in XML fest codiert sind, können nicht ersetzt werden. Wenn Sie ein Fragment durch ein anderes ersetzen müssen, sollten Sie es zunächst dynamisch hinzufügen.

Hinweis: R.id.fragment_container ist ein Layout oder Container Ihrer Wahl in der Aktivität, in die Sie das Fragment bringen.

// 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
quelle
8
Was ist in diesem Fall der R.id.fragment_container?
Guy
4
@ Guy, Es kann ein beliebiges Layout sein, in das Sie das Fragment laden möchten.
Subin Sebastian
1
Wie sollte das Fragment in der XML-Datei heißen? Ich möchte ein Fragment dynamisch hinzufügen und möchte kein statisches Fragment.
Rajat Mehra
1
@RajatMehra Wenn Sie Fragmente dynamisch hinzufügen möchten, müssen Sie das Fragment überhaupt nicht im XML angeben. Sie können eine Containeransicht verwenden. Bitte lesen Sie die Antwort noch einmal.
Subin Sebastian
4
@Ahmed Der Grund dafür ist, dass das System durch die Architektur jedes <fragment> -Tag durch die Ansicht (Gruppe) ersetzt, die von den entsprechenden Fragmenten bereitgestellt wird onCreateView(). Wie Sie also annehmen können, geht jeder Verweis auf das Fragment auf Ansichtsebene tatsächlich verloren. Sie können also grundsätzlich kein Fragment ersetzen, sondern die jetzt im Container vorhandenen Ansichten manuell entfernen und bei Bedarf stattdessen ein Fragment dort ablegen.
Subin Sebastian
35

Bitte sehen Sie diese Frage

Sie können nur ein " dynamisch hinzugefügtes Fragment " ersetzen .

Wenn Sie also ein dynamisches Fragment hinzufügen möchten, sehen Sie sich dieses Beispiel an.

Sana
quelle
1
Hallo . Ich habe die Lösung entdeckt, eigentlich habe ich den Inhalt des Fragments nicht in ein Layout eingefügt, sondern ein anderes Fragment für den Inhalt des vorherigen Fragments verwendet
Lion Heart
Nein, hier wollte ich das gesamte Fragment durch ein neues Fragment ersetzen.
Sana
1
@ Lion Heart, könnten Sie bitte die Lösung ausarbeiten, die Sie gefunden haben?
Namratha
Der Link ist tot: /
Neon Warge
8

Ich habe einen Kern mit gemacht der perfekten Methode zur Verwaltung Fragment Ersatzes und Lebenszyklus .

Das aktuelle Fragment wird nur dann durch ein neues ersetzt, wenn es nicht dasselbe ist und wenn es sich nicht im Backstack befindet (in diesem Fall wird es eingeblendet).

Es enthält mehrere Optionen, als ob das Fragment im Backstack gespeichert werden soll.

=> Siehe Gist hier

Wenn Sie diese und eine einzelne Aktivität verwenden, möchten Sie diese möglicherweise zu Ihrer Aktivität hinzufügen:

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

    super.onBackPressed();
}
Hugo Gresse
quelle
1
@ RémiP der Link funktioniert wie erwartet. Sie können diese überprüfen, die möglicherweise besser ist IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/…
Hugo Gresse
8

Verwenden Sie den folgenden Code 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();
Sachin Suthar
quelle
4

Verwenden Sie diesen Code mit 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
quelle
3

Ich hoffe, es geht dir gut. Als ich anfing zu arbeiten, hatte Android Fragmentsich auch das gleiche Problem. Dann las ich über 1- Wie man ein Fragment mit einem anderen wechselt. 2- Hinzufügen eines Fragments, wenn Fragment containerkein Fragment vorhanden ist.

Nach einigen Forschungs- und Entwicklungsarbeiten habe ich dann eine Funktion erstellt, die mir in vielen Projekten bis jetzt hilft, und ich verwende diese einfache Funktion immer noch.

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

genieße deine Codezeit :)

John Smith
quelle
3

Verwenden Sie ViewPager. Es ist Arbeit für mich.

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
quelle
1

Sie können diesen Code verwenden

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

oder Sie können diesen Code verwenden

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

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

In Kotlin können Sie Folgendes tun:

// 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
quelle
0

Sie können einfachen Code für die Transaktion verwenden

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

Ich ändere Fragmente dynamisch in einzeiligem Code.
Es funktioniert in jeder SDK-Version und AndroidX, als die
ich die Navigation verwendeBottomNavigationView

    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
quelle