The effect I’m going after is the same as in Google+ and the new Market app:
- Several homescreens/streams/dashboard views. One visible at a time, swipe left and right to switch between them.
- There is no padding around each child view, they take all the space that is allocated to their parent view.
- Switching views one-at-a-time. Don’t want flinging over 3 views at once.
Gallery widget is not the best starting point for implementing something like this:
- It supports padding around each gallery item. Gallery items don’t generally take up all the horizontal space, several can be visible at the same time, next to each other.
- When user swipes, Gallery flings, potentially over several child elements. Preventing that requires some hacky code.
- It is adapter-based. Cannot define all the views in singe XML layout, need to create/inflate them in adapter.
HorizontalScrollView. It’s much simpler than Gallery so less quirks to hack around. The most prominent feature that
Gallery has and
HorizontalScrollView lacks, is that gallery always tries to center on one of its elements. HorizontalScrollView can be scrolled freely, and will happily stay at any horizontal scroll offset. But this is not hard to fix. By listening in on touch events and detecting flings, I can make it smooth-scroll to the nearest screen-ful in fling’s direction. I’m saying “screen-ful” not “element” because HorizontalScrollView is a subclass of
FrameLayout and can only have a single child view. So I’m putting a horizontal LinearLayout in there, and the child views go in that layout. The LinearLayout is slightly hacked too to set appropriate widths for its child views.
Here’s screencast of updated the demo application:
So two classes of interest in the repo:
LockingHorizontalScrollView. “Locking” as in “will lock on to grid“
WideLinearLayout. “Wide” as in “each child element will be asked something similar to FILL_PARENT“