I Hate the Command Line

mac-terminal

Back when I was a Windows developer, I learned all sorts of arcane things about the platform. I felt I had to in order to be a good developer, and much of it was necessary to support customers running into problems.

Four years ago I bought a Mac, and three years ago I ditched Windows entirely and started learning Android development on my Mac.

I decided I really didn’t want to learn all the innards of the Mac. I never liked dealing with all that on Windows, and since I wasn’t a Mac developer I figured I could skip it.

Which means, of course, that I’m totally useless with the command line. Terminal? No thanks. Bash? Forget it. Git? I’ll use SourceTree instead. If it doesn’t have a GUI, I don’t want to touch it.

Sure, there are probably a ton of cool things I could do from the command line. But I’m happier not feeling I need to know all that stuff.

Test Driving Employees

From the NY Times:

“Employee trials work best for people in support, design and developer positions, said Matt Mullenweg, founder and chief executive of Automattic, the creator of WordPress, the blog and website tool. Still, every hire, without exception, goes through a two- to six-week contract period, and is paid the standard rate of $25 an hour.”

Employee trials are daunting, and downright impossible for many people. For some companies they’re completely unrealistic.

But the fact that Automattic had trials is one of the things that convinced me I wanted to work with them. I wanted to work alongside people who believed so much in what the company was doing that they’d go through the pain of a trial period.

The trial period was certainly painful for me. At the time I was working 60-80 hours a week at a job I wasn’t fully committed to, and I couldn’t imagine how I’d fit a trial period into that. But somehow I did it, and I’m glad I did because now I get to work with people totally invested in a shared goal.

PS: We’re hiring.

Using Android’s ViewPager PageTransformer

A recent addition I made to the Reader in WordPress for Android is the ability to swipe through articles, which is a pretty standard thing on Android thanks to the ViewPager.

But after using it a while, I decided I wasn’t happy with the default swipe animation, so I created a custom PageTransformer to provide a different one.

I then added the ability to swipe through photos in an article, and again I wasn’t happy with the default animation. Rather than create another PageTransformer, I changed the one I’d already coded so it could provide a number of different animations.

Here’s a video demo:

The source code for this custom PageTransformer, which is part of the open source WordPress for Android app, is below.

package org.wordpress.android.ui.reader;

import android.support.v4.view.ViewPager;
import android.view.View;

/*
 * ViewPager transformation animation invoked when a visible/attached page is scrolled - before
 * changing this, first see https://code.google.com/p/android/issues/detail?id=58918#c5
 * tl;dr make sure to remove X translation when a page is no longer fully visible
 *
 * Usage: viewPager.setPageTransformer(false, new ReaderViewPagerTransformer(TransformType.FLOW));
 */
class ReaderViewPagerTransformer implements ViewPager.PageTransformer {
    static enum TransformType {
        FLOW,
        DEPTH,
        ZOOM,
        SLIDE_OVER
    }
    private final TransformType mTransformType;

    ReaderViewPagerTransformer(TransformType transformType) {
        mTransformType = transformType;
    }

    private static final float MIN_SCALE_DEPTH = 0.75f;
    private static final float MIN_SCALE_ZOOM = 0.85f;
    private static final float MIN_ALPHA_ZOOM = 0.5f;
    private static final float SCALE_FACTOR_SLIDE = 0.85f;
    private static final float MIN_ALPHA_SLIDE = 0.35f;

    public void transformPage(View page, float position) {
        final float alpha;
        final float scale;
        final float translationX;

        switch (mTransformType) {
            case FLOW:
                page.setRotationY(position * -30f);
                return;

            case SLIDE_OVER:
                if (position < 0 && position > -1) {
                    // this is the page to the left
                    scale = Math.abs(Math.abs(position) - 1) * (1.0f - SCALE_FACTOR_SLIDE) + SCALE_FACTOR_SLIDE;
                    alpha = Math.max(MIN_ALPHA_SLIDE, 1 - Math.abs(position));
                    int pageWidth = page.getWidth();
                    float translateValue = position * -pageWidth;
                    if (translateValue > -pageWidth) {
                        translationX = translateValue;
                    } else {
                        translationX = 0;
                    }
                } else {
                    alpha = 1;
                    scale = 1;
                    translationX = 0;
                }
                break;

            case DEPTH:
                if (position > 0 && position < 1) {
                    // moving to the right
                    alpha = (1 - position);
                    scale = MIN_SCALE_DEPTH + (1 - MIN_SCALE_DEPTH) * (1 - Math.abs(position));
                    translationX = (page.getWidth() * -position);
                } else {
                    // use default for all other cases
                    alpha = 1;
                    scale = 1;
                    translationX = 0;
                }
                break;

            case ZOOM:
                if (position >= -1 && position <= 1) {
                    scale = Math.max(MIN_SCALE_ZOOM, 1 - Math.abs(position));
                    alpha = MIN_ALPHA_ZOOM +
                            (scale - MIN_SCALE_ZOOM) / (1 - MIN_SCALE_ZOOM) * (1 - MIN_ALPHA_ZOOM);
                    float vMargin = page.getHeight() * (1 - scale) / 2;
                    float hMargin = page.getWidth() * (1 - scale) / 2;
                    if (position < 0) {
                        translationX = (hMargin - vMargin / 2);
                    } else {
                        translationX = (-hMargin + vMargin / 2);
                    }
                } else {
                    alpha = 1;
                    scale = 1;
                    translationX = 0;
                }
                break;

            default:
                return;
        }

        page.setAlpha(alpha);
        page.setTranslationX(translationX);
        page.setScaleX(scale);
        page.setScaleY(scale);
    }
}

