2015-04-07 10 views
24

Ho sotto il codice per l'impostazione di entrare e uscire animazioni per i frammenti.Frammento personalizzatoAnimazione non funzionante in Lollipop

final FragmentManager manager = getSupportFragmentManager(); 
final FragmentTransaction ft = manager.beginTransaction(); 
    ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right); 
    ft.replace(R.id.container, fragment, tag); 
    ft.addToBackStack(tag); 
    ft.commitAllowingStateLoss(); 

slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?> 

<set xmlns:android="http://schemas.android.com/apk/res/android"> 

    <translate android:fromXDelta="-100%" 
    android:toXDelta="0%" 
    android:duration="@integer/slide_anim_duration" /> 

</set> 

Utilizzato stesso metodo per tutti gli altri le animazioni. Funziona bene in tutte le altre versioni, ma il problema è solo in Lollipop. Se guardiamo a alla funzione
setCustomAnimations (int enter, int exit, int popEnter, int popExit)doc-link,
enter e exit funziona bene, ma popEnter e popExit fallisce in Lollipop.
Per favore mi guida su cosa è andato storto e fornire una soluzione compatibile che funziona da Android 2.3 al 5,1

Aggiornamento:

Osservando da vicino, sembra che l'animazione è lì, ma la durata non ha alcun effetto

+0

Hai provato altre animazioni per verificare se il problema è in questo specifico 'slide_in_left.xml' uno? –

+0

Inoltre, hai provato su diversi dispositivi? Il problema si verifica su un emulatore? –

+0

@ Ricardo Sì, sto usando così tante animazioni come quella. Funzionano tutti bene tranne con 'popEnter' e' popExit' in lollipop. Il problema è nei dispositivi con Lollipop. Non ho provato l'emulatore. – Nizam

risposta

1

è possibile inoltre provare onCreateAnimator in tutta la fragments..or il frammento di base che stanno ampliando ...

@target_api 20 or higher 

@Override 
    public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) { 
     if (enter) { 
      return AnimatorInflater.loadAnimator(getActivity(), R.animator.slide_in_top); 
     } else { 
      return AnimatorInflater.loadAnimator(getActivity(), R.animator.fade_out); 
     } 
    } 

Nota entrambi animatori di cui sopra sono pre definiti e R c'è android.R

Spero che questo aiuti saluti!

3

Le animazioni dei frammenti sono interrotte anche prima di L - ci sono alcuni problemi quando si cambia l'orientamento dello schermo.

Sotto soluzione risolve entrambi i problemi L e precedenti problemi di modifica dell'orientamento. Usalo come classe Framment di base.

public abstract class AnimatedSupportFragment extends DaggerFragment { 

    private static final String STATE_ENTER_ANIM = "STATE_ENTER_ANIM"; 
    private static final String STATE_EXIT_ANIM = "STATE_EXIT_ANIM"; 
    private static final String STATE_POP_ENTER_ANIM = "STATE_POP_ENTER_ANIM"; 
    private static final String STATE_POP_EXIT_ANIM = "STATE_POP_EXIT_ANIM"; 
    private static final String STATE_CHANGING_CONFIGURATIONS = "STATE_CHANGING_CONFIGURATIONS"; 

    private @AnimRes int mEnter = 0; 
    private @AnimRes int mExit = 0; 
    private @AnimRes int mPopEnter = 0; 
    private @AnimRes int mPopExit = 0; 
    private boolean mIsChangingConfigurations = false; 

    public void setCustomAnimations(@AnimRes int enterAnim, 
            @AnimRes int exitAnim, 
            @AnimRes int popEnterAnim, 
            @AnimRes int popExitAnim) { 
     mEnter = enterAnim; 
     mExit = exitAnim; 
     mPopEnter = popEnterAnim; 
     mPopExit = popExitAnim; 
    } 

