Zastąpienie fragmentu innym fragmentem wewnątrz grupy aktywności

137

Mam fragment wewnątrz działania grupowego i chcę go zastąpić innym fragmentem:

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

Działa dobrze, gdy jest wykonywany jako osobny projekt bez użycia grupy aktywności, wszystko działa dobrze w log cat, ponieważ kontrola przechodzi do getview (), ale żaden widok nie jest widoczny, nie ma nawet żadnego wyjątku, chcę, aby fragment szczegółów książki zastąpić fragmentem szczegółu przekroju.

XML fragmentu szczegółów książki ma id book_description_fragment, a xml dla fragmentu opisu sekcji ma id section_description_fragment.

Powyższy kod jest w metodzie onClick elementu, chcę, aby po dotknięciu elementu przez użytkownika w widoku przewijania poziomego fragment się zmienił.

Lwie Serce
źródło

Odpowiedzi:

250

Fragmentów, które są na stałe zakodowane w XML, nie można zastąpić. Jeśli chcesz zamienić fragment na inny, powinieneś dodać je przede wszystkim dynamicznie.

Uwaga: R.id.fragment_container to układ lub kontener do wyboru w działaniu, do którego przenosisz 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
źródło
8
co to jest R.id.fragment_container w tym przypadku?
Guy,
4
@ Guy, może to być dowolny układ, do którego chcesz załadować fragment.
Subin Sebastian,
1
jaka powinna być nazwa fragmentu w pliku xml? Chcę dodać fragment dynamicznie i nie chcę żadnego statycznego fragmentu.
Rajat Mehra
1
@RajatMehra Jeśli chcesz dynamicznie dodawać fragmenty, nie musisz w ogóle określać fragmentu wewnątrz XML. Możesz użyć widoku kontenera. Przeczytaj odpowiedź ponownie.
Subin Sebastian
4
@Ahmed Powodem jest to, że dzięki architekturze system zastępuje każdy tag <fragment> widokiem (grupą) dostarczonym przez odpowiednie fragmenty ” onCreateView(). Tak więc, jak możesz założyć, wszelkie odniesienia do fragmentu są faktycznie tracone na poziomie widoku. Tak więc w zasadzie nie można zastąpić fragmentu, ale raczej można ręcznie usunąć widoki obecne w kontenerze i zamiast tego umieścić tam fragment, jeśli jest to wymagane.
Subin Sebastian
35

Zobacz to pytanie

Możesz zastąpić tylko „ fragment dodawany dynamicznie ”.

Jeśli więc chcesz dodać fragment dynamiczny, zobacz ten przykład.

Sana
źródło
1
Cześć . Znalazłem rozwiązanie, właściwie nie umieszczałem zawartości fragmentu w układzie zamiast tego użyłem innego fragmentu do zawartości poprzedniego fragmentu
Lion Heart
Nie, tutaj chciałem zastąpić cały fragment nowym fragmentem.
Sana
1
@Lion Heart, czy mógłbyś opisać rozwiązanie, które znalazłeś?
Namratha
Link nie działa: /
Neon Warge,
8

Zrobiłem podsumowanie z doskonałą metodą zarządzania wymianą fragmentów i cyklem życia .

Zastąpi tylko aktualny fragment nowym, jeśli nie jest taki sam i nie znajduje się w backstacku (w tym przypadku go wyskoczy).

Zawiera kilka opcji, tak jakbyś chciał, aby fragment został zapisany w backstacku.

=> Zobacz Gist tutaj

Korzystając z tego i jednego działania, możesz dodać to do swojego działania:

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

    super.onBackPressed();
}
Hugo Gresse
źródło
1
@ RémiP łącze działa zgodnie z oczekiwaniami. Można sprawdzić to taki, który może być lepiej IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/...
Hugo GRESSE
8

Użyj poniższego kodu w 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
źródło
4

Użyj tego kodu w wersji 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
źródło
3

mam nadzieję, że dobrze sobie radzisz. kiedy zacząłem pracę z, Android Fragmentsto też miałem ten sam problem, wtedy przeczytałem o 1- Jak zamienić fragment na inny. 2- Jak dodać fragment, jeśli Fragment containernie ma żadnego fragmentu.

potem, po kilku badaniach i rozwoju, stworzyłem funkcję, która do tej pory pomaga mi w wielu projektach i nadal używam tej prostej funkcji.

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

miłego czasu na kod :)

John Smith
źródło
3

Użyj ViewPager. To dla mnie praca.

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
źródło
1

Możesz użyć tego kodu

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

lub możesz użyć kodu

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

        if (fragments==null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
        }
Diako Hasani
źródło
0

W Kotlinie możesz:

// 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
źródło
0

możesz użyć prostego kodu do transakcji

Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit(); 
Nicola Gallazzi
źródło
0

Dynamicznie zmieniam fragment w kodzie jednowierszowym.
Działa w dowolnej wersji SDK i androidx
, jakoBottomNavigationView

    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
źródło