Los fragmentos anidados desaparecen durante la animación de transición


Aquí está el escenario: Activity contiene fragment A, que a su vez usa getChildFragmentManager() para agregar fragmentos A1 y A2 en su onCreate así:

getChildFragmentManager()
  .beginTransaction()
  .replace(R.id.fragmentOneHolder, new FragmentA1())
  .replace(R.id.fragmentTwoHolder, new FragmentA2())
  .commit()

Hasta ahora, todo está funcionando como se esperaba.

Luego ejecutamos la siguiente transacción en la Actividad:

getSupportFragmentManager()
  .beginTransaction()
  .setCustomAnimations(anim1, anim2, anim1, anim2)
  .replace(R.id.fragmentHolder, new FragmentB())
  .addToBackStack(null)
  .commit()

Durante la transición, las animaciones enter para fragment B se ejecutan correctamente, pero los fragmentos A1 y A2 desaparecen por completo. Cuando revertimos la transacción con el botón Atrás, inicializar correctamente y mostrar normalmente durante la animación popEnter.

En mi breve prueba, se puso más extraño: si establezco las animaciones para los fragmentos secundarios (ver más abajo), la animación exit se ejecuta de forma intermitente cuando agregamos fragment B

getChildFragmentManager()
  .beginTransaction()
  .setCustomAnimations(enter, exit)
  .replace(R.id.fragmentOneHolder, new FragmentA1())
  .replace(R.id.fragmentTwoHolder, new FragmentA2())
  .commit()

El efecto que quiero lograr es simple - Quiero el exit (o debería ser popExit?) animación en fragment A (anim2) a ejecutar, animando todo el contenedor, incluyendo sus hijos anidados.

¿hay alguna manera de lograr que?

Editar : Por favor, encuentre un caso de prueba aquí

Edit2: Gracias a @StevenByle por empujarme a seguir intentando con las animaciones estáticas. Al parecer, puede establecer animaciones en una base per-op (no global a toda la transacción), lo que significa que los hijos pueden tener un conjunto de animación estática indefinida, mientras que sus padres pueden tener una animación diferente y todo puede confirmarse en una transacción. Ver la discusión a continuación y el proyecto de caso de prueba actualizado.

Author: Fllo, 2013-02-15

13 answers

Para evitar que el usuario vea desaparecer los fragmentos anidados cuando se elimina/reemplaza el fragmento padre en una transacción, podría "simular" esos fragmentos que aún están presentes proporcionando una imagen de ellos, tal como aparecieron en la pantalla. Esta imagen se utilizará como fondo para el contenedor de fragmentos anidados, por lo que incluso si las vistas del fragmento anidado desaparecen, la imagen simulará su presencia. Además, no veo perder la interactividad con el fragmento anidado las vistas como un problema porque no creo que quieras que el usuario actúe sobre ellas cuando están en proceso de ser eliminadas(probablemente como una acción del usuario también).

He hecho un pequeño ejemplo con la configuración de la imagen de fondo(algo básico).

 33
Author: Luksprog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-22 05:53:28

Así que parece que hay muchas soluciones diferentes para esto, pero basado en la respuesta de @Jayd16, creo que he encontrado una solución bastante sólida que aún permite animaciones de transición personalizadas en fragmentos secundarios, y no requiere hacer una caché de mapa de bits del diseño.

Tenga una clase BaseFragment que extienda Fragment, y haga que todos sus fragmentos extiendan esa clase (no solo fragmentos secundarios).

En esa clase BaseFragment, añádase lo siguiente:

// Arbitrary value; set it to some reasonable default
private static final int DEFAULT_CHILD_ANIMATION_DURATION = 250;

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    final Fragment parent = getParentFragment();

    // Apply the workaround only if this is a child fragment, and the parent
    // is being removed.
    if (!enter && parent != null && parent.isRemoving()) {
        // This is a workaround for the bug where child fragments disappear when
        // the parent is removed (as all children are first removed from the parent)
        // See https://code.google.com/p/android/issues/detail?id=55228
        Animation doNothingAnim = new AlphaAnimation(1, 1);
        doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
        return doNothingAnim;
    } else {
        return super.onCreateAnimation(transit, enter, nextAnim);
    }
}

