Summary: Demonstrating how to register a swipe over a row of radio buttons in Android
In this Android coding example, a user is presented with a row of radio buttons. Clicking on a radio button causes the background of the application to change to a different color.
That’s the easy part! Here’s the hard part: there’s a secret swipe, from the left edge of the screen all the way to the right edge, which changes the background color to black. Not only do you need to swipe all the way from left to right, you also have to swipe over the radio buttons.
Android is designed to make it easy for radio buttons to register and respond to clicks. This example is complicated because detecting a swipe over the screen, if done incorrectly, may interfere with that mechanism. Also, we don’t want the left-to-right swipe to do anything if it falls outside the radio buttons. So special code needs to be added to check for this when swiping.
The code sample which solves this problem is available as a project in github.
These are the key parts to the solution:
For responding to individual clicks, the radio buttons are given an onClickListener
when they are created.
Responding to a swipe is the tricky part. The activity’s onTouchEvent
is implemented to check when a swipe starts (with MotionEvent.ACTION_DOWN
) and ends (with MotionEvent.ACTION_UP
). Then, as the user’s finger moves across the screen, the code in onTouchEvent
checks to see if its position stays over the radio buttons.
The radio buttons are laid out in a LinearLayout
and given a specific id, surround_layout
. If we know the upper and lower vertical boundaries to this layout, then we can check to see whether the user’s “touch” strays outside this boundary while it moves across the screen – when onTouchEvent
receives a MotionEvent.ACTION_MOVE
event.
Here’s the “design” view of that layout in Android Studio. The boundaries of the layout show up as a white frame.
That’s great, but how do we get the boundaries of the layout when our application is running? The answer is that our Activity
implements ViewTreeObserver.OnGlobalLayoutListener
. This is done so that the boundaries can be computed after the layout is inflated. If you try to get these values before the view is inflated, you’ll find that the boundaries are not correct.
This code example is useful because it forces you to deal with the way layouts are created and inflated. This is something that is usually safely ignored when programming for Android. However, understanding these details can save you a lot of time when they become important.