Steve Jobs has passed away.

The news were surprising enough, even though I knew he was ill. What surprised me the most, however, was my own reaction, the extent to which this affected me. Since the day I experienced death in my closest family, the topic has always triggered discomfort and sadness in me, and I expected that this time around as well, but I didn’t expect such a strong feeling of loss.

Steve Jobs introducing the first iPhone

Steve Jobs introducing the first iPhone

After much thought (and sadness, and anger, and frustration, and disappointment), I have come to believe that mourning is just as necessary as it is dangerous. I’ll be the first to say that it’s a process you have to go through, that it allows you to move on; but I also think that if you’re not careful, it can trap you, entangle you, and by the time you realize, the pain of death has clouded your memories and dyed all recollections of the person’s life.

Heh, this is the fifth time I start this paragraph from scratch. I’ve spent the last few minutes staring at the words “For that reason”. After the previous paragraph, I intended to celebrate Steve Jobs’ life, not lament his passing. I can’t seem to get it right, though, so I’ll give it one more try and keep it brief.

The goal of changing the world seems to be reserved for hopeless optimists and idealists, and even regarded as childish by most of those who have lived long enough. Well, Steve Jobs pulled it off. His work, and that of the people he surrounded himself with, had a true, positive impact in all of our lives. He helped shape the world. It is so rare a feat, that the fact alone should be enough to earn our deepest admiration and respect. It earned mine, that’s for sure.

Thank you, and rest in peace, Steve. Rest knowing that those of us that still have time left, will spend it in the reality you helped create.

(If you have the time, read the short statements of Bill Gates, Sergey Brin, Larry Page, Tim Cook, and the memorial in the Apple website. You may also like Walt Mossberg’s The Steve Jobs I knew, Sam Altman’s Thanks, Steve, and The Value of saying No. There’s also Randall Munroe’s xkcd tribute)

A few days ago, I had to create a list that allowed the user to drag elements and rearrange them. It was unexpectedly troublesome, and somewhat more of a challenge than I had initially anticipated, so I thought to document the experience.

If you just want to get your hands on the code, it’s freely available here. Any and all kinds of feedback are welcome!

Rearranging

The functionality can already be seen in dozens of popular applications, but there’s not really a standard, and implementations show minor differences both in behavior and presentation. For that reason, I think I should begin by clarifying what I was expecting to achieve.

I wanted the user to be able to activate an edit mode on a list, hold his finger down on an item, and drag it up or down with immediate visual feedback of each positional swap. The keyword here is immediate: I didn’t want to give the impression that the item was being “lifted” and then “dropped” — I wanted it to look like the item was pushing its neighbors as it moved.

As a side note, I actually find the classic lifted/dropped effect, with a transparent duplicate of the item hovering above the list as you drag it, much more beautiful and comfortable. Only, you know,… work, requirements and all that.

Design Considerations

Long before my hands were anywhere near the keyboard, I noticed the task at hand wasn’t so straightforward. If I wanted to keep it decoupled and independent of implementation details, there were at least three actors in my play:

  1. The adapter, holding access to the dataset and responsible for creating/recycling views.
  2. The views associated with the items, which may want to be grabbed only from certain areas, and/or redraw themselves to give visual feedback when moving around.
  3. The ListView itself, the one that could actually detect the user’s movements

I tried to organize them hierarchically, so that the mechanism would only rely on one of them and automatically handle the rest, but I found no way of doing it without having objects overstepping their boundaries or making dangerous assumptions. The responsibilities are simply too well-defined: the ListView handles the list presentation logic, each View takes care of its own presentation logic, and the Adapter provides the bridge with the dataset. I also felt that “hard-wiring” the components would heavily restrict the code user’s ability to extend or modify the behavior.

After some thinking, I ended up with three definitions: a RearrangeableListView class extending ListView, and two interfaces to externalize all the behavior that I thought should be external, namely RearrangeListener and MovableView.

The RearrangeListener interface is meant to represent the Adapter, and will most likely be implemented by it. Let’s take a look at it:

interface RearrangeListener {
    void onGrab(int index);
    boolean onRearrangeRequested(int fromIndex, int toIndex);
    void onDrop();
}