private static long getNextAnimationDuration(Fragment fragment, long defValue) {
    try {
        // Attempt to get the resource ID of the next animation that
        // will be applied to the given fragment.
        Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim");
        nextAnimField.setAccessible(true);
        int nextAnimResource = nextAnimField.getInt(fragment);
        Animation nextAnim = AnimationUtils.loadAnimation(fragment.getActivity(), nextAnimResource);

        // ...and if it can be loaded, return that animation's duration
        return (nextAnim == null) ? defValue : nextAnim.getDuration();
    } catch (NoSuchFieldException|IllegalAccessException|Resources.NotFoundException ex) {
        Log.w(TAG, "Unable to load next animation from parent.", ex);
        return defValue;
    }
}

Lo hace, desafortunadamente, requiere reflexión; sin embargo, dado que esta solución es para la biblioteca de soporte, no corre el riesgo de que la implementación subyacente cambie a menos que actualice su biblioteca de soporte. Si está creando la biblioteca de soporte desde el código fuente, podría agregar un accesor para el siguiente ID de recurso de animación a Fragment.java y eliminar la necesidad de reflexión.

Esta solución elimina la necesidad de "adivinar" la duración de la animación del padre (para que la animación" no hacer nada " tenga la misma duración como la animación de salida del padre), y le permite seguir haciendo animaciones personalizadas en fragmentos secundarios (por ejemplo, si está intercambiando fragmentos secundarios con diferentes animaciones).

 65
Author: kcoppock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-24 17:44:49

Fui capaz de llegar a una solución bastante limpia. IMO es el menos hackeado, y aunque esta es técnicamente la solución de "dibujar un mapa de bits", al menos está abstraída por la liberación de fragmentos.

Asegúrese de que sus fragmentos hijo anulan una clase padre con esto:

private static final Animation dummyAnimation = new AlphaAnimation(1,1);
static{
    dummyAnimation.setDuration(500);
}

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if(!enter && getParentFragment() != null){
        return dummyAnimation;
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}

Si tenemos una animación de salida en los fragmentos secundarios, se animarán en lugar de parpadear. Podemos explotar esto al tener una animación que simplemente dibuja los fragmentos secundarios en alfa completa durante una duración. Por aquí, permanecerán visibles en el fragmento padre mientras se anima, dando el comportamiento deseado.

El único problema que se me ocurre es hacer un seguimiento de esa duración. Tal vez podría configurarlo en un número grande, pero me temo que podría tener problemas de rendimiento si sigue dibujando esa animación en algún lugar.

 28
Author: Jayd16,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-27 01:51:48

Estoy publicando mi solución para mayor claridad. La solución es bastante simple. Si está tratando de imitar la animación de transacción de fragmentos del padre, simplemente agregue una animación personalizada a la transacción de fragmento hijo con la misma duración. Oh y asegúrate de establecer la animación personalizada antes de add ().

getChildFragmentManager().beginTransaction()
        .setCustomAnimations(R.anim.none, R.anim.none, R.anim.none, R.anim.none)
        .add(R.id.container, nestedFragment)
        .commit();

El xml para R. anim.ninguno (El tiempo de animación de entrada/salida de mis padres es de 250 ms)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="0" android:duration="250" />
</set>
 14
Author: Maurycy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-16 00:35:50

Entiendo que esto puede no ser capaz de resolver completamente su problema, pero tal vez se adapte a las necesidades de otra persona, puede agregar enter/exit y popEnter/popExit animaciones para sus hijos Fragments que en realidad no mueven/animan los Fragments. Siempre y cuando las animaciones tengan la misma duración/desplazamiento que sus animaciones padre Fragment, parecerán mover/animar con la animación del padre.

 7
Author: Steven Byle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-21 14:40:34

@@@@@@@@@@@@@@@@@@@@@@@@@@@@

EDITAR: Terminé sin aplicar esta solución ya que había otros problemas que esto tiene. Square recientemente salió con 2 bibliotecas que reemplazan fragmentos. Yo diría que esto podría ser en realidad una mejor alternativa que tratar de hackear fragmentos en hacer algo que Google no quiere que hagan.

