Cómo lograr animaciones de transacciones de fragmentos suaves en Android
He trabajado principalmente con iOS y me he acostumbrado a las animaciones de cambio de pantalla muy fluidas y fluidas. Ahora estoy trabajando en una aplicación de Android y no puedo por la vida de mí obtener una transacción de fragmento suavemente añadir / reemplazar un fragmento.
Mi configuración es la siguiente: MainActivity
tiene un FrameLayout
para su xml que inmediatamente carga FragmentA
en MainActivity
la MainActivity
. Mi aplicación luego procede a reemplazar el MainActivity
de FrameLayout
con FragmentB
, FragmentC
, ect. Así que mi aplicación completa tiene 1 actividad.
- ¿Es mejor usar múltiples SpanObjects o múltiples TextViews en Android?
- Tiempo inactivo de actividad para ActivityRecord
- ¿Cuál es la principal ventaja y la desventaja de "no mantener las actividades" en android
- ¿Cómo afecta la profundidad de color y / o el nivel de compresión de las imágenes al rendimiento de la interfaz de usuario?
- WebView no carga la página web
En clics de botón llamo a lo siguiente para agregar / reemplazar el fragmento actual:
getFragmentManager() .beginTransaction() .setCustomAnimations(R.animator.slide_in, android.R.animator.fade_out, android.R.animator.fade_in, R.animator.slide_out) .addToBackStack(null) .add(R.id.fragment_1, fragment) .commit();
Slide_in.xml parece (slide_out.xml es obviamente lo contrario):
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:interpolator="@android:interpolator/linear" android:propertyName="xFraction" android:valueType="floatType" android:valueFrom="1.0" android:valueTo="0" android:duration="@android:integer/config_shortAnimTime" /> </set>
Deslizándose dentro y fuera Estoy animando xFraction que he subclasificado LinearLayout
para hacer así:
public class SlidingLinearLayout extends LinearLayout { private float yFraction = 0; private float xFraction = 0; public SlidingLinearLayout(Context context) { super(context); } public SlidingLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } public SlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } private ViewTreeObserver.OnPreDrawListener preDrawListener = null; public void setYFraction(float fraction) { this.yFraction = fraction; if (getHeight() == 0) { if (preDrawListener == null) { preDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(preDrawListener); setYFraction(yFraction); return true; } }; getViewTreeObserver().addOnPreDrawListener(preDrawListener); } return; } float translationY = getHeight() * fraction; setTranslationY(translationY); } public float getYFraction() { return this.yFraction; } public void setXFraction(float fraction) { this.xFraction = fraction; if (getWidth() == 0) { if (preDrawListener == null) { preDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(preDrawListener); setXFraction(xFraction); return true; } }; getViewTreeObserver().addOnPreDrawListener(preDrawListener); } return; } float translationX = getWidth() * fraction; setTranslationX(translationX); } public float getxFraction() { return xFraction; } }
Así que mi problema es la mayor parte del tiempo cuando inicialmente haga clic en un botón para agregar / reemplazar un fragmento, no tengo una animación que sólo una especie de pops en su lugar. Sin embargo más veces que no cuando presiono el botón de la parte posterior y el fragmento estallido de la backstack la animación se ejecuta según lo esperado. Siento que es un problema con la inicialización al tratar de animar. Cuando el fragmento está en la memoria y animado fuera de la pantalla hace mucho mejor que cuando se crea un nuevo fragmento y luego se anima a la pantalla. Estoy curioso si otros han experimentado esto y si es así cómo lo resolvieron.
Esta es una molestia que ha plagado mi experiencia de desarrollo de Android que realmente me gustaría poner a descansar! Cualquier ayuda sería muy apreciada. ¡Gracias!
- ¿Importa en qué orden llamo finish () y startActivity ()?
- Honeycomb Android emulador es perro lento - se manejará antes del lanzamiento oficial?
- La aplicación o la actividad lleva tiempo para cargarse algunas veces
- ListView MUY lento cuando se cargan imágenes (con Universal Image Loader)
- Problema "La prueba del repositorio tiene un error" al intentar importar el proyecto de bitbucket al android studio
- PercentRelativeLayout es más performante?
- Android adb velocidad usb
- Anulación de variables de Fragmento on onDestroy ()
En mi experiencia, si el fragmento está haciendo demasiado trabajo en la carga, entonces el sistema básicamente omitirá la animación de entrada y sólo mostrar el fragmento. En mi caso la solución era crear un oyente de animación en onCreateAnimation para esperar hasta que la animación de entrada terminara antes de hacer el trabajo intensivo del proceso que estaba causando que la animación se saltara.
@Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { if (nextAnim == 0) { return super.onCreateAnimation(transit, enter, nextAnim); } Animation anim = android.view.animation.AnimationUtils.loadAnimation(getContext(), nextAnim); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { // Do any process intensive work that can wait until after fragment has loaded } @Override public void onAnimationRepeat(Animation animation) {} }); return anim; }
- Cómo recibir un archivo usando NFC (Android Beam) en Android
- Android Studio INSTALL_FAILED_DEXOPT e INSTALL_FAILED_UID_CHANGED en la ejecución del proyecto