elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  Andoid - Como evitar los Fragment superpuestos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 3 Ir Abajo Respuesta Imprimir
Autor Tema: Andoid - Como evitar los Fragment superpuestos  (Leído 10,163 veces)
MaX2

Desconectado Desconectado

Mensajes: 116


Ver Perfil
Andoid - Como evitar los Fragment superpuestos
« en: 22 Abril 2019, 20:00 pm »

Hola, tengo creado un menú horizontal con pestañas desde las que llamo a la clase que extienden de Fragment, donde tengo puesto unos botones para abrir una segunda clase Fragment.
 
El problema es que cunado llamo a esta segundo Fragment el primer Fragment se siguen mostrando debajo.
 
Lo de poner un fondo no es efectivo, porque si pulsamos sobre una parte de la pantalla que contiene debajo un botón, éste sigue activo y mostraría su contenido.
 
Alguien me puede decir como evitar que se superpongan los Fragment ?
 
Este es el codigo que tengo puesto en el Fragment y su xml

Menu1.java extends Fragment

Código:
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View rootView = inflater.inflate( R.layout.menu1, container, false );

        bt_apuntes = rootView.findViewById(R.id.btn_Apuntes);
        bt_apuntes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Apuntes_2 fl=new Apuntes_2();
                FragmentTransaction transaction=manager.beginTransaction();
                transaction.replace(R.id.fragmen_menu1,fl);
                transaction.addToBackStack(null);
                transaction.commit();
            }
        });

  return rootView;

}

Menu1.xml  (he quitado mas código que tengo puesto para otros botones para dejar de ejemplo solo uno)


Código:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    ....
    ....
    android:clickable="true"
    android:focusable="true"
    tools:context=".Menu1">

    <FrameLayout
        ....
        ....
        android:id="@+id/fragmen_menu1">

            <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

                <Button
                    android:id="@+id/btn_Apuntes"
                    android:text="Apuntes"
                    ....
                    ....
                    ....
                    ..../>
            </androidx.constraintlayout.widget.ConstraintLayout>

    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>


P.D. lo de poner el android:clickable="true" y android:focusable="true" es porque he leido que para que no se superpongan los fragment hay que ponelo, pero a mi no me funciona.


Un saludo.


« Última modificación: 22 Abril 2019, 20:42 pm por MaX2 » En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #1 en: 22 Abril 2019, 20:13 pm »

Tienes que hacerle un pop al contenedor o gestor de Fragments. Hace tiempo qeu no trabajo con Android pero creo que era con ésto :

https://developer.android.com/reference/android/app/FragmentManager.html

Investiga

PD O guarda la referncia del anterior y hazle un onDestroy(), porque por lo que veo lo que te puse está deprecated.


« Última modificación: 22 Abril 2019, 20:16 pm por srWhiteSkull » En línea

MaX2

Desconectado Desconectado

Mensajes: 116


Ver Perfil
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #2 en: 22 Abril 2019, 20:25 pm »

Hola srWhiteSkull, gracias por responder tan pronto, la verdad es que no estoy muy puesto y ando un poco perdido, y no se muy bien lo que quiere decir de hacer un pop al contenedor, y la pagina oficial con la traducción que hace google hay veces que....

Creo que se lo que me quieres decir, sustituir el layaut de ese fragment por el segundo, de todas formas en un rato pongo el código en el primer post por si se puede ver mejor lo que estoy haciendo mal.

La verdad es que llevo viendo muchos vídeos, para ver si que codigo utilizandan en los ejemplos y los que he visto siempre llaman a un solo Fragment desde una clase que extiende de AppCompatActivity, lo de llamar a un fragmen desde otro fragmen no lo he visto


Editado
No me interesa destruir los fragment anteriores, porque necesito volver atrás.

Un saludo.
En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #3 en: 22 Abril 2019, 20:51 pm »

No, me refiero hacer un pop, un pop es sacar el Fragment. Supuestamente los Fragment o las vistas se van apilando y existe un gestor que te indiqué en el enlace y que en la documentación recomiendan no usarlo por obsolescencia. Este gestor de fragmentos tiene funciones para sacar el último Fragment, y combinándolo con otro objeto que ya ni me acuerdo, recuerdo que podías hacer transiciones entre Fragments. La verdad es que no estoy muy puesto al día pero si recuerdo el problema que comentas.

En teoría según la doc debes evitar usar el sistema comentado y atenerte al ciclo de vida del Fragment por lo que sugiero que pruebes usar el método onDestroy() con el Fragment que se queda atrás, y para ello debes conservar de alguna manera su "referencia".

Quizás si no entiendes los términos descritos aquí lo que necesitas es más práctica y experiencia con la programación del Api de Android. Si no quieres destrozar el proyecto que tienes con experimentos te aconsejo que crees nuevos proyectos de prueba y cuando entiendas todo eso lo apliques al proyecto que tienes entre mano.

