Tuesday, September 17, 2013

Upcoming Conferences

I just wanted to let anyone interested know about some upcoming conferences I'll be speaking at...

Droidcon London
London, October 24-27th
Crafting Unique, Delightful Apps (9:45 AM, Thursday, October 24th)

I'll be giving this talk in conjunction with our awesome designer, Chris Arvin.  To be honest, 45 minutes is hardly enough time to talk about all the things we could, but I'll be around all week long to talk more.

I'm also planning on attending the hackathon that weekend.  I've never done a hackathon before so it should be fun.  My only concern is that I have zero interest in staying up all night coding.  I think 8 hours of sleep (and some mental rest) is far more valuable than being drained all Sunday.

AnDevCon
San Francisco, November 12-15th
I Can Animate and So Can You (8:30 AM, Friday, November 15th)

I've started embracing animations in the last year in a way I never had before.  I regarded them as chunky and painful, which was true back in the days of 1.x and 2.x, but that's no longer the case.  It's possible to make really awesome animations now but it's still difficult to fit them into your app's structure.  This talk is designed to get you to think about how to do advanced animations in your app.

I also have a discount code for AnDevCon.  It'll knock $200 off registration.  Just use the code "LEW".

Tuesday, September 3, 2013

Smoothing performance on Fragment transitions

Suppose you're doing a pretty standard Fragment replacement with a custom animation:

getSupportFragmentManager()
    .beginTransaction()
    .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
    .replace(android.R.id.content, new MyFragment())
    .commit();

You may notice that the performance can be a bit rough, not as smooth as you'd like. A common way to improve Android animation performance is to use hardware layers.  Normally you'd add it to the animation directly but with fragments you don't get access to it unless you take advantage of Fragment.onCreateAnimation()*.  Here's how it looks:

public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    Animation animation = super.onCreateAnimation(transit, enter, nextAnim);

    // HW layer support only exists on API 11+
    if (Build.VERSION.SDK_INT >= 11) {
        if (animation == null && nextAnim != 0) {
            animation = AnimationUtils.loadAnimation(getActivity(), nextAnim);
        }

        if (animation != null) {
            getView().setLayerType(View.LAYER_TYPE_HARDWARE, null);

            animation.setAnimationListener(new AnimationListener() {
                public void onAnimationEnd(Animation animation) {
                    getView().setLayerType(View.LAYER_TYPE_NONE, null);
                }

                // ...other AnimationListener methods go here...
            });
        }
    }

    return animation;
}

Now the animation should be a lot more smooth!  In my own code, I've overridden this method in a base Fragment from which all others extend so that I always get this feature (though if you're more particular you could only apply it to certain Fragments).

* If you're not using the support library, then you'll be overriding Fragment.onCreateAnimator() and using animator-based classes.