Showing posts with label animations. Show all posts
Showing posts with label animations. Show all posts

16 June 2015

Android integration with Chrome Custom Tabs


Announced at Google IO 2015 was the ability to integrate custom tabs in Android. Much like Facebook has been using it’s own browser like tab to open links, this ability is now available in Android with Chrome. This is great news as it allows developers to integrate a web link and maintain some of the look and feel of their app. You can add toolbar colors, animations and even a button.


Before going any further as of June 2015 you need to install Chrome from the dev channel:
Version 45 has this feature, they say it’ll take about twelve weeks to roll through to release.

This works in any version of Android, so don’t worry about M or any of that. It degrades really nicely, so if your client has the feature in Chrome, it’ll slide in and out beautifully. If not, then it’ll open like a regular intent. Although your custom in animation will probably show.

First you need to create four standard in and out animations, left in, left out, right in, right out.
Then you need to define some final constants which will be used in the intent extras:
private static final String EXTRA_CUSTOM_TABS_SESSION_ID = "android.support.CUSTOM_TABS:session_id";
public static final String EXTRA_CUSTOM_TABS_EXIT_ANIMATION_BUNDLE = "android.support.CUSTOM_TABS:exit_animation_bundle";
private static final String EXTRA_CUSTOM_TABS_TOOLBAR_COLOR = "android.support.CUSTOM_TABS:toolbar_color";

Then you can launch like this from your activity:

String url = "http://www.google.com/";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.putExtra(EXTRA_CUSTOM_TABS_SESSION_ID, -1);
intent.putExtra(EXTRA_CUSTOM_TABS_TOOLBAR_COLOR, getResources().getColor(R.color.colorPrimary));

if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    Bundle finishBundle = ActivityOptions.makeCustomAnimation(MainActivity.this, R.anim.slide_in_left, R.anim.slide_out_right).toBundle();
    intent.putExtra(EXTRA_CUSTOM_TABS_EXIT_ANIMATION_BUNDLE, finishBundle);
    Bundle startBundle = ActivityOptions.makeCustomAnimation(MainActivity.this, R.anim.slide_in_right, R.anim.slide_out_left).toBundle();
    startActivity(intent, startBundle);
}else{
    startActivity(intent);
}


Note that basically all we are doing is launch an intent.ACTION_VIEW but we’re tweaking it with extras so Chrome can interpret this request, slightly differently.
That’s it!

22 December 2014

Android Lollipop Shared Elements


In Lollipop the new material design has given us a new feature called shared elements or shared transitions. This allows us an easy method of animating common elements between screens. Sure it doesn't add any features, but it looks nice. Anything that gives the user a tiny bit of a happy design feeling is worth some effort.

The kodaline example demonstrates this:
http://android-developers.blogspot.co.uk/2014/10/implementing-material-design-in-your.html

It wasn't immediately obvious to me how this works after following Android developer's code examples there. So I created a simple example. I wasn't really interested in the full page animation with all the other pieces animating into place. I just wanted a really quick and easy win to take advantage of material. My example is a main activity with two small images on. Then a details activity with a single large activity. You click on an image, it gets bigger.

So there are four elements to this simple transition.


  1. values-v21/styles.xml
    Create a values-v21 directory in your res folder and add in a styles.xml file. This will override your existing styles file for Lollipop, you need the windowContentTransitions element. Here's my whole file:

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
    
        <style name="AppTheme" parent="android:Theme.Material">
            <item name="android:windowContentTransitions">true</item>
        </style>
    </resources>
    


  2. Activity xml
    Add a transitionName element to the xml of the item you wish to share. For my example I'm just using an image, so I've added the transitionName  to the image in activity_main, and of course the image in the details activity.

    Activity main:
        <ImageView
            android:id="@+id/activity_main_monkey"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center_horizontal"
            android:tag="@string/monkey"
            android:layout_marginTop="30dp"
            android:transitionName="@string/MyTransitionName"
            android:src="@drawable/monkey" />
    

    Activity Details:
        <ImageView
            android:id="@+id/activity_details_image"
            android:layout_width="wrap_content"
            android:layout_height="400dp"
            android:layout_gravity="top|center_horizontal"
            android:layout_marginTop="10dp"
            android:transitionName="@string/MyTransitionName"
            android:src="@drawable/monkey" />
    


  3. Launch detail activity from main
    Now comes the bit where we launch the second activity, from the first. Normally this is just a simple startActivity but the magic of shared transitions works by adding some options here. The important bit is this:
    options = ActivityOptions.makeSceneTransitionAnimation(this, v, getString(R.string.MyTransitionName));
    

    As you can see we use the same transition name we put in the xml. I've also added in a few if statements so we can run this on pre lollipop and it won't crash.

        @SuppressLint("NewApi")
        private void startDetailsActivity(View v){
            Intent intent = new Intent(this, DetailsActivity.class);
            ActivityOptions options = null;
            // create the transition animation - the images in the layouts of both activities are defined with android:transitionName="MyTransition"
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.L) {
                options = ActivityOptions.makeSceneTransitionAnimation(this, v, getString(R.string.MyTransitionName));
            }
            intent.putExtra(DetailsActivity.TAG_IMAGE_NAME, (String) v.getTag());
            // start the new activity
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && options != null) {
                this.startActivity(intent, options.toBundle());
            }else{
                startActivity(intent);
            }
        }
    
That's it. Hope it helps.

Here's the code: https://github.com/jimbo1299/shared-transitions