我有以下代码,用于设置片段的输入和退出动画。
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>
对所有其他动画使用相同的方法。在所有其他版本中工作正常,但问题仅在于Lollipop。当我们看到功能
时
setCustomAnimations (int enter, int exit, int popEnter, int popExit)
doc-link,
enter
和exit
工作正常,但“棒棒糖”中popEnter
和popExit
失败。
请指导我出现问题并提供适用于Android 2.3到5.1的兼容解决方案
更新
仔细观察,似乎动画就在那里,但持续时间没有效果。
答案 0 :(得分:3)
片段动画甚至在L之前就被破坏了 - 改变屏幕方向时会出现一些问题。
以下解决方案修复了L问题和早期方向更改问题。将它用作基础Fragment类。
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;
}
}
答案 1 :(得分:1)
你还可以在所有片段中尝试onCreateAnimator ..或者他们正在扩展的基础片段......
@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);
}
}
注意以上动画师都是预先定义的,R还有android.R
希望这会有所帮助 干杯!
答案 2 :(得分: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" />
你可以减少持续时间,但你会看到更少的动画。
答案 3 :(得分: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();
}
答案 4 :(得分:0)
这是工作解决方案: 修改版@jskierbi回答。
import android.support.v4.app.Fragment;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
/**
* @author : Pedramrn@gmail.com 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();