As part of our continuing focus on mobile, we recently shipped List Your Space and Manage Listing on mobile. A rapidly-growing team came together for a simultaneous release on Android and iPhone, allowing hosts to quickly and easily create and manage their listing whenever and wherever they want.
Two big challenges we wanted to tackle with List Your Space on mobile were verifying the location of your listing and easily capturing and uploading photos of your space. Both of these steps can be complicated through a web browser, but the mobile platforms lend themselves well to these tasks. However, this doesn’t mean that you are limited to a single platform. We support managing your listing on all platforms at every stage during the process of creation, pre-list, and post-list!
Speaking of managing beautiful photos of your space, we also built really slick photo rearranging and captioning into our new mobile tool box. We feel this especially stands out on Android, where smoothly-animating, responsive photo rearrangement is simply not found. All of this amazing user experience is supported back to Android 2.2 (Froyo), just like everything else in our app. Let’s dive into how we made the new PhotoRearranger View class on Android. To start, here are the main building blocks we used:
The PhotoRearranger is built entirely upon the concept of mapping photo indices to rectangular portions of the screen. These rectangles are calculated in onSizeChanged(), so they are cached and always reflect the current size and orientation of the screen. After the user long-presses on a photo, we offset the photo’s location based on drag events (tracked by maintaining a touch pointer id) and scale it over time based on an interpolator to indicate selection. Each frame, we calculate the current index based on the photo’s screen location. If this differs from the last frame’s index, we adjust the location of all other photos in the collection over time, based on two more interpolators, one for horizontal translation and the other for vertical translation. When the user releases the photo by lifting his or her finger, we calculate the current offset from the target screen rectangle and interpolate smoothly until the scale and location of the photo match that target rectangle.
Every photo is responsible for reporting to the PhotoRearranger if it is currently animating. The View will then use this information to decide whether or not the next draw should be scheduled. This concept is similar to GLSurfaceView.RENDERMODE_WHEN_DIRTY and serves to save your device’s battery life while admiring those wonderful photos! All photos are drawn to the View’s Canvas with the method Canvas.drawBitmap(Bitmap, Rect, RectF, Paint) with cached rectangles for maximum efficiency. If you’re coming from a graphics background, you can think of the Rect object as texture coordinates in the range of (0, 0) to (w, h) and the RectF object as screen coordinates. Fortunately, all of the images from our server are guaranteed to have the same aspect ratio, but the PhotoRearranger will maintain aspect ratio during scaling if it detects something is amiss. Of course, all of this manual drawing also means we have to handle drawing the multiselect CheckBoxes and updating their states based on TouchEvents, but this is trivial since we have screen locations for each photo precomputed.
Since we needed to be able to scroll while dragging a photo, we also included a Scroller object that we could use to manually control scroll behavior while maintaining the standard Android flywheel scrolling behavior and feel. By defining regions at the top and bottom of the screen that will cause a scroll, the user is able to move a photo from the last index to the lead position (or even the trash can, which lives under the ActionBar overlay) easily and intuitively.
Still with me? Great! The final piece to the PhotoRearranger logic is the fact that the lead image spans the entire View, while all other indices are confined to columns (more on this later). Because of this size difference, all photos maintain yet another interpolator responsible for updating scale over time. This is separate from the selection scale interpolator for simplicity and is updated whenever the photo’s index is modified. With this final interpolator, photos not only move from index to index smoothly, but also scale smoothly when entering or leaving the lead position. Speaking of the photo columns, since this is a custom View, many custom attributes may be overridden in XML, such as photos per row, photo padding, haptic feedback duration, interpolated animation duration, selection scale factor, edge scrolling threshold and speed, progress spinner resources, checkbox state resources, and several more!
Be sure to check out the new List Your Space and Manage Listing features on Android and iPhone, and stay tuned for more great mobile host tools coming your way.