Http://corner.squareup.com/2014/01/mortar-and-flow.html

@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Pensé en poner esto solución para ayudar a las personas que tienen este problema en el futuro. Si rastrea la conversación del póster original con otras personas y mira el código que publicó, verá que el póster original finalmente llega a la conclusión de usar una animación no operativa en los fragmentos secundarios mientras anima el fragmento principal. Esta solución no es ideal, ya que le obliga a realizar un seguimiento de todos los fragmentos secundarios, lo que puede ser engorroso cuando se utiliza un ViewPager con FragmentPagerAdapter.

Dado que uso Fragmentos de Niños por todas partes, se me ocurrió esta solución que es eficiente y modular (por lo que se puede quitar fácilmente) en caso de que alguna vez lo arreglen y esta animación no operativa ya no sea necesaria.

Hay muchas maneras de implementar esto. Elegí usar un singleton, y lo llamo ChildFragmentAnimationManager. Básicamente hará un seguimiento de un fragmento hijo para mí basado en su padre y aplicará una animación no operativa a los niños cuando se les preguntó.

public class ChildFragmentAnimationManager {

private static ChildFragmentAnimationManager instance = null;

private Map<Fragment, List<Fragment>> fragmentMap;

private ChildFragmentAnimationManager() {
    fragmentMap = new HashMap<Fragment, List<Fragment>>();
}

public static ChildFragmentAnimationManager instance() {
    if (instance == null) {
        instance = new ChildFragmentAnimationManager();
    }
    return instance;
}

public FragmentTransaction animate(FragmentTransaction ft, Fragment parent) {
    List<Fragment> children = getChildren(parent);

    ft.setCustomAnimations(R.anim.no_anim, R.anim.no_anim, R.anim.no_anim, R.anim.no_anim);
    for (Fragment child : children) {
        ft.remove(child);
    }

    return ft;
}

public void putChild(Fragment parent, Fragment child) {
    List<Fragment> children = getChildren(parent);
    children.add(child);
}

public void removeChild(Fragment parent, Fragment child) {
    List<Fragment> children = getChildren(parent);
    children.remove(child);
}

private List<Fragment> getChildren(Fragment parent) {
    List<Fragment> children;

    if ( fragmentMap.containsKey(parent) ) {
        children = fragmentMap.get(parent);
    } else {
        children = new ArrayList<Fragment>(3);
        fragmentMap.put(parent, children);
    }

    return children;
}

}

A continuación, necesita tener una clase que extienda el Fragmento que todos sus Fragmentos extienden (al menos sus Fragmentos Secundarios). Yo ya tenía esta clase, y yo la llamo BaseFragment. Cuando se crea una vista de fragmentos, la añadimos a ChildFragmentAnimationManager y la eliminamos cuando se destruye. Puede hacer esto onAttach / Detach,u otros métodos de coincidencia en la secuencia. Mi lógica para elegir Crear / Destruir vista era porque si un fragmento no tiene una vista, no te preocupes por animarlo para seguir siendo visto. Este enfoque también debería funcionar mejor con ViewPagers que usan Fragmentos, ya que no estará haciendo un seguimiento de cada Fragmento que tenga un FragmentPagerAdapter, sino solo 3.

public abstract class BaseFragment extends Fragment {

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

    Fragment parent = getParentFragment();
    if (parent != null) {
        ChildFragmentAnimationManager.instance().putChild(parent, this);
    }

    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onDestroyView() {
    Fragment parent = getParentFragment();
    if (parent != null) {
        ChildFragmentAnimationManager.instance().removeChild(parent, this);
    }

    super.onDestroyView();
}

}

Ahora que todos sus Fragmentos están almacenados en la memoria por el fragmento padre, puede llamar a animate sobre ellos de esta manera, y sus fragmentos hijos no desaparecerán.

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ChildFragmentAnimationManager.instance().animate(ft, ReaderFragment.this)
                    .setCustomAnimations(R.anim.up_in, R.anim.up_out, R.anim.down_in, R.anim.down_out)
                    .replace(R.id.container, f)
                    .addToBackStack(null)
                    .commit();

