Fragment 标准转换没有动画效果

46
我正在使用v4 Android兼容性库,针对Android 2.2设备及以上,使用片段来开发平板电脑UI。

一切都按照预期工作,除了我无法使任何动画效果工作,甚至标准动画也不行。

代码:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    ABCFragment abcFragment = new ABCFragment();
    ft.replace(R.id.main_frame_layout_fragment_holder,abcFragment);     
    ft.addToBackStack(null);
    ft.commit();

不要使用过渡动画,该片段会冻结约一秒钟,然后突然消失,新的片段出现。

使用:

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

同样不起作用。

XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.synergygb.mycustomapp"
android:id="@+id/LinearLayout01" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical"
android:gravity="bottom">
<FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/main_frame_layout_fragment_holder">
</FrameLayout>
<!-- OTHER FIXED UI ELEMENTS-->
</RelativeLayout>

我读到自定义动画在兼容库中是有问题的,但似乎没有人在标准转换方面遇到问题。我已经在3.2.1摩托罗拉Xoom、2.3 Galaxy Tab 7"、2.2模拟器,甚至是带有2.3.4的HTC G2上进行了测试。

这里可能出了什么问题?


Dalvik(调试器)有什么输出信息吗? - IAmYourFaja
你有任何logcat输出可以提供给我们吗? - Kurtis Nusbaum
没有任何提示,这就是我迷失的原因。没有错误。Logcat 没有显示任何内容。只是系统的常规回调,与应用内发生的变化无关。 检查 mTransition 的值为 4099。 该值由以下代码设置: ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); - blindstuff
我在另一台电脑上设置了整个开发环境,结果相同。 - blindstuff
刚刚更新了兼容性包,结果还是一样。我正在使用2.2的Google API进行构建。 - blindstuff
6个回答

38

经过多次尝试,我终于让它正常工作了。

首先和最重要的是,获取最新的ACL(Access Control List),这确实修复了自定义动画问题,虽然这不是我的确切问题,但一旦这些功能可用,我就使用它们代替标准转换。

现在我正在使用:

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

让它在Android 2.1、2.2和2.3以及Android 3.0+上正常工作的关键是执行以下操作:

  • 确保仅使用最低API级别可用的API(在我的情况下为2.1)。
  • 使用Android 3.0进行编译。
  • 在清单文件中,在应用程序标签内设置 android:hardwareAccelerated="true"

现在,片段动画可以在所有设备上工作了。如果您没有在应用程序标签中设置额外的信息,则动画将以非常卡顿的方式发生,使其看起来好像根本没有发生过。

希望这能对未来的某些人有所帮助!

请注意,有一些API检查工具,因此您可以确保不使用任何不适用于您的API。我喜欢使用2.1进行开发,这样IDE就不会显示我不能使用的任何内容,一旦我有了稳定的代码,就会跳回到3.0进行编译。


感谢您的答案,我在SII、HTC Evo、Nexus Galaxy和SIII上进行了测试,很遗憾看到Nexus在动画方面存在滞后的问题,但是使用硬件标签后一切都符合预期 :) - Goofyahead
@blindstuff 如果你没有在使用比你所支持的最低API级别更高的任何代码,则无需针对更新的API进行编译。针对更新的API进行编译唯一提供的好处是可以访问新的类和方法。 - Christopher Perry
2
你需要在3.0或以上版本中编译,才能让android:hardwareAccelerated="true"被识别。 - blindstuff

35

再次尝试获取最新的ACL,他们已经解决了这个问题: http://code.google.com/p/android/issues/detail?id=15623#c19

此外我注意到,对于setCustomAnimations,它需要在事务调用(如replace)之前设置才能生效。

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.in_from_left, R.anim.out_to_right, R.anim.in_from_right, R.anim.out_to_left);
ft.replace(android.R.id.content, newFrag);
ft.addToBackStack(null);
ft.commit();

我已经完成了您所描述的两件事情,因为我在评论中提到了这一点,以便对我的问题进行跟进。我已经让它工作了,但是在我给出不确定的答案之前,我只是在测试。我已经让它在Galaxy Tab上工作了,但在XOOM上,动画看起来像垃圾。 - blindstuff
抱歉,我不能评论其他人的帖子(声望不够)。不过很高兴听到你解决了问题! - dvd
感谢您的帮助,点了个赞。使用ft.setCustomAnimations(R.anim.in_from_left, R.anim.out_to_right, R.anim.in_from_right, R.anim.out_to_left);而不仅仅是ft.setCustomAnimations(R.anim.in_from_left, R.anim.out_to_right);非常有帮助。 - blindstuff
11
这对我解决了问题。这个神秘的“先调用”依赖关系非常愚蠢,如果你不能做一个合适的构建器模式,那就不要做它。 - soren.qvist
1
“call-before” 的存在是因为一个事务可能有多个操作,每个操作都有不同的动画效果。 - mark.kedzierski
1
@mark.kedzierski 这使得API与生成器模式不一致。应该有一个单独的生成器来构建操作和它们的属性,例如添加片段+动画、替换片段+动画等。然后再将它们添加到整个片段事务中。 - dvd

5

您必须在添加片段之前调用setCustomAnimations,以便添加具有不同动画的多个片段。


谢谢@greg-ennis,我差点就要疯了。 - J.C

4

执行片段的自上而下动画,

按照同样的方法来实现自上而下。

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.top_to_bottom_fragment,
android.R.animator.fade_out); ft.replace(R.id.simple_fragment,
fragment); 
ft.commit();

top_to_bottom_fragment.xml

<objectAnimator android:duration="400" android:valueFrom="-800"
    android:valueTo="0" android:propertyName="y"
    android:valueType="floatType"
    xmlns:android="http://schemas.android.com/apk/res/android" />

valueFrom="-800"时,表示您的片段布局底部。


3

0
希望这能帮到某些人。API文档说要使用objectAnimator进行片段动画,但即使使用最新的兼容包,在xml中使用objectAnimator也无法被编译器接受。
对我来说,这个方法可行:
对于Android 3.0或更高版本:在res / animator文件夹中声明xml objectAnimator。
对于低于3.0的兼容包:在res / anim文件夹中声明xml动画。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接