2011-03-14 14 views
44

Ok, cada vez que trato de reemplazar un fragmento en mi aplicación, solo agrega el fragmento dentro del contenedor del otro fragmento y deja el fragmento actual. Intenté llamar a reemplazar y hacer referencia a la vista que contiene el fragmento, y haciendo referencia al fragmento en sí. Ninguno de estos funciona. Puedo agregar un fragmento a una vista con el administrador de transacciones de fragmento, pero incluso si trato de eliminarlo después de que se ha agregado, no funciona. Cualquier ayuda sería apreciada. Aquí están mis archivos.Duplicación de fragmentos en Fragment Transaction

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    //Setup the actionabar. Use setDrawableBackground to set a background image for the actionbar. 
    final ActionBar actionbar = getActionBar(); 
    actionbar.setDisplayShowTitleEnabled(false); 
    actionbar.setDisplayUseLogoEnabled(true); 
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
    actionbar.addTab(actionbar.newTab().setText(R.string.home_tab_text).setTabListener(this),true); 
    actionbar.addTab(actionbar.newTab().setText(R.string.insert_tab_text).setTabListener(this)); 

    Fragment fragment = new insert_button_frag(); 
    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.replace(R.id.button_fragment, fragment); 
    transaction.addToBackStack(null); 

    transaction.commit(); 
} 

Este es el diagrama

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:id="@+id/button_fragment_container" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" > 

     <fragment 
      android:name="com.bv.silveredittab.home_button_frag" 
      android:id="@+id/button_fragment" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 

    <LinearLayout 
     android:orientation="horizontal" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 

     <fragment 
      android:name="com.bv.silveredittab.quick_insert_frag" 
      android:id="@+id/quick_insert_frag" 
      android:layout_width="350dip" 
      android:layout_height="fill_parent" /> 

     <fragment 
      android:name="com.bv.silveredittab.editor_frag" 
      android:id="@+id/editor_frag" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" /> 

    </LinearLayout> 

</LinearLayout> 

Y aquí es el código de fragmento

public class insert_button_frag extends Fragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     return inflater.inflate(R.layout.insert_buttons,container, false); 
    } 
} 

Como he dicho. He intentado hacer referencia a la vista primaria de fragmentos para reemplazarla, y el fragmento mismo (por id) y aún así, solo agrega el nuevo fragmento, dentro de la vista que contiene el fragmento original.

+0

¿Qué hay en el archivo de diseño insert_buttons.xml? – Peter

Respuesta

33

He resuelto mediante el uso de un marcador de posición en mi diseño y luego adjuntar mi Fragmento a ella en tiempo de ejecución.

Al igual que usted, si instalé mi Fragmento en mi diseño xml, entonces el contenido permanecería visible después de reemplazarlo con otro Fragmento en tiempo de ejecución.

+4

Eso es lo que terminé teniendo que hacer. Un poco retrasado ¿no? – Shaun

+2

¡Jaja, sí! Error o * Característica * Me pregunto. – Damian

+1

Exactamente. Parece que el método de reemplazo es inútil entonces. – Tastybrownies

2

Tuve el mismo problema. Eche un vistazo a este enlace: Android Fragment Duplication

Me pregunto si el hecho de que esté pasando el contenedor al método inflater.inflate() hace que cree el nuevo fragmento dentro del antiguo en lugar de reemplazarlo al por mayor. He estado proporcionando 'nulo' a mis infladores en la versión de trabajo.

Aquí es lo esencial de la versión que yo he trabajo ...

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
    View newFrag = new View(getActivity().getApplicationContext()); 
    newFrag = inflater.inflate(R.id.frag, null); 
    return newFrag; 
} 
+0

Lo he echado un vistazo, pero no creo que realmente se aplique a mi situación. No estoy poblando mis fragmentos de forma progmática. Por alguna razón, mi código no encuentra el fragmento existente, por lo que no lo reemplaza. No está generando ningún error o advertencia. Es realmente confuso – Shaun

+0

Lo siento, eso no ayudó. Edité mi respuesta al inflador, pero si eso no ayuda, tendría que solucionarlo con el IDE. – Peter

+0

Intenté este retorno inflater.inflate (R.layout.home_buttons, null, false); pero eso tampoco funcionó – Shaun

18

El problema es esta línea:

transaction.replace(R.id.button_fragment, fragment); 

replace tiene dos formas sobrecargados. En ambos, el primer argumento es el contenedor del Fragmento que se va a reemplazar, no el Fragmento en sí. Así, en su caso, es necesario llamar a

transaction.replace(R.id.button_fragment_container, fragment); 

edición: Veo en su pregunta que usted ha tratado de ambos. He probado y verificado el comportamiento. Esto parece ser un error en la API FragmentTransaction.

Edit2: no es un error después de todo. Simplemente no puede reemplazar fragmentos agregados estáticamente en un archivo de diseño. Solo puede reemplazar aquellos que ha agregado mediante programación (Android: can't replace one fragment with another)

0

El google developer guide es bastante confuso porque muestra primero implementar un fragmento codificado en su xml. Pero si realmente desea reemplazar el fragmento existente con el nuevo, entonces debe agregarlo (el primero) en tiempo de ejecución.

¿Qué official site estado es

FragmentTransaction reemplazar (int containerViewId, fragmento Fragmento, etiqueta de cadena)

reemplazar un fragmento existente que se añadió a un recipiente. Esto es esencialmente lo mismo que llamar remove (Fragment) para todos los fragmentos añadidos que se agregaron con el mismo containerViewId y luego add (int, Fragment, String) con los mismos argumentos dados aquí.

Usted debe notado que dice que reemplazar un fragmento existente que se añadió a contenedor

Por lo tanto, el código XML debe ser similar someActivity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    ... 
    tools:context="someActivity"> 

    <ImageView 
     .../> 

    <LinearLayout 
     android:id="@+id/fragment_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:gravity="bottom"/> 

</RelativeLayout> 

Y que en tu actividad hazlo en OnCreate()

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     [...] 
     getSupportFragmentManager().beginTransaction() 
       .add(R.id.fragment_container, new FirstFragment).commit(); 

    } 

Que puede reemplazar fácilmente el fragmento con sus animaciones y el evento lo agrega a la pila para guardar su estado.

private SecondFrag getSecondFrag(){ 
    if(secondFrag == null) 
     secondFrag = new SecondFrag() 
    return secondFrag; 
} 

private void openRechargeFragment(){ 
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
     ft.setCustomAnimations(R.anim.show_frag, R.anim.hide_frag, 
       R.anim.show_frag, R.anim.hide_frag); 
     ft.replace(R.id.fragment_container, getSecondFrag(), "myTAG"); 
     ft.addToBackStack(null); 
     ft.commit(); 
} 
Cuestiones relacionadas