codejeff.com

Archive for August, 2010

Android Number Picker

Wednesday, August 11th, 2010

For my first open source release of code, I bring you an Android Compound Control. This particular custom control is a number picker with a repeat feature. This is a very basic control, but not one that is provided in the given pre-built control set. For those of you looking to easily fill that void, or perhaps learn how the auto-increment feature was implemented, I give you NumberPicker.


NumberPicker is an extension of LinearyLayout, and as such can be configured horizontally or vertically, shown above. The size of the elements is hard coded at this time, but by looking in the documentation it can be seen that it is very easily changed. Here is an example of using a vertically configured version of this element in an XML layout:

<net.technologichron.android.control.NumberPicker
android:id="@+id/Picker1"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</net.technologichron.android.control.NumberPicker>

There are two particular elements of this control I’d like to talk about. Firstly, is implementing the repeat feature. My first instinct when developing this was to spawn a thread to periodically change the value as long as a user held one of the buttons. I quickly learned that this wasn’t possible by simply spawning a Thread, as only the GUI thread can make changes to the GUI. Further reading in the Android manual led me to the use of Handler to schedule the changes.

Whenever a button is long pressed, a flag is set, and a new Runnable, RepetetiveUpdater, is posted to the Handler. This new RepetetiveUpdater will check if a flag is set, and increment or decrement the value appropriately, and then post a new RepetetiveUpdater to the Handler with a delay of 50 ms. Once the user releases the button, an OnTouchListener checks if the the last touch action was the release of the active button and disables the flag originally set when the long click first occurred.

The second thing I’d like to point out is how the parsing occurs for the EditText value from String to Integer. Much to my surprised, one utilizing a hardware keyboard can force non-numeric characters into an EditText that is configured to be numeric.

There are two issues with this; we don’t want to crash trying to parse something that’s not an Integer, and we don’t want to have our number go up and away if a new line gets through. To mitigate these issues, whenever a key is pressed, an OnKeyListener will save the current valid value that was in place before the user pressed a key, attempt to parse the new text as is, and if it fails, restore the edit text to the last valid value. In this way, whenever a invalid key is pressed, the user doesn’t even notice.

I hope that there will be some utility to some one by me releasing NumberPicker under the BSD license. If you have any questions feel free to voice them in the Comments.

UPDATE: I’ve created a sample Eclipse project that may help you work out implementation details: NumberPickerExample