Suerte
En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #4 en: 22 Abril 2019, 20:58 pm »

Siento el doble post, pero viendo el código que has puesto creo que vas encaminado, prueba usar el método remove(FragmentoAnterior) y luego aplicar el reaplce(nuevoFragmento) o el add(NuevoFragmento).

PD Voy a echar un vistazo a algo que tenga por ahí.
« Última modificación: 22 Abril 2019, 21:00 pm por srWhiteSkull » En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #5 en: 22 Abril 2019, 21:04 pm »

En el activity :
Código
  1.    public void cambiaFrame(String nombre, Fragment fragmento){
  2.        esPrincipal=false;
  3.        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  4.        if (getSupportFragmentManager().getBackStackEntryCount()>=1){ // Comprobamos la pila, y si existen más Fragments dentro entonces...
  5.            if (getSupportFragmentManager().getFragments().get(1).getClass()!=fragmento.getClass()) {
  6.                getSupportFragmentManager().popBackStack(); // Sacamos el de atrás de la pila (creo que era para evitar que cuando pulsaras el botón BACK volvieras a la vista anterior)
  7.                ft.replace(R.id.fragment, fragmento); // y reeplazamos
  8.                ft.addToBackStack(nombre); // Le ponemos un nombre a ese Fragment
  9.            }
  10.        } else {
  11.            ft.add(R.id.fragment, fragmento); // En caso de no existir ninguno simplemente añadimos
  12.            ft.addToBackStack(nombre);
  13.        }
  14.        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  15.        getSupportActionBar().setDisplayShowHomeEnabled(true);
  16.        findViewById(R.id.boton_sms).setVisibility(View.INVISIBLE);
  17.        ft.commit();
  18.    }
  19.  

PD También podrías hacerlo invisible o destruirlo, al de atrás, prueba eso también si este código no te sirve.

Resto del código :
https://github.com/RufusWein/proyecto-fin-curso/blob/master/Cliente%20Android%20con%20Pasarela%20SMS/StudentManager/app/src/main/java/tk/srwhiteskull/studentmanager/ActividadPrincipal.java
« Última modificación: 22 Abril 2019, 21:10 pm por srWhiteSkull » En línea

MaX2

Desconectado Desconectado

Mensajes: 116


Ver Perfil
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #6 en: 22 Abril 2019, 21:25 pm »

He cambiado la imagen, porque he corregido los fallos que puse antes, pero todavía me siguen dando errores






« Última modificación: 23 Abril 2019, 19:29 pm por MaX2 » En línea

MaX2

Desconectado Desconectado

Mensajes: 116


Ver Perfil
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #7 en: 23 Abril 2019, 19:37 pm »

He cambiado la imagen porque parece que en el servidor donde estaba no se podia ver, a no ser que se entre con un proxy, asi que la he cambiado de sitio.

Como ves en esa imagen hay algunos errores que no se como corregirlos, otros como el "boton_sms" yo utilizo botones independientes.




En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #8 en: 23 Abril 2019, 22:43 pm »

Los elementos que comienzan por R indican que son recursos estáticos. Eso significa que ya están creados y definidos en el proyecto. En el caso que te puse de ejemplo, no era para que hicieras un copy/paste, algo que deberías entender si vas a dedicarte a la programación.

Lo siguiente que te voy a mostrar, es un ejemplo más sencillo, pero no es para que hagas copy/paste, es para que asimiles el funcionamiento del proceso de transacción o reemplazo de fragmentos evitando el solapamiento de éstos al retroceder por medio del botón BACK del sistema.

Para que asimiles esto estudia el código y prueba comentar la línea de la función cambiaFrame() del Activity, getSupportFragmentManager().popBackStack(), que es la encargada de sacar el fragmento que se encuentra apilado y que aunque la transacción lo reemplaza en verdad permanece vivo en la aplicación. Verás también, en la consola de depuración, como el resultado de Fragmentos Apilados se incrementa según invoques los fragmentos al pulsar los botones Fragmento A y Fragmento B cuando dicha línea esté comentada pero cuando la línea no está comentada el apilamiento será siempre 1.

Normalmente cuando pulsas la tecla BACK del sistema en la actividad tenderá a volver hacia atrás, si no hay nada en la pila volverá al escritorio pero si existen fragmentos vivos en la pila irá haciendo pop liberando en cada pulsación cada fragmento. Esto lo verás al comentar la susodicha línea. Fíjate en la consola de depuración.

Recursos