También, para que lo tengas, aquí está el no_anim.archivo xml que va en su carpeta res / anim:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <translate android:fromXDelta="0" android:toXDelta="0"
        android:duration="1000" />
</set>

Nuevamente, no creo que esta solución sea perfecta, pero es mucho mejor que para cada instancia que tenga un Fragmento Hijo, implementando código personalizado en el fragmento padre para realizar un seguimiento de cada hijo. He estado allí, y no es divertido.

 2
Author: spierce7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-16 18:17:44

Estaba teniendo el mismo problema con map fragment. Siguió desapareciendo durante la animación de salida de su fragmento que lo contenía. La solución es agregar animación para el fragmento de mapa hijo que lo mantendrá visible durante la animación de salida del fragmento padre. La animación del fragmento hijo mantiene su alfa al 100% durante su período de duración.

Animación: res/animator/keep_child_fragment.xml

<?xml version="1.0" encoding="utf-8"?>    
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="alpha"
        android:valueFrom="1.0"
        android:valueTo="1.0"
        android:duration="@integer/keep_child_fragment_animation_duration" />
</set>

La animación se aplica cuando el mapa el fragmento se añade al fragmento padre.

Fragmento padre

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

    View view = inflater.inflate(R.layout.map_parent_fragment, container, false);

    MapFragment mapFragment =  MapFragment.newInstance();

    getChildFragmentManager().beginTransaction()
            .setCustomAnimations(R.animator.keep_child_fragment, 0, 0, 0)
            .add(R.id.map, mapFragment)
            .commit();

    return view;
}

Finalmente, la duración de la animación del fragmento hijo se establece en un archivo de recursos.

Valores / enteros.xml

<resources>
  <integer name="keep_child_fragment_animation_duration">500</integer>
</resources>
 1
Author: Evgenii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-25 05:59:57

Puede hacer esto en el fragmento hijo.

@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
    if (true) {//condition
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(getView(), "alpha", 1, 1);
        objectAnimator.setDuration(333);//time same with parent fragment's animation
        return objectAnimator;
    }
    return super.onCreateAnimator(transit, enter, nextAnim);
}
 1
Author: peng gao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-14 07:42:04

Creo que he encontrado una mejor solución a este problema que snapshotear el fragmento actual a un mapa de bits como sugirió Luksprog.

El truco es ocultar el fragmento que se está eliminando o separando y solo después de que se hayan completado las animaciones, el fragmento se elimina o separará en su propia transacción de fragmento.

Imagina que tenemos FragmentA y FragmentB, ambos con fragmentos secundarios. Ahora, cuando normalmente haría:

getSupportFragmentManager()
  .beginTransaction()
  .setCustomAnimations(anim1, anim2, anim1, anim2)
  .add(R.id.fragmentHolder, new FragmentB())
  .remove(fragmentA)    <-------------------------------------------
  .addToBackStack(null)
  .commit()

En su lugar lo haces

getSupportFragmentManager()
  .beginTransaction()
  .setCustomAnimations(anim1, anim2, anim1, anim2)
  .add(R.id.fragmentHolder, new FragmentB())
  .hide(fragmentA)    <---------------------------------------------
  .addToBackStack(null)
  .commit()

fragmentA.removeMe = true;

Ahora para el implementación del Fragmento:

public class BaseFragment extends Fragment {

    protected Boolean detachMe = false;
    protected Boolean removeMe = false;

    @Override
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
        if (nextAnim == 0) {
            if (!enter) {
                onExit();
            }

            return null;
        }

        Animation animation = AnimationUtils.loadAnimation(getActivity(), nextAnim);
        assert animation != null;

        if (!enter) {
            animation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    onExit();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
        }

        return animation;
    }

    private void onExit() {
        if (!detachMe && !removeMe) {
            return;
        }

        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        if (detachMe) {
            fragmentTransaction.detach(this);
            detachMe = false;
        } else if (removeMe) {
            fragmentTransaction.remove(this);
            removeMe = false;
        }
        fragmentTransaction.commit();
    }
}
 0
Author: Danilo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-08 02:23:34