    @Override public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (savedInstanceState != null) { 
      mEnter = savedInstanceState.getInt(STATE_ENTER_ANIM); 
      mExit = savedInstanceState.getInt(STATE_EXIT_ANIM); 
      mPopEnter = savedInstanceState.getInt(STATE_POP_ENTER_ANIM); 
      mPopExit = savedInstanceState.getInt(STATE_POP_EXIT_ANIM); 
      mIsChangingConfigurations = savedInstanceState.getBoolean(STATE_CHANGING_CONFIGURATIONS); 
     } 
    } 

    @Override public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putInt(STATE_ENTER_ANIM, mEnter); 
     outState.putInt(STATE_EXIT_ANIM, mExit); 
     outState.putInt(STATE_POP_ENTER_ANIM, mPopEnter); 
     outState.putInt(STATE_POP_EXIT_ANIM, mPopExit); 
     outState.putBoolean(STATE_CHANGING_CONFIGURATIONS, mIsChangingConfigurations); 
    } 

    @Override public void onResume() { 
     super.onResume(); 
     mIsChangingConfigurations = false; 
    } 

    @Override public void onPause() { 
     super.onPause(); 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      mIsChangingConfigurations = getActivity().isChangingConfigurations(); 
     } 
    } 

    @SuppressLint("NewApi") 
    @Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 

     // This implementation fixes loosing transition animations on orientation changes: 
     // @see http://stackoverflow.com/questions/8837408/fragment-lost-transition-animation-after-configuration-change 
     // @see https://code.google.com/p/android/issues/detail?id=25994&can=4&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
      // Do not support animations PRE-3.0, isChangingConfigurations() is not available! 
      return null; 
     } 

     try { 
      int anim; 
      if (mIsChangingConfigurations) { 
       // Recreating after change configuration, we don't want to play animation 
       anim = 0; 
      } else if (nextAnim != 0) { 
       // Animation available (not lost) -> play it! 
       anim = nextAnim; 
      } else { 
       // Animation probably lost - load anim saved in fragment state. 
       // enter = we're about to play popEnterAnim, in other case popExitAnimation 
       anim = enter ? mPopEnter : mPopExit; 
      } 
      if (anim != 0) { 
       return AnimationUtils.loadAnimation(getActivity(), anim); 
      } 
     } catch (Exception ignore) {} 

     return null; 
    } 
} 
+0

I valori per STATE_ENTER_ANIM, ecc., Sono arbitrari o gli hai impedito di guardare il codice sorgente Android? Dalla mancanza di upvotes posso solo supporre che le persone non stiano usando le animazioni di transizione dei frammenti con un lavoro tanto bello. – enl8enmentnow

+0

Non funziona .... – Pedram

+0

Sto usando questo codice in molti progetti e funziona come un fascino :) Quali sono i sintomi? Qual è il tuo caso d'uso? Come hai creato la transazione del tuo frammento? – jskierbi

0

Se si imposta la durata a 2000, si vedrà l'animazione, ma penso che sia troppo lento. Questo è il mio codice:

<translate xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fromXDelta="-100%p" 
    android:toXDelta="0" 
    android:interpolator="@android:anim/decelerate_interpolator" 
    android:duration="2000" /> 

È possibile mettere meno la durata, ma si vedrà meno animazione.

0

trovo un altra soluzione, non fa esattamente la stessa animazione, ma è molto simile, mi piace questa animazione più che la slitta tradizionale questo è il mio codice per fare l'animazione:

 private Fragment fragment=new Fragment(); 
private FragmentManager fragmentManager=getSupportFragmentManager(); 


private void replaceFragmentWithAnimation(){ 
    FragmentTransaction ft = fragmentManager.beginTransaction(); 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && fragment != null) { 
      Slide slideLeft = new Slide(Gravity.RIGHT); 
      slideLeft.setDuration(300); 
      fragment.setExitTransition(slideLeft); 
     } 

     fragment = CalendarFragment.newInstance(selectedDays, plusMonths); 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      Slide slideRight = new Slide(Gravity.RIGHT); 
      slideRight.setDuration(350); 
      fragment.setEnterTransition(slideRight); 

     } else { 
      ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right); 
     } 
     ft.replace(calendarDaysContFL.getId(), fragment); 
     ft.commit(); 
    } 
0

Ecco la soluzione operativa: Versione modificata della risposta @jskierbi.

import android.support.v4.app.Fragment; 
import android.view.animation.Animation; 
import android.view.animation.AnimationUtils; 


/** 
* @author : [email protected] Created on: 2016-02-19 
*/ 
public class SupportBaseFragment extends Fragment { 

private boolean mIsChangingConfigurations = false; 
private static final String STATE_CHANGING_CONFIGURATIONS = "STATE_CHANGING_CONFIGURATIONS"; 

@Override 
public void onResume() { 
    super.onResume(); 
    mIsChangingConfigurations = false; 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    mIsChangingConfigurations = getActivity().isChangingConfigurations(); 
} 


@Override 
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 
    if (mIsChangingConfigurations) 
     return null; 
    if (enter) 
     return AnimationUtils.loadAnimation(getContext(), nextAnim == 0 ? R.anim.enter_pop : nextAnim); 
    else 
     return AnimationUtils.loadAnimation(getContext(), nextAnim == 0 ? R.anim.exit_pop : nextAnim); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (savedInstanceState != null) { 
     mIsChangingConfigurations = savedInstanceState.getBoolean(STATE_CHANGING_CONFIGURATIONS); 
    } 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putBoolean(STATE_CHANGING_CONFIGURATIONS, mIsChangingConfigurations); 
} 

enter.xml

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

enter_pop.xml

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

exit.xml

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

exit_pop.xml

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

Usage:

getSupportFragmentManager() 
       .beginTransaction() 
       .setCustomAnimations(R.anim.enter, R.anim.exit, 
         R.anim.enter_pop, R.anim.exit_pop) 
       .replace(R.id.fragment_container, myFancyFragment) 
       .addToBackStack(null) 
       .commit();