【问题标题】:How to show a Dialog on Android using the reveal effect from material design?如何使用材料设计的显示效果在 Android 上显示对话框?
【发布时间】:2015-07-16 14:06:02
【问题描述】:

我有一个Activity 和一个FloatingActionButton。当我按下 FAB 时,会显示一个 AlertDialog。我想通过使用 AndroidMaterial Design 中的显示效果或曲线运动来为其外观设置动画。 documentation 仅提供更改现有视图可见性的示例。

对于AlertDialog,我怎样才能做到这一点?

【问题讨论】:

    标签: android animation android-alertdialog material-design


    【解决方案1】:

    在显示对话框之前,我通过调用对话框的setOnShowListener 做了类似的事情。我还需要完善动画,但这是一个开始:

    dialogToAnimate.setOnShowListener(new OnShowListener() {
        @Override public void onShow(DialogInterface dialog) {
            // Remember that ViewAnimationUtils will not work until API 21.
            final View view = dialogToAnimate.getWindow().getDecorView();
            final int centerX = view.getWidth() / 2;
            final int centerY = view.getHeight() / 2;
            // TODO Get startRadius from FAB
            // TODO Also translate animate FAB to center of screen?
            float startRadius = 20;
            float endRadius = view.getHeight();
            Animator animator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
            animator.setDuration(1000);
            animator.start();
        }
    });
    

    【讨论】:

    • 我更新了答案以在 Dialog 上使用现有 API。
    【解决方案2】:

    如果您有自定义视图(在 XML 中定义),您可以试试这个:

    AlertDialog a = new AlertDialog.Builder(this)...blablabla;
    View v = a.findViewById(R.layout.example);
    
    // get the center for the clipping circle
    int cx = (v.getLeft() + v.getRight()) / 2;
    int cy = (v.getTop() + v.getBottom()) / 2;
    
    // get the final radius for the clipping circle
    int finalRadius = Math.max(v.getWidth(), v.getHeight());
    
    // create the animator for this view (the start radius is zero)
    Animator anim = ViewAnimationUtils.createCircularReveal(v, cx, cy, 0, finalRadius);
    
    // make the view visible and start the animation
    v.setVisibility(View.VISIBLE);
    anim.start();
    

    使用反向动画隐藏它:

    View v = <yourAlertDialog>.findViewById(R.layout.example);
    
    // get the center for the clipping circle
    int cx = (v.getLeft() + v.getRight()) / 2;
    int cy = (v.getTop() + v.getBottom()) / 2;
    
    // get the initial radius for the clipping circle
    int initialRadius = v.getWidth();
    
    // create the animation (the final radius is zero)
    Animator anim = ViewAnimationUtils.createCircularReveal(v, cx, cy, initialRadius, 0);
    
    // make the view invisible when the animation is done
    anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            v.setVisibility(View.INVISIBLE);
        }
    });
    
    // start the animation
    anim.start();
    

    【讨论】:

    • 对于 API 级别
    【解决方案3】:

    上述 API 21 的带有显示效果的警报对话框=>

    public final void customAlertDialog(final Activity mActivity)
     {
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mActivity);
            final View view = LayoutInflater.from(mActivity).inflate(R.layout.alert_dialog_simple_msg,null);
            alertDialogBuilder.setView(view);
            final AlertDialog alertDialog = alertDialogBuilder.create();
            alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
            TextView tvOk= (TextView) view.findViewById(R.id.tvOk);
            final Animator[] animHide = {null};
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                alertDialog.show();
                view.post(new Runnable() {
                    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
                    @Override
                    public void run() {
                        int cx = (int)view.getWidth() / 2;
                        int cy = (int) view.getHeight() / 2;
                        float finalRadius = (float) Math.hypot(cx, cy);
                        Animator animVisible = ViewAnimationUtils.createCircularReveal(view, cx, cy, 0, finalRadius);
                        animHide[0] = ViewAnimationUtils.createCircularReveal(view, cx, cy, finalRadius, 0);
                        animVisible.start();
                    }
                });
            }
            tvOk.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                        if ( animHide[0]!=null)
                        {
                            animHide[0].addListener(new AnimatorListenerAdapter() {
                                @Override
                                public void onAnimationEnd(Animator animation) {
                                    super.onAnimationEnd(animation);
                                    alertDialog.dismiss();
                                }
                            });
                            animHide[0].start();
                        }
                        else
                        {
                            alertDialog.dismiss();
                        }
                    }
                    else
                    {
                        alertDialog.dismiss();
                    }
                }
            });
            alertDialog.setCancelable(false);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-03
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多