自定义对话框的动画效果

105

我试图让一个自定义对话框从文本视图滑出,这可行吗?我似乎无法将任何动画应用于对话框类。我在构造函数中尝试了以下代码,但它没有任何效果:

this.getWindow().setWindowAnimations(R.anim.paranimation);

我甚至不确定动画是否正确,但一旦我看到它的效果,就能调整它。为了完整起见,我将其列在下面。我不需要关于实际动画的帮助,只需要将其应用于对话框。

paranimation.xml:

<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="-200%"
    android:toXDelta="0%"
    android:fromYDelta="200%"
    android:toYDelta="0%"
    android:duration="3000"
    android:zAdjustment="top">
</translate>

4
我也需要知道这个。似乎可以给任何东西添加动画,除了这个。难道我错了吗?! - andy_spoo
7个回答

225

今天我在努力解决对话框动画的问题,最终通过样式使其工作,这里是一个示例。

首先,最重要的事情——今天我可能用了5种不同的方法让它工作了,但是因为......如果您设备的动画设置为“无动画”(设置→显示→动画),那么无论做什么,对话框都不会有动画效果!

以下是我的styles.xml的简化版本。希望它很清楚易懂。这应该位于res/values目录中。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="PauseDialog" parent="@android:style/Theme.Dialog">
        <item name="android:windowAnimationStyle">@style/PauseDialogAnimation</item>
    </style>

    <style name="PauseDialogAnimation">
        <item name="android:windowEnterAnimation">@anim/spin_in</item>
        <item name="android:windowExitAnimation">@android:anim/slide_out_right</item>
    </style>
</resources>

windowEnterAnimation是我的动画之一,位于res\anim中。 windowExitAnimation是Android SDK中的动画之一。

然后,在我的活动的onCreateDialog(int id)方法中创建对话框时,我执行以下操作。

Dialog dialog = new Dialog(this, R.style.PauseDialog);

// Setting the title and layout for the dialog
dialog.setTitle(R.string.pause_menu_label);
dialog.setContentView(R.layout.pause_menu);

或者,您可以通过以下方式设置动画,而不是使用带有主题的对话框构造函数。

Dialog dialog = new Dialog(this);
dialog.getWindow().getAttributes().windowAnimations = R.style.PauseDialogAnimation;

2
那只是我为这个例子编造的一个名称,我从未真正创建过那个动画。 - ChrisJD
2
非常感谢您的回答,虽然我是通过Android Developers组的提示找到了这篇文章,但它的文档记录真的很差。 - David Snabel-Caunt
3
+1 对于 "如果您的设备动画设置为“无动画”(设置→显示→动画),则无论您做什么,对话框都不会有动画效果!" 我忘记检查了。 - Vincent Mimoun-Prat
对于API 11,Dialog dialog = new Dialog(this, R.style.PauseDialog);,但这是通用的Dialog dialog = new Dialog(Context context); - mehmet
2
我面临的问题是,当对话框显示时我最小化应用程序,然后再恢复应用程序时,对话框会再次动画显示,如何避免这种情况,其他方面都很完美。+1 - Parth Anjaria
显示剩余3条评论

64
我已经使用ChrisJD的代码为对话框创建了淡入淡出动画。

  1. 在res/style.xml文件中:

    <style name="AppTheme" parent="android:Theme.Light" />
    <style name="PauseDialog" parent="@android:style/Theme.Dialog">
        <item name="android:windowAnimationStyle">@style/PauseDialogAnimation</item>
    </style>
    
    <style name="PauseDialogAnimation">
        <item name="android:windowEnterAnimation">@anim/fadein</item>
        <item name="android:windowExitAnimation">@anim/fadeout</item>
    </style>
    

  2. 在anim/fadein.xml文件中

    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="500" />
    
  3. 在 anim/fadeout.xml 中

    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/anticipate_interpolator"
        android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="500" />
    
  4. 主活动界面

  5. Dialog imageDiaglog= new Dialog(MainActivity.this,R.style.PauseDialog);
    

14
您可以使用默认的Android淡入淡出动画'@ android:anim / fade_in''@ android:anim / fade_out'。 - Marek
谢谢,我发表这个答案时它还不存在。 :) - AkshayT

21

对于从右到左的进入动画和从左到右的退出动画:

styles.xml:

<style name="CustomDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowAnimationStyle">@style/CustomDialogAnimation</item>
</style>

<style name="CustomDialogAnimation">
    <item name="android:windowEnterAnimation">@anim/translate_left_side</item>
    <item name="android:windowExitAnimation">@anim/translate_right_side</item>
</style>

在res/anim/目录下创建两个文件:

translate_right_side.xml:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%" android:toXDelta="100%"
    android:fromYDelta="0%" android:toYDelta="0%"
    android:duration="600"/>

translate_left_side.xml:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="600"
    android:fromXDelta="100%"
    android:toXDelta="0%"/>
在您的Fragment/Activity中:
Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);

17

首先,您需要在res/anim目录中创建两个动画资源

slide_up.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
    android:duration="@android:integer/config_mediumAnimTime"
    android:fromYDelta="100%"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toXDelta="0">
</translate>
</set>

滑动底部.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate 
    android:duration="@android:integer/config_mediumAnimTime" 
    android:fromYDelta="0%p" 
    android:interpolator="@android:anim/accelerate_interpolator" 
    android:toYDelta="100%p">
</translate>
</set>

那么您需要创建一个样式

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_bottom</item>
</style>

并将此行添加到你的类中

dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id

位于http://www.devexchanges.info/2015/10/showing-dialog-with-animation-in-android.html的基础上


1
参考URL非常有用! - Ahmed Nabil

13

我遇到了同样的问题,但是最后我按照以下方式解决了问题。

((ViewGroup)dialog.getWindow().getDecorView())
.getChildAt(0).startAnimation(AnimationUtils.loadAnimation(
context,android.R.anim.slide_in_left));

4
不是一个明智的回答。对话中的观点变得生动起来。 - DJphy

3
请尝试以下代码:

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));// set transparent in window background

        View _v = inflater.inflate(R.layout.some_you_layout, container, false);

        //load animation
        //Animation transition_in_view = AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in);// system animation appearance
        Animation transition_in_view = AnimationUtils.loadAnimation(getContext(), R.anim.customer_anim);//customer animation appearance

        _v.setAnimation( transition_in_view );
        _v.startAnimation( transition_in_view );
        //really beautiful
        return _v;

    }

创建自定义动画:res/anim/customer_anim.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:duration="500"
        android:fromYDelta="100%"
        android:toYDelta="-7%"/>
    <translate
        android:duration="300"
        android:startOffset="500"
        android:toYDelta="7%" />
    <translate
        android:duration="200"
        android:startOffset="800"
        android:toYDelta="0%" />

</set>

0
关于https://dev59.com/zW445IYBdhLWcg3wg6tm#5591827的参考。
对话框打开和关闭的动画是有效的,但如果你使用的是
dialog.setCanceledOnTouchOutside(true);

[那你将面临一些问题]

问题 - 如果用户在对话框外点击,对话框将关闭而没有动画效果

错误修复:我已经将淡入/淡出动画更改为从左到右/从右到左(也适用于AlertDialog) leftToRight.anim

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:duration="300"
        android:fromXDelta="-100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />
</set>

rightToLeft.anim

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:duration="300"
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="100%"
        android:toYDelta="0%" />
</set>

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