【问题标题】:Change DialogFragment enter/exit transition at just before dismissing在关闭之前更改 DialogFragment 进入/退出转换
【发布时间】:2015-12-30 17:30:31
【问题描述】:

我有一个DialogFragment,我在onActivityCreated 方法中设置了进入/退出动画,如下所示:

  @Override
    public void onActivityCreated(Bundle arg0) {
        super.onActivityCreated(arg0);
        getDialog().getWindow()
                .getAttributes().windowAnimations = R.style.DialogAnimation;
    }

我的DialogAnimation样式文件如下:

<style name="DialogAnimation">
        <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
    </style>

这对我有用...

现在我的问题是我想要两个不同的退出动画,一个用于单击“确定”按钮,一个用于取消按钮。所以我所做的就是在解雇之前尝试更改过渡,但没有奏效。

有什么办法可以实现吗?

这是我尝试过的:

  @Override
    public void onClick(View v) {
        getDialog().getWindow()
                .getAttributes().windowAnimations = R.style.DialogAnimation2;
        this.dismiss();
    }

【问题讨论】:

标签: android android-animation buttonclick dialogfragment


【解决方案1】:

您可以在 DialogFragment 中执行此操作,无需更改

getDialog().getWindow()
            .getAttributes().windowAnimations

您应该在 onStart 和 onClick 中为“装饰视图”设置动画。

这是截取的代码:

先创建对话框

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setTitle("Hello from animated dialog :)")
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                //we have to add button here and then override it's click in onStart
                            }
                        }
                )
                .setCancelable(false)
                .create();
    }

然后重写 onStart 方法

@Override
    public void onStart() {
        super.onStart();

        AlertDialog dialog = (AlertDialog)getDialog();

        final View decorView = getDialog()
                .getWindow()
                .getDecorView();

        ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(decorView,
                PropertyValuesHolder.ofFloat("scaleX", 0.0f, 1.0f),
                PropertyValuesHolder.ofFloat("scaleY", 0.0f, 1.0f),
                PropertyValuesHolder.ofFloat("alpha", 0.0f, 1.0f));
        scaleDown.setDuration(2000);
        scaleDown.start();


        Button positiveButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
        positiveButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                final View decorView = getDialog()
                        .getWindow()
                        .getDecorView();

                ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(decorView,
                        PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.0f),
                        PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.0f),
                        PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f));
                scaleDown.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        dismiss();
                    }

                    @Override
                    public void onAnimationStart(Animator animation) {
                    }
                    @Override
                    public void onAnimationCancel(Animator animation) {
                    }
                    @Override
                    public void onAnimationRepeat(Animator animation) {
                    }
                });
                scaleDown.setDuration(2000);
                scaleDown.start();
            }
        });
    }

这是结果动画


如果您从我的代码中删除缩放属性,您将只获得 alpha 动画。完全如您所愿。

删除这个:

PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.0f),
PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.0f),

【讨论】:

  • 当我在 decorView 上执行此操作时,我的问题是窗口只有对话框那么大。所以动画会超出窗口。
  • 实际上我使用的是平移和旋转动画,我举了一个 alpha 动画的例子来保持简单
  • 这是正确的解决方案 +1,@DominicD'Souza 如果您愿意,您可以在 DialogFragment 布局的任何视图上播放动画。如果您检查“Dialog”类的来源,您会发现所有操作都在使用装饰视图进行。
  • 如果没有否定或肯定按钮怎么办?
  • 从下往上怎么可能?喜欢向上滑动?
【解决方案2】:

您可以为对话框片段设置上下动画。在“res/anim”中添加两个文件:

//上滑动画

<?xml version="1.0" encoding="utf-8"?>
<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:toYDelta="0" />

</set>

// 幻灯片动画

<?xml version="1.0" encoding="utf-8"?>
<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" />

</set>

// 样式

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

// 对话片段内部

@Override
public void onActivityCreated(Bundle arg0) {
    super.onActivityCreated(arg0);
    getDialog().getWindow()
   .getAttributes().windowAnimations = R.style.DialogAnimation;
}

