动画片段之间的过渡

我正在尝试动画片段之间的过渡。我从下面的
得到答案 Android Fragments和动画 < / p >

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。anm。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)
< p >任何想法?当我检查蜂窝API引用translate在那里。我错过了什么?< br > 有没有其他方法来动画片段之间的过渡? 谢谢你

319828 次浏览

你需要对FragmentTransaction.setCustomAnimationsFragmentTransaction.setTransition使用新的android.animation框架(对象动画器)。

下面是一个从ApiDemos的FragmentHideShow.java中使用setCustomAnimations的例子:

ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);

下面是来自res /动画/ 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>组合多个动画器,就像使用旧的动画框架一样。


编辑:既然人们在问滑动式/滑动式,我将在这里对此进行评论。

滑进滑出

当然,你可以对translationXtranslationYxy属性进行动画化,但通常幻灯片涉及到对屏幕外的内容进行动画化。据我所知,没有任何转换属性使用相对值。但是,这并不妨碍您自己编写它们。记住,属性动画只需要在你动画的对象(在本例中是视图)上使用getter和setter方法,所以你可以在你的视图子类上使用创建自己的 getXFractionsetXFraction方法,如下所示:

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

注意,如果你在其中进行动画的对象与它的父对象宽度不同,事情看起来就不太对,所以你可能需要调整你的属性实现来适应你的用例。

Nurik的答案是非常有用的,但我不能让它工作,直到我找到。简而言之,如果您正在使用兼容性库(例如SupportFragmentManager而不是FragmentManager), XML动画文件的语法将有所不同。

FragmentTransaction的Android SDK实现需要Animator,而支持库需要Animation,不要问我为什么,但在strangeluk的评论之后,我查看了Android 4.0.3代码和支持库。 Android SDK使用loadAnimator(),支持库使用loadAnimation()

下面是片段之间的幻灯片进出动画:

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.enter_anim, R.animator.exit_anim);
transaction.replace(R.id.listFragment, new YourFragment());
transaction.commit();

我们正在使用一个objectAnimator。

下面是动画师子文件夹中的两个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>

我希望这能帮助到一些人。

如果你能负担得起只把自己绑在棒棒糖上,这似乎很管用:

import android.transition.Slide;
import android.util.Log;
import android.view.Gravity;
.
.
.
f = new MyFragment();
f.setEnterTransition(new Slide(Gravity.END));
f.setExitTransition(new Slide(Gravity.START));
getFragmentManager()
.beginTransaction()
.replace(R.id.content, f, FRAG_TAG)  // FRAG_TAG is the tag for your fragment
.commit();

芬兰湾的科特林版:

f = MyFragment().apply {
enterTransition = Slide(Gravity.END)
exitTransition = Slide(Gravity.START)
}
fragmentManager
.beginTransaction()
.replace(R.id.content, f, FRAG_TAG)  // FRAG_TAG is the tag for your fragment
.commit();

希望这能有所帮助。

我是这样做的:

动画将这个方法添加到取代片段:

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>

输出:

enter image description here

它的完成

对于其他任何被捕获的人,确保在构建事务时调用replace/add之前调用setCustomAnimations。

尝试使用这个简单快速的解决方案。Android提供了一些默认的__abc。

fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

输出:

enter image description here

为了给这个老问题添加一个更现代的答案,如果你已经转移到材料设计,这可以很容易地使用提供的运动库来完成——更多细节在https://material.io/develop/android/theming/motion