Es allí una manera de conseguir referencias para todos los fragmentos activos en una Actividad?

No he encontrado una manera sencilla de que todos los activos actualmente (visible, actualmente en la Reanudación de estado) Fragmentos de una Actividad. Es posible, sin personalizado de la contabilidad en mi Actividad? Parece que el FragmentManager no admite esta característica.

  • ¿Cuál es su caso?

6 Kommentare

  1. 109

    Se parece a la API en la actualidad se pierde un método como «getFragments».

    Sin embargo, usando el evento «onAttachFragment» de la clase de Actividad que debería ser bastante fácil para hacer lo que quieres. Me gustaría hacer algo como:

    List<WeakReference<Fragment>> fragList = new ArrayList<WeakReference<Fragment>>();
    @Override
    public void onAttachFragment (Fragment fragment) {
        fragList.add(new WeakReference(fragment));
    }
    
    public List<Fragment> getActiveFragments() {
        ArrayList<Fragment> ret = new ArrayList<Fragment>();
        for(WeakReference<Fragment> ref : fragList) {
            Fragment f = ref.get();
            if(f != null) {
                if(f.isVisible()) {
                    ret.add(f);
                }
            }
        }
        return ret;
    }

    En caso de que no haya listo método para leer el estado del objeto (isActive() en el ejemplo), me gustaría reemplazar onResume y onPause para establecer un indicador (podría ser sólo un bool campo).

    Que ya algunas propias de la contabilidad, pero todavía muy limitado, en mi opinión, teniendo en cuenta la muy específicos objetivo que queremos conseguir (estado dependiente de la lista).

    • Hmm, ¿el WeakReference<Fragmento> ref vez null si no hay ninguna referencias a la real Fragmento que fue añadido a la lista en onAttachFragment?
    • Esto funciona muy bien para mis propósitos. PS yo tengo el de línea: si (f != null && f.isVisible()) { ret.añadir(f); }
    • No, ref misma no se convierta en nulo, solamente get() devuelve null si la actividad fue el recolector de basura. Por lo tanto la asignación de get() a una variable f y, a continuación, compruebe que el valor null es seguro.
    • Amaba la solución greatGoing
    • Como una solución similar me pasó a través de Fragment‘s onAttach y onDetach eventos para FragmentActivity a través de un largo interfaz de devolución de llamada (normalmente se utiliza para enviar notificaciones de selección del elemento en el fragmento). Los métodos agregar fragmentos y, a continuación, eliminarlos de la lista interna. Parece de trabajo sin necesidad de utilizar WeakReferences.
    • En realidad, el apoyo de la biblioteca expone un getFragments() método, pero no debe ser utilizado. Está marcado con el @hide y no debía ser incluido con el apoyo de la biblioteca de la jarra. No se debe considerar como parte de la API exportadas.
    • Y cómo hacer que funcione para los Fragmentos que contienen sub Fragmentos ?
    • Por cierto, mirando el código android, parece que esto va a dar solamente el primer nivel de los fragmentos, no anidados fragmentos.
    • No debería la lista de fragmento de referencias actualizadas, si un fragmento desprendido? De lo contrario podría haber Fragmentos en esa lista, que ya ha desaparecido (o al menos no en la pantalla más).

  2. 14

    Si utiliza Android Support Library, entonces usted puede llamar a escondidas FragmentManager.getFragments() método:

    public List<Fragment> getVisibleFragments() {
        List<Fragment> allFragments = getSupportFragmentManager().getFragments();
        if (allFragments == null || allFragments.isEmpty()) {
            return Collections.emptyList();
        }
    
        List<Fragment> visibleFragments = new ArrayList<Fragment>();
        for (Fragment fragment : allFragments) {
            if (fragment.isVisible()) {
                visibleFragments.add(fragment);
            }
        }
        return visibleFragments;
    }
    • No debemos usar este método. Está marcado con el @hide y no debía ser incluido con el apoyo de la biblioteca de la jarra. No se debe considerar como parte de la API exportadas.
    • Si usted está utilizando el apoyo de la biblioteca y conoce lo que está en el interior, usted puede llamar a cualquiera de los métodos que usted desea. Lo peor que puede pasar es que después de cambiar a una versión más reciente de la biblioteca a la que voy a obtener errores de compilación.
    • Una cosa importante que me gustaría destacar de este método para el futuro de los espectadores (que parece que has cubierto aquí) es que la devolución de los internos fragmento de la lista, y no una copia de la misma. Así que no modifique la lista de volver; crear una instancia de una nueva Lista a partir de la respuesta devuelta y modificar que uno. De lo contrario, vas a pasar un día entero de depuración de intermitentes IndexOutOfBoundsException. 🙂
    • Quiero señalar como @Michael se mencionó, el método ha sido eliminado.
    • Por lo que puedo ver, el método es aún visible, pero tiene un bug
    • Desde android.googlesource.com/platform/frameworks/support/+/… el método getFragments está restringido a las bibliotecas de la misma groupId y Android Lint lanzará una Pelusa de error si la vas a usar.
    • Sí, es verdad, pero estoy seguro de que el equipo Android tiene una buena razón para restringir el método de uso, por eso creo que no es una buena decisión, ignorando que de error. Por la forma en que el RestrictedApi es considerado como un error por defecto con prioridad 4/10 (tools.android.com/tips/lint-checks)

  3. 3

    Otra manera de hacer esto sería poner las etiquetas de los fragmentos cuando se agrega a la actividad.

    Por ejemplo, si se agrega dinámicamente 4 fragmentos, usted puede agregar como:

    for (int i = 0; i < NUM_FRAGMENTS; i++){
        MyFragment fragment = new Fragment(i);
        fragmentTransaction.add(R.id.containerId, fragment, SOME_CUSTOM_PREFIX + i).commit()
    }

    Entonces, si usted necesita para obtener todos los fragmentos más tarde, usted puede hacer:

    for (int i = 0; i < NUM_FRAGMENTS; i++) {
         String tag = SOME_CUSTOM_PREFIX + i;
         fragmentList.add((MyFragment) fragmentManager.findFragmentByTag(tag));
    }
  4. 1

    Me resuelve con esta:

    public ArrayList<Fragment> getAllFragments() {
        ArrayList<Fragment> lista = new ArrayList<Fragment>();
    
        for (Fragment fragment : getSupportFragmentManager().getFragments()) {
            try {
                fragment.getTag();
                lista.add(fragment);
            } catch (NullPointerException e) {
    
            }
        }
    
        return lista;
    
    }
    • Estoy implementando algo similar a esto y me estoy haciendo un NPE siempre que la actividad se recrea y fragmento.getTag() es llamado. ¿Sabes por qué el fragmento es null?
    • Lo sentimos, pero no. Trabajó simplemente para mí.
  5. 1

    android.support.v4.app.FragmentManager tiene un método llamado getFragments() que hace exactamente lo que usted necesita, pero nunca fue accesible. De repente, sin embargo, lo es, pero no estoy seguro si esa es la intención porque todavía marcados como ocultos.

    /**
     * Get a list of all fragments that have been added to the fragment manager.
     *
     * @return The list of all fragments or null if none.
     * @hide
     */
    public abstract List<Fragment> getFragments();

    Regular android.app.FragmentManager no tiene este método en todo, pero si es realmente necesario, usted puede acceder al mismo objeto, consiguiendo que el campo mActive a través de la reflexión (tenga cuidado de no: a partir de la API de 26, su tipo es un SparseArray en lugar de List). Utilice a su propio riesgo 🙂

    • El método es público, pero tiene un bug
    • Null-comprobar durante la iteración de las revisiones.
    • Su disponible para android.app.FragmentManager!
  6. 0

    se pueden utilizar algunos irregular-pero-método legal

        ArrayList<Fragment> getActiveFragments() {
            Fragment f;
            final ArrayList<Fragment> fragments = new ArrayList<>();
            int i = 0;
            try {
                while ((f = getFragmentManager().getFragment(new Intent().putExtra("anyvalue", i++).getExtras(), "anyvalue")) != null) {
                    fragments.add(f);
                }
            } catch (IllegalStateException ex) {
    
            }
            return fragments;
        }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea