tutorial - trabajar con fragmentos en android
Android: fragmentos de problemas superpuestos (15)
Estoy enfrentando un problema de fragmentos superpuestos cuando cambio entre pestañas y anexo fragmentos a una vista de pestaña a continuación es mi código por favor ayuda
public class FragmentManage extends Fragment implements ActionBar.TabListener {
private Fragment mFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_manage, container, false);
OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
switch(v.getId()) {
case R.id.imageBtnCategory:
if (mFragment == null){
mFragment = new FragmentCategory();
}
ft.replace(android.R.id.content, mFragment);
break;
case R.id.imageBtnManageKey:
if (mFragment == null){
mFragment = new FragmentKeys();
}
ft.replace(android.R.id.content, mFragment);
break;
case R.id.imageBtnChangePswd:
if (mFragment == null){
mFragment = new FragmentChangePwd();
}
ft.replace(android.R.id.content, mFragment);
break;
}
ft.commit();
}
};
ImageButton imageBtnCategory = (ImageButton) v.findViewById(R.id.imageBtnCategory);
ImageButton imageBtnManageKey = (ImageButton) v.findViewById(R.id.imageBtnManageKey);
ImageButton imageBtnChangePswd = (ImageButton) v.findViewById(R.id.imageBtnChangePswd);
imageBtnCategory.setOnClickListener(clickListener);
imageBtnManageKey.setOnClickListener(clickListener);
imageBtnChangePswd.setOnClickListener(clickListener);
return v;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mFragment = new FragmentManage();
ft.add(android.R.id.content, mFragment);
ft.attach(mFragment);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
A veces tengo el mismo problema, pero mi problema no está relacionado con diferentes administradores de fragmentos ( getSupportFragmentManager()
, getFragmentManager()
). Creo que todavía hay otro problema. En mi caso, cuando abro el panel de navegación, siempre borro fragmentos viejos en cada opción de menú, por ejemplo:
Fragment calendarFragment = context.getSupportFragmentManager().findFragmentByTag(FragmentTag.CALENDAR.name());
if (calendarFragment != null)
{
context.getSupportFragmentManager().beginTransaction().remove(calendarFragment).commit();
}
No es posible acceder a un submenú sin el cajón de navegación, por lo que los fragmentos básicamente siempre se eliminan. En algunos casos, después de eliminar y agregar un fragmento nuevamente dentro de una Actividad, de repente se superpone con otro fragmento (anterior)? Pero, ¿por qué el administrador de fragmentos encuentra fragmentos anteriores de repente? Eso puede significar que el administrador de fragmentos tiene errores y no elimina fragmentos antiguos, o que algo está roto.
Mi idea es que, de alguna manera, es la culpa de Android Studio o de cualquier otra herramienta de desarrollo de adb que utilice. Por qué creo que es así, porque Android Studio a veces parece perder la instancia de la aplicación en ejecución. Probablemente este problema esté relacionado de alguna manera con el mismo problema: Android Studio no implementa cambios en la aplicación . No me di cuenta aún cuando esto sucede. Lo que sé es que no puede tratarse de un problema de programación, porque no es reproducible después de que Android Studio relanzó la aplicación. Supongo que de alguna manera hay procesos de fondo que cuelgan, lo que causa instancias múltiples de Actividades, Fragmentos, Administradores de fragmentos, etc. Además, no es solo este error. Vi muchos comportamientos extraños en el pasado que son similares a este. (Por ejemplo, los comportamientos desaparecieron repentinamente cuando IDE no inició la aplicación).
Así es como lo arreglé ...
Establecer el fondo eliminaría el efecto de superposición de la pantalla solo si el diseño coincide con la pantalla de relleno
Los nuevos fragmentos reemplazados en los clics de botón no se reemplazaron en la acción tab_selected o tab change
El siguiente código me lo arregló
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// This is required since button click replaces fragment whose link is lost hence overlapping isuee was occuring
ft.replace(android.R.id.content, mFragment);
// On Tab Change remove old fragment views
ft.remove(mFragment);
}
Bueno, configurar el color de fondo del fragmento no es una solución porque el fragmento seguirá estando en la pila de actividades que puede consumir memoria.
La solución sería eliminar todas las vistas de su framelayout antes de agregar cualquier fragmento nuevo.
private void changeFragment(Fragment fr){
FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
fl.removeAllViews();
FragmentTransaction transaction1 = getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.mainframe, fr);
transaction1.commit();
}
Convertir el color de fondo en blanco también lo resolvió para mí. Creo que esto es un error o un problema de implementación en el administrador de fragmentación de Android. Estaba implementando mi reemplazo y popBackStack () correctamente.
Cuando tuve un problema como este, parecía que estaba agregando un fragmento con childFragmentManager y otro con fragmentManager de los padres, así que compruebe que usa el mismo tipo de administrador de fragmentos.
El administrador de fragmentos mantiene la pila de todos los fragmentos anteriores que se reemplazan. A veces, los fragmentos de la pila posterior se superponen con el fragmento que reemplazamos, para mí
fragmentManager.popBackStack();
funciona, podemos hacer esto en un bucle también para hacer estallar todos los fragmentos en la pila espero que ayude, gracias. Happy Coding :)
Encontré una solución simple y limpia. Para mí el problema estaba en la transacción de fragmento de ejecución en cada llamada de onCreate () de mi actividad. Ahora realizo la transacción solo si savedInstanceState == null
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState == null) {
// replace fragment
}
}
No creo que implementar un fondo blanco sea una solución segura, aunque puede ser conveniente. Básicamente, el problema se produce porque el administrador de fragmentos está confundido acerca de qué fragmento mostrar.
backstack se ve así y cree que estás en frag 4 1-> 2, 2-> 3, 3-> 4 pero en realidad estás en frag 6 por alguna razón, así que popbackstack va
remove (4) add (3) <- ahora tienes 3 (nuevo) y 6 (dejado atrás) mezclados
Para controlar mejor mi navegación, hago un seguimiento de mis fragmentos actuales / anteriores y los reemplazo así. Esto permite que mi aplicación controle la navegación por fragmentos.
if ( !(currentFragment instanceof Settings)) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, settings);
fragmentTransaction.addToBackStack(null);
previousFrag = currentFragment;
currentFragment = settings;
fragmentTransaction.commit();
}
En segundo lugar, creo que el método fragmentmanager.replace () es una mejor alternativa. No estoy seguro si eso está disponible para OP en ese momento.
En tercer lugar, para manejar la contrapresión nativa de androides, debe poder retroceder indefinidamente. Muchas personas recomiendan no agregar el primer fragmento a la pila posterior al no usar esta línea.
fragmentTransaction.addToBackStack (null);
Sin embargo, si ese es el caso, debe verificar si es la primera vez que se carga la aplicación. Si no es así y excluye esta línea, su aplicación tendrá estos problemas cada vez que navegue por este fragmento. Prefiero dejarlo en su lugar y hacer lo siguiente en su lugar.
No estoy seguro si esto se considera una buena solución pero funciona muy bien.
1- obtener recuento de backstack 2- eliminar todos los frags existentes 3- realizar un seguimiento de los objetos fragmentados 4- si es el último fragmento en la pila que el usuario desea salir y dado que añadimos la actividad principal a la pila posterior necesitamos duplicar el pop
@Override
public void onBackPressed() {
int num = getFragmentManager().getBackStackEntryCount();
fl.removeAllViews();
super.onBackPressed();
if (currentFragment != previousFrag) {
currentFragment = previousFrag;
}else{
currentFragment = null;
}
if (num == 1){
super.onBackPressed();
}
Otro problema puede estar relacionado con el uso de android.R.id.content
como contenedor. Acabo de crear FrameLayout
y usar id desde allí.
Puedo llegar muy tarde para responder esta pregunta.
Nota:
Esta respuesta puede no estar relacionada con la pregunta anterior, pero espero que ayude a algunos.
Algunas veces, el problema de superposición de Fragmentos ocurre cuando tratamos de usar los diferentes tipos de fragmentos (es decir, usando fragmentos de soporte en algunos fragmentos y fragmentos normales en algún otro fragmento)
Recientemente me enfrenté al mismo problema en el cajón de navegación. Por error, utilicé " import android.support.v4.app.Fragment; " en un fragmento, y usé " import android.app.Fragment; " en algunos otros fragmentos.
Espero que esto ayude a alguien ...
Simplemente establece un color de fondo para tu <fragment />
en el archivo XML.
Resuelve este problema.
También me enfrenté al problema de la superposición de fragmentos. Así es como lo resolví:
1) Necesitamos agregar el primer fragmento con addToBackStack, para que se conserve en la pila -
FirstFragment firstFragment = new FirstFragment();
getFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).addToBackStack("first frag").commit();
2) Al agregar el segundo fragmento, reemplace el primer fragmento en lugar de agregarlo. Ya que el primer fragmento ya se agregó en la pila, estará presente cuando presione hacia atrás desde el segundo fragmento.
SecondFragment secondFragment= new SecondFragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack("second frag").commit();
3) Aquí se explica cómo se puede manejar la retroimpresión, el código siguiente debe estar presente en la Actividad principal:
public void onBackPressed(){
if(getFragmentManager().getBackStackEntryCount() <= 1){
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
Todo tiene que ver con la ingeniería detrás de los métodos replace y addToBackStack .
El método de reemplazo realmente hará dos cosas. Oculta el fragmento existente (digamos A) y agrega uno nuevo (digamos B) en el contenedor.
Agregar esa transacción a la pila posterior hará lo contrario. Retire B y agregue A.
Entonces, la solución a su problema es
1. use el método addToBackStack .
2. asegúrese de que el reemplazo inverso de fragmentos es el orden correcto
La segunda sugerencia es realmente importante, porque con bastante frecuencia en algún momento el fragmento actual no se elimina y se agrega otro, lo que hace que los dos fragmentos se muestren al mismo tiempo.
cuando tienes un fragmento de superposición, tal vez tu fondo de tu fragmento es transparente, necesitas poner un android: background = "@ color / white" ''dentro de tu fragmento.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
y blanco que necesita poner dentro de los colors.xml #FFFFFF en la carpeta de resto.
private void changeFragment(Fragment fr){
FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
fl.removeAllViews();
FragmentTransaction transaction1 =getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.mainframe, fr);
transaction1.commit();}