【讨论】:

  • 我已经这样做了,我的问题是想要有 2 个不同的退出动画,一个用于正按钮单击,一个用于负按钮单击。
  • 你可以在你的正/负按钮点击中向上/向下调用幻灯片
  • 我面临的主要问题是创建对话框后不能更改 windowAnimations
  • 所以调用 getDialog().getWIndow().getAttributes().windowAnimations=R.style.DialogCancelAnimation 在点击的取消按钮中不起作用
  • 为我工作,将 slideUp 中的 'android:toXDelta' 替换为 'android:toYDelta'
【解决方案3】:

我认为最好的方法是在按钮点击时调用不同的动画。因此,您将获得类似于以下内容:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button OkButton = (Button) findViewById(R.id.btnOk);
        Button CancelButton = (Button) findViewById(R.id.btnCancel);

        OkButton.setOnClickListener(new OnClickListener() {

            @Override    
            public void onClick(View view) {
                    getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;    
            }
        });
        return true;

        CancelButton.setOnClickListener(new OnClickListener() {

            @Override    
            public void onClick(View view) {
                getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimation2;    
            }
        });
        return true;
    }

如果我是你,我也会使用正确的命名约定以供将来参考。例如将 DialogAnimation 设置为 OkAnimation,将 DialogAnimation2 设置为 CancelAnimation。

回家这有帮助:)

【讨论】:

  • 我已经尝试了我的问题中提到的上面的代码..似乎你只能在对话框的onCreate中设置windowAnimation..所以上面的代码对我不起作用..你试过了吗。?它对你有用吗?
  • onClockListener 始终存在于 onCreate、OnCreateView 或 onStart 方法中。我已经编辑了答案,为您提供解决方案。
【解决方案4】:

做你想做的一个简单的方法是使用动画监听器。

    animation.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            // TODO Auto-generated method stub
            // dismiss your dialog in here and it will work
        }
    });

在 onclick 方法上启动动画并在 onAnimationEnd() 方法上关闭对话框。您可能需要制作 snimation 对象并使用 View 的 startAnimation(animation) 方法手动启动它们。

【讨论】:

    【解决方案5】:

    你应该为你的基本对话框设置一个主题

    让我们说:-

    public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener
    {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
        {
            return super.onCreateView(inflater, container, savedInstanceState);
        }
    
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) 
        {
            // Set a theme on the dialog builder constructor!
            AlertDialog.Builder builder = 
                new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );
    
            builder  
            .setTitle( "Your title" )
            .setMessage( "Your message" )
            .setPositiveButton( "OK" , new DialogInterface.OnClickListener() 
                {      
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                  dismiss();                  
                }
            });
            return builder.create();
        }
    }
    

    然后您只需要定义包含所需动画的主题即可。在 styles.xml 中添加您的自定义主题:

    <style name="MyCustomTheme" parent="@android:style/Theme.Panel">
        <item name="android:windowAnimationStyle">@style/MyAnimation.Window</item>
    </style>
    
    <style name="MyAnimation.Window" parent="@android:style/Animation.Activity"> 
        <item name="android:windowEnterAnimation">@anim/anim_in</item>
        <item name="android:windowExitAnimation">@anim/anim_out</item>
    </style> 
    

    参考this

    【讨论】:

      【解决方案6】:

      如果任何人最终在许多对话框中使用 onCreateDialog 答案,那么您可以使用这个 Kotlin 扩展函数。

      //ExtensionFunctions.kt file
      fun Dialog.setWindowAnimations(@StyleRes id: Int): Dialog {
          this.window?.attributes?.windowAnimations = id
          return this
      }
      

      在你的 onCreateDialog 函数中

      override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
          return super.onCreateDialog(savedInstanceState)
              .setWindowAnimations(R.style.MyDialogAnimation)
      }
      

      【讨论】:

        猜你喜欢
        • 2016-03-28
        • 1970-01-01
        • 1970-01-01
        • 2019-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2016-10-10
        相关资源
        最近更新 更多