Código
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    xmlns:app="http://schemas.android.com/apk/res-auto"
  4.    xmlns:tools="http://schemas.android.com/tools"
  5.    android:layout_width="match_parent"
  6.    android:layout_height="match_parent"
  7.    android:background="#F44336"
  8.    android:orientation="vertical"
  9.    tools:context=".MainActivity">
  10.  
  11.    <LinearLayout
  12.        android:layout_width="match_parent"
  13.        android:layout_weight=".15"
  14.        android:background="#00BCD4"
  15.        android:orientation="horizontal"
  16.        android:layout_height="0dp">
  17.  
  18.        <Button
  19.            android:id="@+id/llamaFragmentoA"
  20.            android:layout_width="wrap_content"
  21.            android:layout_height="match_parent"
  22.            android:layout_weight="1"
  23.            android:text="Fragmento A" />
  24.  
  25.        <Button
  26.            android:id="@+id/llamaFragmentoB"
  27.            android:layout_width="wrap_content"
  28.            android:layout_height="match_parent"
  29.            android:layout_weight="1"
  30.            android:text="Fragmento B" />
  31.    </LinearLayout>
  32.  
  33.    <FrameLayout
  34.        android:id="@+id/contenedor"
  35.        android:layout_width="match_parent"
  36.        android:layout_weight=".85"
  37.        android:layout_height="0dp">
  38.  
  39.    </FrameLayout>
  40. </LinearLayout>

Código
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    android:layout_width="match_parent"
  4.    android:layout_height="match_parent">
  5.  
  6.  
  7.    <LinearLayout
  8.        android:layout_width="match_parent"
  9.        android:layout_height="match_parent"
  10.        android:orientation="vertical">
  11.  
  12.        <TextView
  13.            android:id="@+id/textView"
  14.            android:layout_width="match_parent"
  15.            android:layout_weight=".50"
  16.            android:gravity="center"
  17.            android:text="Fragmento A"
  18.            android:layout_height="0dp" />
  19.  
  20.        <FrameLayout
  21.            android:layout_width="match_parent"
  22.            android:layout_height="0dp"
  23.            android:layout_weight=".50"
  24.            android:background="#4CAF50">
  25.  
  26.            <EditText
  27.                android:id="@+id/editText"
  28.                android:layout_width="match_parent"
  29.                android:layout_height="match_parent"
  30.                android:ems="10"
  31.                android:gravity="center"
  32.                android:inputType="textPersonName"
  33.                android:text="A"
  34.                android:textSize="200dp" />
  35.        </FrameLayout>
  36.  
  37.    </LinearLayout>
  38. </FrameLayout>

Código
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    android:layout_width="match_parent"
  4.    android:layout_height="match_parent">
  5.  
  6.  
  7.    <LinearLayout
  8.        android:layout_width="match_parent"
  9.        android:layout_height="match_parent"
  10.        android:orientation="vertical">
  11.  
  12.        <FrameLayout
  13.            android:layout_width="match_parent"
  14.            android:layout_height="0dp"
  15.            android:layout_weight=".50"
  16.            android:background="#FF9800">
  17.  
  18.            <EditText
  19.                android:id="@+id/editText"
  20.                android:layout_width="match_parent"
  21.                android:layout_height="match_parent"
  22.                android:ems="10"
  23.                android:gravity="center"
  24.                android:inputType="textPersonName"
  25.                android:text="B"
  26.                android:textSize="200dp" />
  27.        </FrameLayout>
  28.  
  29.        <TextView
  30.            android:id="@+id/textView"
  31.            android:layout_width="match_parent"
  32.            android:layout_weight=".50"
  33.            android:gravity="center"
  34.            android:text="Fragmento B"
  35.            android:layout_height="0dp" />
  36.  
  37.    </LinearLayout>
  38. </FrameLayout>

Codigo

Hay que añadir a cada clase el package con el nombre correspondiente que le hayas dado al proyecto.

