Part 1 — The skeleton of the project

from giphy.com

I want you to focus on the animation, so I am going to create two really simple activities with solid colors, a text and a button. You can get your hands dirty and make an amazing UI after you learn the animation!

XML for activity 1:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:padding="16dp"

android:fitsSystemWindows="true"

android:background="@android:color/background_dark"

tools:context="com.ebanx.circularreveal.MainActivity">



<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="First activity"

android:layout_centerHorizontal="true"

/>



<Button

android:id="@+id/btn"

android:layout_width="70dp"

android:layout_height="70dp"

android:text="GO!"

android:textColor="@android:color/white"

android:layout_centerInParent="true"

android:background="@drawable/button_shape"/>



</RelativeLayout>

I made the activity with a black background because I want you to see very clearly the animation to the second activity.

I used custom background for the button to make it a circle. Please remind that this animation needs to be used in the right place. It wouldn’t look very nice with a squared button, for example (or maybe it does!).

This is the button_shape:

<shape android:shape="rectangle"

xmlns:android="http://schemas.android.com/apk/res/android" >



<corners android:radius="100dp" />

<solid android:color="@color/colorPrimary"/>

</shape>

Code for activity 1:

public class MainActivity extends AppCompatActivity {



private Button btnCreate;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);



btnCreate = (Button) findViewById(R.id.btn);



btnCreate.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presentActivity(v);

}

});

}



public void presentActivity(View view) {

ActivityOptionsCompat options = ActivityOptionsCompat.

makeSceneTransitionAnimation(this, view, "transition");

int revealX = (int) (view.getX() + view.getWidth() / 2);

int revealY = (int) (view.getY() + view.getHeight() / 2);



Intent intent = new Intent(this, SecondActivity.class);

intent.putExtra(SecondActivity.EXTRA_CIRCULAR_REVEAL_X, revealX);

intent.putExtra(SecondActivity.EXTRA_CIRCULAR_REVEAL_Y, revealY);



ActivityCompat.startActivity(this, intent, options.toBundle());

}

}

Really simple, right? All we have to do is to create an scene transition animation to use the default fading animation. I am sending the coordinates to the secound activity so it knows where is it should start de reveal animation. I picked the coordinates of the center of the button, but you can choose the way you prefer.

XML for activity 2:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/root_layout"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="32dp"

android:background="@android:color/background_light"

android:fitsSystemWindows="true"

tools:context="com.ebanx.circularreveal.SecondActivity">



<TextView

android:text="It works!"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true" />



</RelativeLayout>

The only important line is this one:

android:background="@android:color/background_light"

Our second activity has a transparent background, remember? So you need to set a color to the root_layout so you don’t end up with a totally transparent activity.

Code for activity 2:

Now we have the first part of our project. Let's make the transition between the two activities.

public class SecondActivity extends AppCompatActivity {



public static final String EXTRA_CIRCULAR_REVEAL_X = "EXTRA_CIRCULAR_REVEAL_X";

public static final String EXTRA_CIRCULAR_REVEAL_Y = "EXTRA_CIRCULAR_REVEAL_Y";



View rootLayout;



private int revealX;

private int revealY;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_second);



final Intent intent = getIntent();



rootLayout = findViewById(R.id.root_layout);



if (savedInstanceState == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&

intent.hasExtra(EXTRA_CIRCULAR_REVEAL_X) &&

intent.hasExtra(EXTRA_CIRCULAR_REVEAL_Y)) {

[I will show the code for this in a while!] } else {

rootLayout.setVisibility(View.VISIBLE);

}

Ok, so we get the coordinates from the previous activity. But, before implementing the animation, we need to make some configurations in our project.

Part 2 — Some configurations

You will need to create a values-v21 folder, because the styles that you are going to use are only supported for this version and up.

Create the folder and, inside it, create a styles.xml. We are going to make the style for our first activity:

<!-- Base application theme. -->

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

<!-- Customize your theme here. -->

<item name="colorPrimary">@color/colorPrimary</item>

<item name="colorPrimaryDark">@color/colorPrimaryDark</item>

<item name="colorAccent">@color/colorAccent</item>

<item name="android:windowTranslucentNavigation">true</item>

<item name="android:windowTranslucentStatus">true</item>

</style>



<style name="AppTheme.Transparent" parent="AppTheme">

<item name="android:windowIsTranslucent">true</item>

<item name="android:windowBackground">@android:color/transparent</item>

<item name="android:windowDrawsSystemBarBackgrounds">true</item>



</style>

That is what makes our navigation bar, status bar and window translucent. Our windowBackground must be transparent or we won't be able to achieve the effect that we desire. When the new activity enters, we will be able to see the first activity because the second is transparent.

Apply the code theme in your activities