Reemplazar un fragmento con otro fragmento dentro del grupo de actividad

137

Tengo un fragmento dentro de una actividad grupal y quiero reemplazarlo con otro 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 bien cuando se realiza como un proyecto separado sin usar el grupo de actividades, todo funciona bien en log cat ya que el control entra en getview (), pero no se ve ninguna vista, ni siquiera surge ninguna excepción, quiero que el fragmento de detalles del libro ser reemplazado por el fragmento de detalle de sección.

El xml del fragmento de detalles del libro tiene id. Book_description_fragment y xml para el fragmento de descripción de sección tiene id. Section_description_fragment.

El código anterior está en el método onClick de un elemento, quiero que cuando el usuario toque un elemento en la vista de desplazamiento horizontal, el fragmento cambie.

corazón de León
fuente

Respuestas:

250

Los fragmentos que están codificados en XML no se pueden reemplazar. Si necesita reemplazar un fragmento con otro, primero debería haberlos agregado dinámicamente.

Nota: R.id.fragment_container es un diseño o contenedor de su elección en la actividad a la que está llevando el 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
fuente
8
¿Cuál es el R.id.fragment_container en este caso?
Guy
44
@Guy, puede ser cualquier diseño en el que desee cargar el fragmento.
Subin Sebastian
1
¿Cuál debería ser el nombre del fragmento en el archivo xml? Quiero agregar fragmentos dinámicamente y no quiero ningún fragmento estático.
Rajat Mehra
1
@RajatMehra Si desea agregar fragmentos dinámicamente, no tiene que especificar el fragmento dentro del XML. Puede usar una vista de contenedor. Por favor lea la respuesta nuevamente.
Subin Sebastian
44
@Ahmed La razón es que, por arquitectura, el sistema reemplaza cada etiqueta <fragment> con la vista (grupo) proporcionada por los fragmentos correspondientes ' onCreateView(). Por lo tanto, como puede suponer, cualquier referencia al fragmento se pierde realmente en el nivel de vista. Por lo tanto, básicamente no puede reemplazar un fragmento, sino que puede eliminar manualmente las vistas ahora presentes en el contenedor y colocar un fragmento allí si es necesario.
Subin Sebastian
35

Por favor vea esta pregunta

Solo puede reemplazar un " fragmento agregado dinámicamente ".

Entonces, si desea agregar un fragmento dinámico, vea este ejemplo.

Sana
fuente
1
Hola . He descubierto la solución, en realidad no estaba colocando el contenido del fragmento en un diseño, sino que estaba usando otro fragmento para el contenido del fragmento anterior
Lion Heart
No, aquí estaba buscando reemplazar todo el fragmento con un nuevo fragmento.
Sana
1
@Lion Heart, ¿podrías elaborar la solución que encontraste por favor?
Namratha
El enlace está muerto: /
Neon Warge
8

He hecho una idea fundamental con EL método perfecto para administrar el reemplazo de fragmentos y el ciclo de vida .

Solo reemplaza el fragmento actual por uno nuevo, si no es el mismo y si no está en la pila (en este caso, lo abrirá).

Contiene varias opciones como si quisieras que el fragmento se guarde en la pila.

=> Ver Gist aquí

Con esta y una sola Actividad, es posible que desee agregar esto a su actividad:

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

    super.onBackPressed();
}
Hugo Gresse
fuente
1
@ RémiP el enlace funciona como se esperaba. Puede verificar este que puede ser mejor IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/…
Hugo Gresse
8

Use el siguiente código en 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
fuente
4

Use este código 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();
Butola Manish
fuente
3

Espero que te esté yendo bien. Cuando comencé a trabajar, Android Fragmentstambién tuve el mismo problema y luego leí acerca de 1- Cómo cambiar el fragmento con otro. 2- Cómo agregar un fragmento si Fragment containerno tiene ningún fragmento.

luego, después de un poco de I + D, creé una función que me ayuda en muchos proyectos hasta ahora y todavía estoy usando esta función 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();
    }
}

disfruta tu tiempo de código :)

John Smith
fuente
3

Use ViewPager. Es trabajo para mi.

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

Puedes usar este código

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

o puede usar este código de uso

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

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

En kotlin puedes hacer:

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

puede usar código simple, su trabajo para la transacción

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

Cambio el fragmento dinámicamente en código de una sola línea.
Funciona en cualquier versión de SDK y androidx
. Utilizo la navegación 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
fuente