Para animar la desaparición de fragmentos neasted podemos forzar pop back stack en ChildFragmentManager. Esto activará la animación de transición. Para hacer esto necesitamos ponernos al día en el evento Backbuttonpressed o escuchar los cambios de backstack.

Aquí hay un ejemplo con código.

View.OnClickListener() {//this is from custom button but you can listen for back button pressed
            @Override
            public void onClick(View v) {
                getChildFragmentManager().popBackStack();
                //and here we can manage other fragment operations 
            }
        });

  Fragment fr = MyNeastedFragment.newInstance(product);

  getChildFragmentManager()
          .beginTransaction()
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
                .replace(R.neasted_fragment_container, fr)
                .addToBackStack("Neasted Fragment")
                .commit();
 0
Author: Mateusz Biedron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-21 13:54:47

Recientemente me encontré con este problema en mi pregunta: Los fragmentos anidados transitan incorrectamente

Tengo una solución que resuelve esto sin guardar un mapa de bits, ni usar reflexión o cualquier otro método insatisfactorio.

Un proyecto de ejemplo se puede ver aquí: https://github.com/zafrani/NestedFragmentTransitions

Un GIF del efecto se puede ver aquí: https://imgur.com/94AvrW4

En mi ejemplo hay 6 fragmentos de niños, divida entre dos fragmentos principales. Soy capaz de lograr las transiciones para entrar, salir, pop y push sin ningún problema. También se gestionan con éxito los cambios de configuración y las rotativas de retroceso.

La mayor parte de la solución está en la función de mi fragmento base (el fragmento extendido por mis fragmentos hijos y padres) onCreateAnimator que se ve así:

   override fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator {
    if (isConfigChange) {
        resetStates()
        return nothingAnim()
    }

    if (parentFragment is ParentFragment) {
        if ((parentFragment as BaseFragment).isPopping) {
            return nothingAnim()
        }
    }

    if (parentFragment != null && parentFragment.isRemoving) {
        return nothingAnim()
    }

    if (enter) {
        if (isPopping) {
            resetStates()
            return pushAnim()
        }
        if (isSuppressing) {
            resetStates()
            return nothingAnim()
        }
        return enterAnim()
    }

    if (isPopping) {
        resetStates()
        return popAnim()
    }

    if (isSuppressing) {
        resetStates()
        return nothingAnim()
    }

    return exitAnim()
}

La actividad y el fragmento padre son responsables de establecer los estados de estos booleanos. Es más fácil ver cómo y donde de mi proyecto de ejemplo.

No estoy usando fragmentos de soporte en mi ejemplo, pero la misma lógica se puede usar con ellos y su función onCreateAnimation

 0
Author: zafrani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-24 01:03:32

Una forma sencilla de solucionar este problema es usar la clase Fragment de esta biblioteca en lugar de la clase estándar library fragment:

Https://github.com/marksalpeter/contract-fragment

Como nota al margen, el paquete también contiene un patrón delegado útil llamado ContractFragment que puede resultar útil para crear sus aplicaciones aprovechando la relación de fragmento padre-hijo.

 0
Author: Mark Salpeter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-13 23:53:11

De la respuesta anterior de @kcoppock,

Si tiene Actividad->Fragmento->Fragmentos ( apilamiento múltiple, lo siguiente ayuda ), una edición menor a la mejor respuesta en mi humilde opinión.

public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {

    final Fragment parent = getParentFragment();

    Fragment parentOfParent = null;

    if( parent!=null ) {
        parentOfParent = parent.getParentFragment();
    }

    if( !enter && parent != null && parentOfParent!=null && parentOfParent.isRemoving()){
        Animation doNothingAnim = new AlphaAnimation(1, 1);
        doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
        return doNothingAnim;
    } else
    if (!enter && parent != null && parent.isRemoving()) {
        // This is a workaround for the bug where child fragments disappear when
        // the parent is removed (as all children are first removed from the parent)
        // See https://code.google.com/p/android/issues/detail?id=55228
        Animation doNothingAnim = new AlphaAnimation(1, 1);
        doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
        return doNothingAnim;
    } else {
        return super.onCreateAnimation(transit, enter, nextAnim);
    }
}
 0
Author: alekshandru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-06 19:07:36