[android] obtener fragmento actualmente mostrado


Answers

Sé que es una publicación anterior, pero también estaba teniendo problemas con ella anteriormente. Encontré una solución que debía hacer esto en la función de escucha onBackStackChanged()

  @Override
    public void onBackPressed() {
        super.onBackPressed();

         Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
      if(f instanceof CustomFragmentClass) 
        // do something with f
        ((CustomFragmentClass) f).doSomething();

    }

Esto funcionó para mí, ya que no quería recorrer cada fragmento para encontrar uno que sea visible. Espero que ayude a alguien más también.

Question

Estoy jugando con Fragment en Android.

Sé que puedo cambiar el fragmento usando el siguiente código:

FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction fragTrans = fragMgr.beginTransaction();

MyFragment myFragment = new MyFragment();//my custom fragment

fragTrans.replace(android.R.id.content, myFragment);
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragTrans.commit();

Mi pregunta es, en un archivo de Java, ¿cómo puedo obtener la instancia de Fragment que se muestra actualmente?




Si obtiene la instancia actual de Fragment de la actividad principal, puede simplemente

findFragmentByID(R.id.container);

Esto realmente es la instancia actual de fragmento que se llena en la vista. Tuve el mismo problema. Tuve que cargar el mismo fragmento dos veces, manteniendo uno en backstack.

El siguiente método no funciona. Simplemente obtiene un Fragmento que tiene la etiqueta. No pierdas tu tiempo en este método. Estoy seguro de que tiene sus usos, pero obtener la versión más reciente del mismo Fragmento no es uno de ellos.

findFragmentByTag()



En el caso de fragmentos desplazados, cuando su instancia de uso de la clase ViewPager, suponga mVeiwPager, puede llamar a mViewPager.getCurrentItem () para obtener el número int actual del fragmento.




Es un poco tarde, pero para cualquiera que esté interesado: si conoce el índice de su fragmento deseado en FragmentManager, simplemente haga una referencia y compruebe la función esMenuVisible (). aquí :

getSupportFragmentManager().getFragments().get(0).isMenuVisible()

Si es true visible para el usuario, etc.




Usar un bus de eventos (como Otto , EventBus o RxJava Bus ) es especialmente útil en estas situaciones.

Si bien este enfoque no necesariamente te entrega el fragmento actualmente visible como un objeto (aunque eso también se puede hacer, pero lleva a una cadena de llamadas más larga), te permite ejecutar acciones en el fragmento visible actualmente (que generalmente es lo que quiero hacer saber el fragmento visible actualmente).

  1. asegúrese de respetar el ciclo de vida del fragmento y registrar / anular el registro del bus de eventos en el momento apropiado
  2. en el punto donde necesitas saber el fragmento visible actualmente y ejecutar un conjunto de acciones. dispara un evento con el bus de eventos.

todos los fragmentos visibles que se hayan registrado con el bus ejecutarán la acción necesaria.




Cada vez que muestres un fragmento debes ponerlo en el backstack:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);       
ft.add(R.id.primaryLayout, fragment, tag);
ft.addToBackStack(tag);
ft.commit();        

Y luego, cuando necesite obtener el fragmento actual, puede usar este método:

public BaseFragment getActiveFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag);
}



share funciona cuando pulsas el botón Atrás o si no cambias la pila trasera.

Aunque hice algo ligeramente diferente. Tengo una configuración de detector de cambio de backstack en un Fragmento base y sus fragmentos derivados y este código está en el oyente:

Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container);

if (f.getClass().equals(getClass())) {
    // On back button, or popBackStack(),
    // the fragment that's becoming visible executes here,
    // but not the one being popped, or others on the back stack

    // So, for my case, I can change action bar bg color per fragment
}



En la actividad principal, se llama al método onAttachFragment (Fragmento fragmentado) cuando se adjunta un nuevo fragmento a la actividad. En este método, puede obtener la instancia del fragmento actual. Sin embargo, el método onAttachFragment no se invoca cuando se saca un fragmento de la backstack, es decir, cuando se presiona el botón Atrás para obtener el fragmento superior en la parte superior de la pila. Todavía estoy buscando un método de devolución de llamada que se activa en la actividad principal cuando un fragmento se vuelve visible dentro de la actividad.




La forma reactive :

Observable.from(getSupportFragmentManager().getFragments())
    .filter(fragment -> fragment.isVisible())
    .subscribe(fragment1 -> {
        // Do something with it
    }, throwable1 -> {
        // 
    });



Hola, sé que este es un problema muy antiguo, pero me gustaría compartir mi propia solución.

Para obtener la lista de fragmentos examinados por el usuario, creé una clase de ayuda:

public class MyHelperClass{

    private static ArrayList<Fragment> listFragment = new ArrayList<>();

    public static void addFragment(Fragment f){
        if(!existFragment(f)) {
            listFragment.add(f);
        }
    }
    public static void removeFragment(){
        if(listFragment.size()>0)
            listFragment.remove(listFragment.size()-1);
    }
    public static Fragment getCurrentFragment(){
        return listFragment.get(listFragment.size()-1);
    }
    public static int sizeFragments(){
        return listFragment.size();
    }
    private static Boolean existFragment(Fragment f){
        Boolean ret = false;
        for(Fragment fragment : listFragment){
            if (fragment.getClass() == f.getClass()){
                ret = true;
            }
        }
        return ret;
    }

Y en la actividad principal, anulo el método AttachFragment

@Override
public void onAttachFragment(Fragment f) {
    super.onAttachFragment(f);

    MyHelperClass.addFragment(f);
}

y también, sobreescribo en el método BackPressed:

@Override
public void onBackPressed() {
        General.removeFragment();
        if(General.sizeFragments()>0){
            Fragment fragment = null;
            Class fragmentClass = General.getCurrentFragment().getClass();

            try {
                fragment = (Fragment) fragmentClass.newInstance();
                fragment.setArguments(General.getCurrentFragment().getArguments());
            } catch (Exception e) {
                e.printStackTrace();
            }

            fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
        }else{
            super.onBackPressed();
        }
}

para que de esta forma, en cualquier momento, puedas obtener el fragmento activo con MyHelperClass.getCurrentFragment ()

Espero que esto sea útil para cualquiera

Saludos




Puedes obtener el fragmento actual usando el siguiente código

FragmentClass f = (FragmentClass)viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem());



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

Esto funciona para mí Debe realizar una comprobación nula antes de iterar a través de la lista de fragmentos. Puede haber un escenario en el que no se carguen fragmentos en la pila.

El fragmento que regresa se puede comparar con el fragmento que desea colocar en la pila.




Bueno, esta pregunta recibió muchas vistas y atención, pero aún no contenía la solución más fácil de mi parte: usar getFragments ().

            List fragments = getSupportFragmentManager().getFragments();
            mCurrentFragment = fragments.get(fragments.size() - 1);



Esta es la mejor manera:

       android.app.Fragment currentFragment=getFragmentManager().findFragmentById(R.id.main_container);
            if(currentFragment!=null)
            {
                String[] currentFragmentName = currentFragment.toString().split("\\{");
                if (currentFragmentName[0].toString().equalsIgnoreCase("HomeSubjectFragment"))
                {
                    fragment = new HomeStagesFragment();
                    tx = getSupportFragmentManager().beginTransaction();
                    tx.replace(R.id.main_container, fragment);
                    tx.addToBackStack(null);
                    tx.commit();
                }
                else if(currentFragmentName[0].toString().equalsIgnoreCase("HomeStagesFragment"))
                {
                    new AlertDialog.Builder(this)
                            .setMessage("Are you sure you want to exit?")
                            .setCancelable(false)
                            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    finish();
                                }
                            })
                            .setNegativeButton("No", null)
                            .show();
                }

            }

no te olvides de definir esto en el encabezado:

private Fragment fragment;
FragmentTransaction tx;



Esta es una forma simple de obtener el fragmento actual ..

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  @Override public void onBackStackChanged() {
    currentFragment = fragmentManager.findFragmentById(R.id.content);
    if (currentFragment !=  null && (currentFragment instanceof LoginScreenFragment)) {
      logout.setVisibility(View.GONE);
    } else {
      logout.setVisibility(View.VISIBLE);
    }
  }
});



Related