I am new to Android development (from Swift/iOS). I am trying to add some animation to this closing of a DialogFragment
when I tap outside the view. I have read various posts on animation for Dialogs and found posts that helped to get this far for my solution.
What works:
- Nicely scales up and fades in the alert (the
onStart()
is working) - Nicely scales down and fades out the alert when the "Close" button is
tapped (the
onClick()
is working)
What does not work:
- Tapping outside the alert. It closes the alert without the graceful animation.
Technically this is for:
DialogFragment
- Using an
AlertDialog.Builder
- The
cancelable
property is set to true on the builder - The
setCanceledOnTouchOutside
property is set to true on the createdAlertDialog
. - Using
ObjectAnimator
for my animations - For customer compliance, I need to support both a close button and "tap outside" to cancel/dismiss the dialog.
- From my discovery
onCancel
happens beforeonDismiss
Issues:
I was excited to add an OnCancelListener
to my dialog. However, during runtime I received an error, basically stating
Note: DialogFragment own the Dialog.setOnCancelListener and Dialog.setOnDismissListener callbacks. You must not set them yourself. To find out about these events, override onCancel(DialogInterface) and onDismiss(DialogInterface).
Ok. Easy enough, I thought I would override OnCancel
.
I did, but the animation does occur when I tap outside the alert dialog fragment. It still cancels (closes) - just no animation. Debugging, I see it step into my code, but the alert is already closed/hide/canceled as soon as I enter the overridden onCancel()
method. It seems like I am too late in the lifecycle. Since I cannot override OnCancelListener
for DialogFragments
, I was wondering if anyone has a solution or insight into my dilemma.
Long and Short: I would like to be able to have the same animation I have for clicking on the dialog's close button as I do when clicking outside the alert.
Here is my code snippet:
public void onStart() {
super.onStart();
AlertDialog dialog = (AlertDialog)getDialog();
ObjectAnimator scaleUp = scaleUp(dialog);
scaleUp.start();
Button closeButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
closeButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
AlertDialog dialog = (AlertDialog)getDialog();
ObjectAnimator scaleDown = scaleDown(dialog);
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.start();
}
});
}
Here is the onCancel override:
@Override
public void onCancel(final DialogInterface dialog) {
ObjectAnimator scaleDown = scaleDown((AlertDialog)dialog);
scaleDown.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
Log.i("DialogFragment","onAnimationEnd");
dialog.dismiss();
}
@Override
public void onAnimationStart(Animator animation) {
Log.i("DialogFragment","onAnimationStart");
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
scaleDown.start();
}
The two methods scaleUp
and scaleDown
are just refactored, they are just the settings for the ObjectAnimator
.
Followup: The inspiration of my solution was found in the one marked as possible duplicate. Change DialogFragment enter/exit transition at just before dismissing, however this does not address the specifics situation I had outlined - animation when tapping outside the dialog.
The solution I used from that link is great close animating when tapping on a button inside the dialog, but does not handle the setCanceledOnTouchOutside(true)