Obtener el objeto fragmento actual


175

En mi main.xmltengo

  <FrameLayout
        android:id="@+id/frameTitle"
        android:padding="5dp"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="@drawable/title_bg">
            <fragment
              android:name="com.fragment.TitleFragment"
              android:id="@+id/fragmentTag"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" />

  </FrameLayout>

Y estoy configurando un fragmento de objeto como este

FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");

// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Está configurando diferentes tipos de objetos Fragment ( FragmentType2,FragmentType3,...) en diferentes momentos. Ahora en algún momento necesito identificar qué objeto está actualmente allí.

En resumen , necesito hacer algo como esto:

Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle

Probé lo siguiente

TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);

y

    TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");

Pero ambos objetos (titleFragmentById y titleFragmentByTag) sonnull
¿Me perdí algo?
Estoy usando Compatibility Package, r3y desarrollando para API level 7.

findFragmentById()y findFragmentByTag()funcionará si hemos establecido un fragmento usando fragmentTransaction.replaceo fragmentTransaction.add, pero funcionará return nullsi hemos establecido el objeto en xml (como lo que hice en mi main.xml). Creo que me falta algo en mis archivos XML.



¿La respuesta @CommonsWare te ayuda, porque sigo siendo nulo?
IntoTheDeep

Respuestas:


253

Ahora en algún momento necesito identificar qué objeto está actualmente allí

Llamar findFragmentById()en FragmentManagery determinar qué fragmento se encuentra en su R.id.frameTitleenvase.


1
Gracias por su respuesta. Funcionará si hemos establecido un fragmento usando fragmentTransaction.replace o fragmentTransaction.addpero no lo conseguiremos si lo hemos establecido en xml. Ver mi edición 2
Labeeb Panampullan

9
@Labeeb P: No puede modificar fragmentos declarados en los recursos de diseño.
CommonsWare

La creación de una clase para contener la pestaña / fragmento actualmente visible también funcionará, solo lo intenté. Espero que no haya fallas.
Skynet

@CommonsWare findFragmentByTagdevuelve nulo en caso de ActionBarpestañas. En mi Activityque se extiende, ActionBarActivityprimero agrego pestañas ActionBary luego lo encuentro.
Muhammad Babar

1
@MuhammadBabar: Puede probar executePendingTransactions()el FragmentManagerdespués de llamar commit()a la transacción, aunque no he probado esto. O puede usar setContentView()para usar un archivo de diseño con una <fragment>etiqueta. Cualquiera de los dos ocurre sincrónicamente, por lo que el fragmento existirá dentro de la onCreate()propia llamada donde usó executePendingTransaction()o setContentView(). De lo contrario, un ordinario FragmentTransactionse procesa de forma asíncrona, y ni siquiera habrá comenzado para cuando onCreate()termine el tiempo .
CommonsWare

110

Prueba esto,

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);

esto le dará el fragmento actual, luego puede compararlo con la clase de fragmento y hacer sus cosas.

    if (currentFragment instanceof NameOfYourFragmentClass) {
     Log.v(TAG, "find the current fragment");
  }

¿Dónde poner esta línea?
Anand Savjani

9
A veces tiene que usar getSupportFragmentManager()en su lugar, y quedará nulo sin la supportparte
Muz

Elimine las citas de "NOMBRE DE SU CLASE DE FRAGMENTO".
Alan Nelson

37

Creo que puede usar el evento onAttachFragment puede ser útil para detectar qué fragmento está activo.

@Override
public void onAttachFragment(Fragment fragment) {
    // TODO Auto-generated method stub
    super.onAttachFragment(fragment);

    Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();

}

3
puedo obtener qué fragmento estoy adjunto. Mi deseo es cuando cambio la orientación, entonces necesito mostrar la misma vista, no otra vista, así que cómo hacerlo.
Androi Developer

77
Esto no funciona porque no actualiza el fragmento activo cuando regresa.
Justin

1
@Justin, así que solo necesitamos usar onDetach también con una lista de
referencia débil

12

Creo que deberías hacer:

Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");

La razón es porque configura la etiqueta "fragmentTag" en el último fragmento que ha agregado (cuando llamó a replace).


Gracias lo he corregido. Es un error tipográfico al escribir esta pregunta. Funcionará si hemos establecido un fragmento usando fragmentTransaction.replace o fragmentTransaction.addpero no lo conseguiremos si lo hemos establecido en xml. Vea mi edición 2
Labeeb Panampullan

Muchas gracias! Resuelto mi problema!
Jonas Gröger

