Android Dialog Reveal Animation

Style definition

res/values/styles.xml

<resources ... >

    ...

    <style name="CustomAnimations"/>

    <!-- Sliding animation -->
    <style name="CustomAnimations.slide">
        <item name="android:windowEnterAnimation">@anim/slide_in_left</item>
        <item name="android:windowExitAnimation">@anim/slide_out_right</item>
    </style>

    <!-- Grow animation -->
    <style name="CustomAnimations.grow">
        <item name="@android:windowEnterAnimation">@anim/grow_in</item>
        <item name="@android:windowExitAnimation">@anim/grow_out</item>
    </style>

</resources>

Animation config

res/anim/slide_in_left

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

</translate>  

res/anim/slide_out_right

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

</translate>  

res/anim/grow_in

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="0%"
        android:toXScale="0.3"
        android:toYScale="0.3" />

    <alpha
        android:duration="@android:integer/config_shortAnimTime"
        android:fromAlpha="1.0"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:toAlpha="0.0" />
</set>  

res/anim/grow_out

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXScale="0.3"
        android:fromYScale="0.3"
        android:pivotX="50%"
        android:pivotY="100%"
        android:toXScale="1.0"
        android:toYScale="1.0" />

    <alpha
        android:duration="@android:integer/config_shortAnimTime"
        android:fromAlpha="0.0"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:toAlpha="1.0" />
</set>  

Usage in Fragment

In Fragment, define animation style in the last two lines.

AlertDialog alertDialog;

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());  
builder.setTitle("Some title");  
builder.setMessage("Some string");  
builder.setNegativeButton("Some button", new DialogInterface.OnClickListener() {  
    public void onClick(DialogInterface dialog, int which) {
        Log.i(TAG, "Clicked some button");
    }
});
builder.setIcon(R.mipmap.some_icon);

alertDialog = builder.create();  
alertDialog.getWindow().getAttributes().windowAnimations = R.style.CustomAnimations_slide;  
alertDialog.show();

Extras: Circular Reveal

To achieve this effect, we'll be needing a custom dialog view. Create a simple one as below:

res/layout/dialog_custom.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:orientation="vertical">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/reveal_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="vertical"
        android:paddingBottom="8dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="8dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="Pinned Quote"
            android:layout_marginBottom="15dp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="This is a text inside a dialog"
            android:textSize="18sp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_save"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="?android:attr/selectableItemBackground"
                android:text="Save" />
        </LinearLayout>
    </LinearLayout>
</ScrollView>  

Now, use it in our AlertDialog Builder:

final View dialogView = View.inflate(getActivity(), R.layout.dialog_custom, null);

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());  
builder.setView(dialogView);

dialog = builder.create();  
dialog.setOnShowListener(new DialogInterface.OnShowListener() {  
    @Override
    public void onShow(DialogInterface dialog) {
        revealShow(dialogView, true, null);
    }
});
dialogView.findViewById(R.id.btn_save).setOnClickListener(new View.OnClickListener() {  
    @Override
    public void onClick(View v) {
        revealShow(dialogView, false, dialog);
    }
});
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));  
dialog.show();  

To generate the Circular reveal and hiding effect, use the function below. Everything else is pretty straighforward line by line:

private void revealShow(View rootView, boolean reveal, final AlertDialog dialog) {  
    final View view = rootView.findViewById(R.id.reveal_view);
    int w = view.getWidth();
    int h = view.getHeight();
    float maxRadius = (float) Math.sqrt(w * w / 4 + h * h / 4);

    if(reveal){
        Animator revealAnimator = ViewAnimationUtils.createCircularReveal(view,
                w / 2, h / 2, 0, maxRadius);
        view.setVisibility(View.VISIBLE);
        revealAnimator.start();
    } else {
        Animator anim = ViewAnimationUtils.createCircularReveal(view, w / 2, h / 2, maxRadius, 0);

        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                dialog.dismiss();
                view.setVisibility(View.INVISIBLE);

            }
        });

        anim.start();
    }
}

Aiman Baharum

More about this blog https://github.com/aimanbaharum/random-wiki/wiki

Kuala Lumpur, Malaysia http://www.aimanbaharum.com

Subscribe to Knowledge Log

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!