The object implementing it is notified when an item in the list is grabbed, dragged or dropped. More importantly, it is responsible for allowing or disallowing rearrangements, and for ensuring the backing dataset reflects the changes appropriately.

The notification behavior is as straightforward as any listener’s. The allowing/disallowing is also quite simple: if the listener returns false from onRearrangeRequested, the move is invalidated; while a return value of true indicates the rearrangement was successful and is already accounted for in the dataset. The reason behind asking the listener to validate moves may not be so intuitive, but remember I didn’t want the ListView to hold any kind of information about the data, so that it could be held and organized in any way. The less assumptions made, the better.

Let’s take a look at how an ArrayAdapter could implement this interface to simply allow and reflect all rearrangements within its data’s bounds:

@Override
public void onGrab(int index) {
    getItem(index).doSomething();
    notifyDataSetChanged();
}
 
@Override
public boolean onRearrangeRequested(int fromIndex, int toIndex) {
     
    if (toIndex >= 0 && toIndex < getCount()) {
        Object item = getItem(fromIndex);
         
        remove(item);
        insert(item, toIndex);
        notifyDataSetChanged();
         
        return true;
    }
     
    return false; 
}

@Override
public void onDrop() {
    doSomethingElse();
    notifyDataSetChanged();
}

This is just an example: the calls to notifyDataSetChanged may or may not be necessary, and both onGrab and onDrop() could be empty snippets.

The second interface I mentioned, MovableView, is defined as follows:

interface MovableView {
    public boolean onGrabAttempt(int x, int y);
    public void onRelease();
}

When the user attempts to grab a View for dragging, and it implements this interface, it can be notified of what’s happening and is allowed to reject a grab attempt, just as the listener is allowed to reject a rearrangement. Why? Well, the View might want to define a specific area from which it can be grabbed, or a certain set of circumstances under which that makes sense. Imagine the typical a list item with a grab handle on the right — the interface would be implemented like this:

@Override
public boolean onGrabAttempt(int x, int y) {
    Rect hitRect = new Rect();
    this.mMyHandleView.getHitRect(hitRect);
    
    return hitRect.contains(x, y);
}

@Override
public void onRelease() {}

Benefits of the design

What are the upsides of demanding the implementation of two interfaces? Well, as I see it, there are several assumptions that we don’t need to make, which allows for greater flexibility and reusability. To name a few:

  1. The dataset format, location and organization is completely irrelevant to the RearrangeableListView.
  2. The Adapter can decide on the fly whether a certain movement is valid, enacting changes in the dataset to add/remove/replace items besides the one being moved.
  3. The View children of the list can have any size, behavior and internal arrangement (even varying between items!), since they are fully responsible for their own piece of the mechanism’s logic.
  4. The ListView can handle UI events only when both the listener and the view approve, and leave room for other components to step in otherwise.

Implementation details

I think most of the code is pretty self-explanatory, so I won’t go into full detail, but there is something I think is worth mentioning: scrolling.

When the user drags an item to the visible bottom (or top) of the list, with the intention to keep dragging it down (or up), the list should automatically swap the held item with the first invisible one, scroll a bit, and keep doing that until the user releases his hold on the item. It took a lot of trial and error to get this behavior right, since several methods are available that sound tempting enough to use but end up introducing more problems than they solve.

The easiest way I found of forcing a scroll on the list was the setSelected() method. In pseudo-java-like code:

if (scrollingUp())
    setSelection(getFirstVisiblePosition() - 1);
else
if (scrollingDown())
    setSelection(getFirstVisiblePosition() + 1);

Now, invoking this code will make the list scroll appropriately once. Calling this from the MotionEvent handler would require the user (or us) to generate additional events just to keep the list scrolling. What I wanted was for the list to automatically scroll at a fixed rate until the user released the item, so instead I wrote a Runnable that executes the above logic and reposts itself with a delay. Again, in java-like pseudocode:

final Runnable autoScroll = new Runnable() {
    @Override
    public void run() {
        
        if (scrolling() && moveApproved()) {
            
            if (scrollingUp())
                setSelection(getFirstVisiblePosition() - 1);
            else
            if (scrollingDown())
                setSelection(getFirstVisiblePosition() + 1);
            
            postDelayed(this, AUTO_SCROLL_DELAY);
        }
    }
};

