我正在尝试动画片段之间的过渡。我从下面得到了答案 Android Fragments and animation
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
DetailsFragment newFragment = DetailsFragment.newInstance();
ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");
// Start the animated transition.
ft.commit();
我的R.anim.slide_in_left
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="50%p" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
但是当我尝试这个时,显示
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): FATAL EXCEPTION: main
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): java.lang.RuntimeException: Unknown animator name: translate
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:129)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:126)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:93)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:72)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.loadAnimator(FragmentManager.java:621)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:733)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.BackStackRecord.run(BackStackRecord.java:578)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1217)
有什么想法吗?当我检查Honeycomb API时,参考translate
就在那里。我错过了什么?
有没有其他方法来动画片段之间的过渡?
谢谢
答案 0 :(得分:335)
您需要将新的android.animation
框架(对象动画制作者)与FragmentTransaction.setCustomAnimations
以及FragmentTransaction.setTransition
一起使用。
以下是使用ApiDemos'{strong> FragmentHideShow.java 中的setCustomAnimations
的示例:
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
这是来自 res / animator / fade_in.xml 的相关动画XML:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad"
android:valueFrom="0"
android:valueTo="1"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
请注意,您可以使用<set>
组合多个动画师,就像使用较旧的动画框架一样。
编辑:由于人们在询问插入/滑出,我会在这里发表评论。
您当然可以为translationX
,translationY
,x
和y
属性设置动画,但通常幻灯片涉及在屏幕外设置内容动画。据我所知,没有任何使用相对值的过渡属性。但是,这并不妨碍您自己编写它们。请记住,属性动画只需要在您正在制作动画的对象上使用getter和setter方法(在本例中为视图),这样您就可以创建自己的 getXFraction
和setXFraction
方法在您的视图子类上,如下所示:
public class MyFrameLayout extends FrameLayout {
...
public float getXFraction() {
return getX() / getWidth(); // TODO: guard divide-by-zero
}
public void setXFraction(float xFraction) {
// TODO: cache width
final int width = getWidth();
setX((width > 0) ? (xFraction * width) : -9999);
}
...
}
现在您可以为'xFraction'属性设置动画,如下所示:
<强> RES /动画/ slide_in.xml 强>:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:valueFrom="-1.0"
android:valueTo="0"
android:propertyName="xFraction"
android:duration="@android:integer/config_mediumAnimTime" />
请注意,如果你动画的对象宽度与其父对象的宽度不同,那么事情看起来不太合适,所以你可能需要调整你的属性实现以适应你的用例。
答案 1 :(得分:157)
我这样做了:
将此方法添加到替换片段与动画:
public void replaceFragmentWithAnimation(android.support.v4.app.Fragment fragment, String tag){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
transaction.replace(R.id.fragment_container, fragment);
transaction.addToBackStack(tag);
transaction.commit();
}
您必须在动画文件夹中添加 四个动画 关联与资源强>:
<强> enter_from_left.xml 强>:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
<强> exit_to_right.xml 强>:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700" />
</set>
<强> enter_from_right.xml 强>:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700" />
</set>
<强> exit_to_left.xml 强>:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
<强>输出:强>
完成。
答案 2 :(得分:49)
如果你有能力将自己绑在Lollipop之后,这似乎可以解决问题:
import android.transition.Slide;
import android.util.Log;
import android.view.Gravity;
.
.
.
f = new MyFragment();
f.setEnterTransition(new Slide(Gravity.RIGHT));
f.setExitTransition(new Slide(Gravity.LEFT));
getFragmentManager()
.beginTransaction()
.replace(R.id.content, f, FRAG_TAG) // FRAG_TAG is the tag for your fragment
.commit();
希望这有帮助。
答案 3 :(得分:47)
Nurik的答案非常有帮助,但在找到this之前我无法让它工作。简而言之,如果您使用兼容性库(例如SupportFragmentManager而不是FragmentManager),则XML动画文件的语法将有所不同。
答案 4 :(得分:25)
这是片段之间的幻灯片放入/缩小动画:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.enter_anim, R.animator.exit_anim);
transaction.replace(R.id.listFragment, new YourFragment());
transaction.commit();
我们正在使用objectAnimator。
以下是 animator 子文件夹中的两个xml文件。
<强> enter_anim.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="x"
android:valueFrom="2000"
android:valueTo="0"
android:valueType="floatType" />
</set>
<强> exit_anim.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="x"
android:valueFrom="0"
android:valueTo="-2000"
android:valueType="floatType" />
</set>
我希望这会对某人有所帮助。
答案 5 :(得分:19)
对于其他被捕的人,请确保在构建事务时调用replace / add之前调用setCustomAnimations。
答案 6 :(得分:12)
FragmentTransaction的Android SDK实现想要一个Animator
,而支持库想要一个Animation
,不要问我为什么但是在missluk的评论之后我调查了android 4.0.3代码和支持库。
Android SDK使用loadAnimator()
并支持库使用loadAnimation()
答案 7 :(得分:0)
为了为这个老问题添加一个更现代的答案,如果您已转向 Material Design,则可以使用提供的动画库轻松完成此操作——更多详情请访问 https://material.io/develop/android/theming/motion。