2015-04-07 134 views
24

我有下面的代码来设置片段的进入和退出动画。片段customAnimation不起作用在棒棒糖

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> 

用于其他所有动画相同的方法。在所有其他版本中工作正常,但问题仅限于棒棒糖。正如我们在看功能
setCustomAnimations (int enter, int exit, int popEnter, int popExit)doc-link
enterexit工作正常,但popEnterpopExit在棒棒糖失败。
请指导我,什么地方出了错,并提供在Android 2.3工程5.1兼容的解决方案

更新:

密切观察,似乎动画是存在的,但持续时间没有效果。

+0

您是否尝试过其他动画来检查问题出在这个特定的'slide_in_left.xml'一个? –

+0

另外,你测试过不同的设备?问题是否发生在模拟器上? –

+0

@Ricardo是的,我正在使用如此多的动画。除了棒棒糖中的“popEnter”和“popExit”之外,所有工作都很好。问题在于有棒棒糖的设备。没有尝试模拟器。 – Nizam

回答

1

,你还可以尝试onCreateAnimator所有fragments..or,他们正在扩大上述两种动画是预先定义和R有android.R

基片段...

@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); 
     } 
    } 

希望这会有所帮助 干杯!

3

即使在L之前片段动画也被打破 - 更改屏幕方向时会出现一些问题。

下面的解决方案解决了L问题和早期的方向更改问题。用它作为你的基础片段类。

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

STATE_ENTER_ANIM等的值是否是任意的,还是您从android源代码中获取它们?从缺乏upvotes我只能假设人们没有使用片段过渡动画那么多,很好的工作。 – enl8enmentnow

+0

不工作.... – Pedram

+0

我在很多项目中使用此代码,它的作用就像一个魅力:)什么是症状?你的用例是什么?你是如何创建你的片段交易的? – jskierbi

0

如果将持续时间设置为2000,则会看到动画,但我认为它太慢了。这是我的代码:

<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" /> 

你可以把时间少了,但你会看到更少的动画。

0

我找到其他的解决办法,它不是使完全一样的动画,但很相似,我喜欢这个动画比传统滑动,这是我的代码做动画:

 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

这里工作解决方案: @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> 

用法:

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();