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<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F44336"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_weight=".15"
android:background="#00BCD4"
android:orientation="horizontal"
android:layout_height="0dp">
<Button
android:id="@+id/llamaFragmentoA"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Fragmento A" />
<Button
android:id="@+id/llamaFragmentoB"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Fragmento B" />
</LinearLayout>
<FrameLayout
android:id="@+id/contenedor"
android:layout_width="match_parent"
android:layout_weight=".85"
android:layout_height="0dp">
</FrameLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_weight=".50"
android:gravity="center"
android:text="Fragmento A"
android:layout_height="0dp" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".50"
android:background="#4CAF50">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ems="10"
android:gravity="center"
android:inputType="textPersonName"
android:text="A"
android:textSize="200dp" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".50"
android:background="#FF9800">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ems="10"
android:gravity="center"
android:inputType="textPersonName"
android:text="B"
android:textSize="200dp" />
</FrameLayout>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_weight=".50"
android:gravity="center"
android:text="Fragmento B"
android:layout_height="0dp" />
</LinearLayout>
</FrameLayout>
CodigoHay que añadir a cada clase el
package con el nombre correspondiente que le hayas dado al proyecto.
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById
(R.
id.
llamaFragmentoA).
setOnClickListener(new View.
OnClickListener() { @Override
public void onClick
(View v
) { Log.d("Evento","Frgamento A");
cambiaFrame("A",new FragmentoA());
}
});
findViewById
(R.
id.
llamaFragmentoB).
setOnClickListener(new View.
OnClickListener() { @Override
public void onClick
(View v
) { Log.d("Evento","Frgamento B");
cambiaFrame("B",new FragmentoB());
}
});
}
public void cambiaFrame
(String nombre, Fragment fragmento
){ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
int numFragmentos = getSupportFragmentManager().getBackStackEntryCount();
Log.d("Frame","Fragmentos Apilados = "+numFragmentos);
if (numFragmentos>=1){ // Comprobamos la pila, y si existen más Fragments dentro entonces...
// Comenta esta linea y compara el resultado sin comentar esta linea, cual es la conclusión?
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)
ft.replace(R.id.contenedor, fragmento); // y reeplazamos
ft.addToBackStack(nombre); // Le ponemos un nombre a ese Fragment
} else {
ft.add(R.id.contenedor, fragmento); // En caso de no existir ninguno simplemente añadimos
ft.addToBackStack(nombre);
}
ft.commit();
}
@Override
public void onBackPressed() {
super.onBackPressed();
int numFragmentos = getSupportFragmentManager().getBackStackEntryCount();
Log.d("Frame","Haciendo Pop, fragmentos apilados = "+numFragmentos);
}
}
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* A simple {@link Fragment} subclass.
*/
public class FragmentoA extends Fragment {
public FragmentoA() {
// Required empty public constructor
}
@Override
public View onCreateView
(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmento_a, container, false);
}
}
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* A simple {@link Fragment} subclass.
*/
public class FragmentoB extends Fragment {
public FragmentoB() {
// Required empty public constructor
}
@Override
public View onCreateView
(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmento_b, container, false);
}
}
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.