2
¿No significa esta solución que tienes que poner la misma etiqueta para varios fragmentos? de lo contrario, ¿cómo saber si fragmentTages la etiqueta para el fragmento actual?
Thupten

12

Puede obtener la lista de los fragmentos y buscar el último.

    FragmentManager fm = getSupportFragmentManager();
    List<Fragment> fragments = fm.getFragments();
    Fragment lastFragment = fragments.get(fragments.size() - 1);

Pero a veces (cuando navega hacia atrás) el tamaño de la lista sigue siendo el mismo, pero algunos de los últimos elementos son nulos. Entonces, en la lista, iteré hasta el último fragmento no nulo y lo usé.

    FragmentManager fm = getSupportFragmentManager();
    if (fm != null) {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for(int i = fragments.size() - 1; i >= 0; i--){
                Fragment fragment = fragments.get(i);
                if(fragment != null) {
                    // found the current fragment

                    // if you want to check for specific fragment class
                    if(fragment instanceof YourFragmentClass) {
                        // do something
                    }
                    break;
                }
            }
        }
    }

3
No uses el getFragments()método. Está marcado con @hidey no se suponía que debía incluirse con el archivo jar de la biblioteca de soporte. No debe considerarse como parte de la API exportada.
James Wald

Je, entonces deberían haber creado un método que te permita hacer exactamente lo que getFragments()hace, porque lo necesitas con bastante frecuencia. Creo que ahora también está disponible públicamente.
EpicPandaForce

10

Esta es la solución más simple y funciona para mí.

1.) agregas tu fragmento

ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();

2.)

FragmentManager fragmentManager = getSupportFragmentManager();

Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);

if(currentFragment.getTag().equals("fragment_tag"))

{

 //Do something

}

else

{

//Do something

}

9

Puede que sea tarde, pero espero que ayude a alguien más, también @CommonsWare ha publicado la respuesta correcta.

FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");

9
Esto no le permite obtener el fragmento activo, ya que no necesariamente conoce la identificación o etiqueta.
Justin

7

Quizás la forma más simple es:

public MyFragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    for(Fragment fragment : fragments){
        if(fragment != null && fragment.getUserVisibleHint())
            return (MyFragment)fragment;
    }
    return null;
}

Funciono para mi


6

Puede crear un campo en su clase de actividad principal:

public class MainActivity extends AppCompatActivity {

    public Fragment fr;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

Y luego dentro de cada clase de fragmento:

public class SomeFragment extends Fragment {

@Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        ((MainActivity) getActivity()).fr = this;
}

Su campo 'fr' es un fragmento actual Objeto

También funciona con popBackStack ()


4

Sé que ha pasado un tiempo, pero lo haré aquí en caso de que ayude a alguien.

La respuesta correcta con diferencia es (y la seleccionada) la de CommonsWare. Estaba teniendo el mismo problema que el publicado, el siguiente

MyFragmentClass fragmentList = 
            (MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);

siguió volviendo nulo. Mi error fue realmente tonto, en mi archivo xml:

<fragment
    android:tag="@+id/fragementID"
    android:name="com.sf.lidgit_android.content.MyFragmentClass"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

El error fue que tenía android: tag INSTEAD OF android: id .


2

La respuesta de @Hammer funcionó para mí, estoy usando para controlar un botón de acción flotante

final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
            Log.d("VIE",String.valueOf(currentFragment));
            if (currentFragment instanceof PerfilFragment) {
                PerfilEdit(view, fab);
            }
        }
});

2

Si se está extendiendo desde AbstractActivity, podría usar el método getFragments ():

for (Fragment f : getFragments()) {
    if (f instanceof YourClass) {
        // do stuff here
    }
}

1

Si está definiendo el fragmento en el diseño XML de la actividad, Activityasegúrese de llamar setContentView()antes de llamar findFragmentById().


1

Si está utilizando BackStack ... y SOLO si está utilizando Back stack, intente esto:

rivate Fragment returnToPreviousFragment() {

    FragmentManager fm = getSupportFragmentManager();

    Fragment topFrag = null;

    int idx = fm.getBackStackEntryCount();
    if (idx > 1) {
        BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
        topFrag = fm.findFragmentByTag(entry.getName());
    }

    fm.popBackStack();

    return topFrag;
}

0

Esto le dará el nombre de la clase de fragmento actual ->

String fr_name = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();

0
  1. Haga una comprobación (qué fragmento en el contenedor de actividad) en el método onStart;

    @Override
    protected void onStart() {
    super.onStart();
    Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container);
    }
  2. Algunos chequean:

    if (fragmentCurrent instanceof MenuFragment) 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.