Código
  1. import android.content.Context;
  2. import android.support.v4.app.Fragment;
  3. import android.support.v4.app.FragmentTransaction;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.util.AttributeSet;
  7. import android.util.Log;
  8. import android.view.View;
  9. import android.widget.Button;
  10.  
  11. public class MainActivity extends AppCompatActivity {
  12.  
  13.    @Override
  14.    protected void onCreate(Bundle savedInstanceState) {
  15.        super.onCreate(savedInstanceState);
  16.        setContentView(R.layout.activity_main);
  17.  
  18.        findViewById(R.id.llamaFragmentoA).setOnClickListener(new View.OnClickListener() {
  19.            @Override
  20.            public void onClick(View v) {
  21.                Log.d("Evento","Frgamento A");
  22.                cambiaFrame("A",new FragmentoA());
  23.            }
  24.        });
  25.  
  26.        findViewById(R.id.llamaFragmentoB).setOnClickListener(new View.OnClickListener() {
  27.            @Override
  28.            public void onClick(View v) {
  29.                Log.d("Evento","Frgamento B");
  30.                cambiaFrame("B",new FragmentoB());
  31.            }
  32.        });
  33.    }
  34.  
  35.    public void cambiaFrame(String nombre, Fragment fragmento){
  36.        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  37.        int numFragmentos = getSupportFragmentManager().getBackStackEntryCount();
  38.        Log.d("Frame","Fragmentos Apilados = "+numFragmentos);
  39.        if (numFragmentos>=1){ // Comprobamos la pila, y si existen más Fragments dentro entonces...
  40.            // Comenta esta linea y compara el resultado sin comentar esta linea, cual es la conclusión?
  41.            getSupportFragmentManager().popBackStack(); // Sacamos el de atrás de la pila (creo que era para evitar que cuando pulsaras el botón BACK volvieras a la vista anterior)
  42.  
  43.            ft.replace(R.id.contenedor, fragmento); // y reeplazamos
  44.            ft.addToBackStack(nombre); // Le ponemos un nombre a ese Fragment
  45.  
  46.        } else {
  47.            ft.add(R.id.contenedor, fragmento); // En caso de no existir ninguno simplemente añadimos
  48.            ft.addToBackStack(nombre);
  49.        }
  50.        ft.commit();
  51.    }
  52.  
  53.    @Override
  54.    public void onBackPressed() {
  55.        super.onBackPressed();
  56.        int numFragmentos = getSupportFragmentManager().getBackStackEntryCount();
  57.        Log.d("Frame","Haciendo Pop, fragmentos apilados = "+numFragmentos);
  58.  
  59.    }
  60. }

Código
  1. import android.os.Bundle;
  2. import android.support.v4.app.Fragment;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.TextView;
  7.  
  8. /**
  9.  * A simple {@link Fragment} subclass.
  10.  */
  11. public class FragmentoA extends Fragment {
  12.  
  13.  
  14.    public FragmentoA() {
  15.        // Required empty public constructor
  16.    }
  17.  
  18.  
  19.    @Override
  20.    public View onCreateView(LayoutInflater inflater, ViewGroup container,
  21.                             Bundle savedInstanceState) {
  22.        return inflater.inflate(R.layout.fragmento_a, container, false);
  23.    }
  24.  
  25. }

Código
  1. import android.os.Bundle;
  2. import android.support.v4.app.Fragment;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.TextView;
  7.  
  8. /**
  9.  * A simple {@link Fragment} subclass.
  10.  */
  11. public class FragmentoB extends Fragment {
  12.  
  13.  
  14.    public FragmentoB() {
  15.        // Required empty public constructor
  16.    }
  17.  
  18.  
  19.    @Override
  20.    public View onCreateView(LayoutInflater inflater, ViewGroup container,
  21.                             Bundle savedInstanceState) {
  22.        return inflater.inflate(R.layout.fragmento_b, container, false);
  23.    }
  24.  
  25. }

Este sistema permite solucionar el problema que tienes pero como indica la doc en Apis iguales o superiores a la 28 se debe prescindir del FragmentManager, aconsejando tener en cuenta el ciclo de vida.
En línea

MaX2

Desconectado Desconectado

Mensajes: 116


Ver Perfil
Re: Andoid - Como evitar los Fragment superpuestos
« Respuesta #9 en: 24 Abril 2019, 06:19 am »

Esta tarde me llevare el portátil al curro y lo probare, pero por lo que veo es más o menos lo que yo tengo con un código parecido, y eso si me está funcionando, puedo mostrar desde los botones del AppCompatActivity los Fragment.


El problema viene en el siguiente paso, que en el código que pones no está, que sería poner unos botones en uno de los Fragment y abrir otro Fragment


Ahí es donde tengo el problema para mostrar ese segundo Fragment



Mira a ver si con el video se muestra algo más claro,


En línea

Páginas: [1] 2 3 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Botones superpuestos con swing
Java
rigoxls 8 12,871 Último mensaje 12 Noviembre 2020, 17:58 pm
por MCKSys Argentina
Dont fragment iphdr C
Programación C/C++
soyloqbuskas 0 1,570 Último mensaje 12 Octubre 2012, 11:59 am
por soyloqbuskas
Dos objetos superpuestos. Utilización de la etiqueta z-index
Desarrollo Web
Bròquil 2 2,442 Último mensaje 9 Marzo 2014, 23:48 pm
por Bròquil
Cómo evitar que servicios como Unroll.me espíen tus cuentas de Google o Facebook
Noticias
wolfbcn 0 2,065 Último mensaje 26 Abril 2017, 02:20 am
por wolfbcn
Como Deshabilitar botones del Fragment anterior ?
Java
MaX2 0 1,976 Último mensaje 25 Febrero 2022, 14:19 pm
por MaX2
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines