Replace () no funciona correctamente con multi-fragmentos
Actividad principal
package example.antonio.activitydemo; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.support.v4.app.*; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final FragmentManager fragmentManager = getSupportFragmentManager(); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FirstFragment fragment = new FirstFragment(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.container, fragment); fragmentTransaction.commit(); } }); Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SecondFragment fragment = new SecondFragment(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.container, fragment); fragmentTransaction.commit(); } }); } }
Primer fragmento
- ¿Java sobreescribe XML en Android?
- Cómo rotar un RelativeLayout por 180 grados?
- No se puede ejecutar dex: se superó el límite superior de GC en Eclipse
- Hace TimerTask ejecutando en nuevo hilo
- SlidingDrawer semi abierto al inicio
package example.antonio.activitydemo; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.ViewGroup; import android.view.View; public class FirstFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) { return inflater.inflate(R.layout.first_fragment, container, false); } }
Segundo fragmento
package example.antonio.activitydemo; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.ViewGroup; import android.view.View; public class SecondFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) { return inflater.inflate(R.layout.second_fragment, container, false); } }
Sus archivos XML:
Main_activity.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/container" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start1" android:id="@+id/button"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start2" android:id="@+id/button2"/> </LinearLayout>
First_fragment.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#000000"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="First!" android:textColor="#ffffff"/> </FrameLayout>
Second_fragment.xml igual que el anterior, solo con android:text="Second!"
Aquí está la cosa extraña, cuando hago clic para 4 veces el botón de Start1
entonces consigo 4 veces la palabra First!
, Hasta aquí todo normal. Siguiendo si Start2
botón Start2
lo que esperaría es el borrado de los 4 fragmentos anteriores y el agregado de solo uno nuevo, con apariencia de Second!
. Esto es lo que entendí de los documentos:
Reemplazar un fragmento existente que se agregó a un contenedor. Esto es esencialmente lo mismo que llamar a remove (Fragment) para todos los fragmentos agregados actualmente que se agregaron con el mismo containerViewId y luego agregar (int, Fragment, String) con los mismos argumentos que se dan aquí.
Pero esto es lo que obtengo:
Traté de leer el código fuente, tal vez me encontré donde está el "problema", me gustaría saber lo que piensa y si soy yo que estoy cometiendo un error en alguna parte.
Aquí está el fragmento de BackStackRecord.java , método run()
:
case OP_REPLACE: { Fragment f = op.fragment; int containerId = f.mContainerId; if (mManager.mAdded != null) { for (int i = 0; i < mManager.mAdded.size(); i++) { Fragment old = mManager.mAdded.get(i); if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "OP_REPLACE: adding=" + f + " old=" + old); } if (old.mContainerId == containerId) { if (old == f) { op.fragment = f = null; } else { if (op.removed == null) { op.removed = new ArrayList<Fragment>(); } op.removed.add(old); old.mNextAnim = op.exitAnim; if (mAddToBackStack) { old.mBackStackNesting += 1; if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "Bump nesting of " + old + " to " + old.mBackStackNesting); } } mManager.removeFragment(old, mTransition, mTransitionStyle); } } } }
Y aquí está el fragmento de FragmentManager.java :
public void removeFragment(Fragment fragment, int transition, int transitionStyle) { if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); final boolean inactive = !fragment.isInBackStack(); if (!fragment.mDetached || inactive) { if (false) { // Would be nice to catch a bad remove here, but we need // time to test this to make sure we aren't crashes cases // where it is not a problem. if (!mAdded.contains(fragment)) { throw new IllegalStateException("Fragment not added: " + fragment); } } **if (mAdded != null) { mAdded.remove(fragment); }** if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } fragment.mAdded = false; fragment.mRemoving = true; moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED, transition, transitionStyle, false); } }
Como se puede ver, el método removeFragment
elimina un fragmento de mAdded
pero después en el método run()
, el índice i
no se modifica, se reinicia desde donde se ha dejado, de tal manera que puede perder algunos elementos …
- SMS en hebreo en Android
- Cordova está ejecutando la versión incorrecta de Java. ¿Cómo puedo obtener Cordova para ejecutar una versión específica de Java?
- Uso de la modularización en Android
- Loopj Android Async Http - onFailure no disparado
- Cómo obtener NoClassDefFoundError cuando se utiliza common.lang.StringUtils en el código androide java?
- ActionBarSherlock 4.0 no funciona. Pero 3.5.1 hacer
- "No se pudo encontrar la clase android.transition.Transition" excepción al pulsar el botón Atrás
- Reaccionar-despliegue nativo al error del dispositivo android 3 clase de actividad no existe
No se puede lograr este escenario con el lineallayout como un contenedor.
Si intenta usar el fragmento como un contenedor en linearlayout puede lograrlo. Por favor remítase a este enlace para más aclaraciones
Android: el fragmento .replace () no reemplaza el contenido: lo pone en la parte superior
De lo contrario, utilice el siguiente código para las acciones de clic de botón,
Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FirstFragment fragment = new FirstFragment(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.add(R.id.container, fragment).addToBackStack(null); fragmentTransaction.commit(); } }); Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SecondFragment fragment = new SecondFragment(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); for(int i=0; i < getSupportFragmentManager().getBackStackEntryCount(); i++) getSupportFragmentManager().popBackStack(); fragmentTransaction.replace(R.id.container, fragment); fragmentTransaction.commit(); } });
Espero que esto te ayude .. Gracias
- KnoxVpnUidStorageknoxVpnSupported Valor de API devuelto es error falso al usar Parse api
- Notificaciones de doble gcm