Tech as the Teen Common Ground

I was born in England in 1967. Two years later my family moved to the USA. Since then, many of my relatives have scattered across the globe.

When a cousin visits me in the USA – which happens maybe once every five years – we seek some common ground, and invariably it turns out to be music or some other form of entertainment. We start talking about the music and movies we like, and from there we find other things to talk about.

By when their kids interact with my kids, the common ground is tech.

My cousin from Germany visited us last week, and we wondered if our sons – who had never met – would have much to talk about. But it turned out they’re both avid users of Instagram and Snapchat, and they both run Minecraft servers and have YouTube channels where they talk about their gaming addiction.

Their common ground in tech was the starting point for their relationship, and that relationship continues even after we said our goodbyes thanks to the tech they use to communicate.

Why I Left Indie Development

indiana-jones

In what feels like a different life now, I used to be a fairly well-known indie developer. I spoke at events like SXSW, and my blog had a large audience of people who liked hearing about my work on HomeSite, TopStyle and FeedDemon.

I parted ways with that life several years ago, in part because it’s extremely difficult to be a one-man show and still have time to be a husband and father. I was also burned out from years of doing my own support. I had lovely customers, of course, but I spent so much time supporting them that I wasn’t able to spend as much time feeding my code addiction. Almost everything I do professionally is so I can enjoy the bliss of getting lost in writing software.

But I also gave up pursuing the indie life because I wanted to make the switch to mobile development, and I didn’t see much future for indie mobile developers. The economics of the various app stores coupled with the plethora of free software didn’t paint a rosy picture for one-person companies building consumer apps. In fact, I didn’t make the leap to mobile until I was offered a full-time job as an Android dev.

So it’s been interesting reading the latest round of blog posts about the state of indie mobile development. While there are success stories, there certainly aren’t many of them. Making a decent living as an indie developer writing mobile apps is ridiculously hard – and I don’t see it getting better anytime soon.

A lot of mobile developers have left the indie ship and done as I have and joined a larger company, many of which look at mobile apps as a free (or nearly free) complement to their other offerings.1 There’s plenty of opportunity here for mobile developers, and I think that opportunity will continue to grow for a while.


  1. As an aside, I’m not convinced the “mobile as a complement” strategy is the right one long term. Mobile is becoming the primary way people access their information, to the point that web and desktop software are turning into the complement.

Goodbye Blue Sky

goodbye-blue-sky
My parents grew up in England during World War II. They used to tell me about the air raid sirens that sounded at night alerting them to seek shelter, quickly.

I often asked them about this, thinking they must still be haunted by the thought of bombs dropping on them as they slept.

But they said it was normal to them. It was all they ever knew.

That has always stuck with me.

It makes me wonder how many things we accept simply because we’ve never known any different.

Abolishing the Gingerbread Tax

A few weeks ago I said this:

Every Android developer I know will dance in the streets the day they can drop support for pre-ICS versions of Android

Well, it looks like it’s time for me to hit the streets because WordPress for Android – the app I work on – is dropping Gingerbread support in new versions.

Strangely, though, I was a bit nervous when we first talked about doing this. Leaving any users stranded really bothered me.

But then I thought about how much extra work we put into maintaining backwards compatibility for a dwindling number of people, and I considered how much better the app could be for the large majority of our users if we spent that time improving it for newer devices.

When I looked at it that way, I wondered whether we should’ve dropped Gingerbread support even sooner. And I wondered how many other Android developers are continuing to make the majority of their users pay this Gingerbread Tax.

If you’re one of them, perhaps it’s time your app stops supporting pre-ICS devices, too.