The advantage of this approach is that we don’t need any additional threads or countdown handlers, since we just rely on the UI’s event loop. To start an autoscroll, a simple call to run() is enough.

Final notes

I intended to give a much more in-depth description of the implementation, but as I said above, I think reading the code will do. Again, the full source code for RearrangeableListView is available in the blogActivity repository. I welcome all comments, bug reports, fixes or improvements — do contact me.

Saludos!

How’s that for a catchy title, huh? Let me take a moment to re-read it. Done. Moving on, then.

I’ve been digging around GitHub and GoogleCode a lot lately. I’ve probably seen more of other people’s code this past month that in the year before that, and specially Java code, for obvious reasons.

Among OOP languages, Java is specially infamous for its average code quality and readability. I won’t argue with that: expressing certain kinds of behavior in Java through code that won’t offend the eyes of a reader is already quite a challenge, and that’s if you actually care. Lots of coders don’t. However, I noticed a peculiar trend I consider particularly dangerous, a trend not restricted to but much more frequent in Java, and thought I’d write a short post about it.

Getters, getters

Let’s say we start writing a class. In a sudden fit of originality, let’s call it Person, and create some of the members we’ll need — say id, name, birthDate and address.

class Person {

    private long id;
    private Date birthDate;
    private String name, address;

}

Since we’re are educated object-oriented programmers, we declare these fields to be private, and create accessors for them: getId() getName(), getAddress() and getBirthDate().

Now, we notice that most of the time we just want the person’s age, rather than its date of birth. Well, thanks to our encapsulation, we can offer that through the public interface without changing our internal data structure. Oh, and while we’re at it, we can also wrap the ugly java.util.Date into JodaTime’s superior DateTime to perform the calculation!

public int getAge() {
    Date now = new Date();

    /* Mmmh,... maybe I should make this blog's content column wider */
    return Years.yearsBetween(
        new DateTime(birthDate),
        new DateTime(now)

    ).getYears();
}

This last bit of code may seem trivial enough, but think about the amazing encapsulation it achieves! The user of this class is totally unaware of how we handle our data, he just interacts with our Person and obtains its age as fast as he can call a getter. He doesn’t need to know that to return that integer we created and discarded at least four objects, and did some math — that’s what encapsulation is about, right?

We then close the editor tab, satisfied with our beautiful OO implementation.

Some time later, another coder (let’s call him John — there’s just no end to my creativity today!) is asked to sort a list of Person instances by age. He saw our getter used somewhere else in the code, so he thinks “oh, good! I’ll just write a Comparator!”.

public class AgeComparator implements Comparator<Person> {

    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }

}

And, armed with the Comparator, he sets off to sort a list of millions of people and spends half an afternoon wondering just why the Garbage Collector is working so much overtime.

The getter anti-pattern

Okay, I admit I could’ve come up with a better example, but you’re looking at a guy that named his class Person and his coder John. Let’s just pretend you are shocked by the sheer impact the previous section had on you, and move on to see why poor John wasted so much of his time.

I don’t think it’s our fault for storing a person’s date of birth, instead of his/her age. We are allowed to compute, aren’t we? We can’t just have a variable for every derived attribute out there, or the data redundancy would quickly get out of hand. No, I think the problem is in the following snippet:

    public int getAge();

Yes. The problem is we named the method getAge(). We could’ve named it calculateAge(), and John would’ve been much more careful, instead of instantly assuming the operation was as light-weight as returning an instance member.

I’ve seen getters perform all kinds of monstrous computations. I’ve seen classes with nothing but getters, half of them false accessors in disguise. I’ve even been fooled several times myself into using a getter that seemed innocent enough only to later discover it was doing all sorts of operations behind my back. I don’t just think this particular abuse of getters is bad, I think it qualifies as an anti-pattern by definition:

  • It initially appears to be beneficial, since getters go a long way towards hiding internal details, but ultimately produces more bad consequences than beneficial results, for abusing them lures users of your code into believing everything is easily accessible.
  • An alternative solution exists: just choose a different name.

There are thousands of verbs other than getcalculate, compute, build, create,… — and if my creativity can come up with four today, so can yours anytime.

All that, or maybe I’m just exaggerating. I do that. Have a nice week!