From The Blog: Widget updates – resizable picker wheels and more

Since the earliest incarnation of the PickerWheelWidget, created via widget.newPickerWheel(), its overall size was a fixed 320×222 pixels. The origin of this goes back to the first visual implementation of the widget which was based on iOS 6 styling/size. That carried through to updated versions, even with the introduction of more modern widget themes like iOS 7+ and Android Holo.

Clearly, this was not ideal for Corona developers. While those using a typical 320×480 content area in portrait orientation could use picker wheels that spanned the full content width, developers using other content area sizes like 640×960 were stuck with tiny, undersized picker wheels. More troubling is the fact that, on tablets and larger displays, “native” picker wheels like that used for the iOS alarm clock selector do not occupy the entire screen (visually, that would be overwhelming).

Introducing resizable picker wheels

Starting with the latest Corona public release (2016.2992), all Corona developers can now easily implement resizable picker wheels. Visually, these can simply adopt the modern iOS or Android Holo themes, or you can visually customize them using frames from an image sheet.

If you’re comfortable with diving directly into the documentation, you may — otherwise, continue reading for a summary of how resizable picker wheels are constructed.

Basic implementation

The primary “trigger” to enable a resizable picker wheel is the style key in the widget.newPickerWheel() constructor. This must be set to "resizable":

local pickerWheel = widget.newPickerWheel( { style = "resizable",

Next, you must define a width value for the picker wheel. Obviously, this tells Corona what the overall content width of the widget should be. For example:

local pickerWheel = widget.newPickerWheel( { style = "resizable", width = 280,

Next, you must define a rowHeight value, not an overall content height of the widget. Picker wheels have always, and remain still, a 5-row selector where the end user sees a “selection row” in the center along with 2 rows of other options both above and below the central row:

picker

As such, when constructing a resizable picker wheel, you must define the row height to yield an overall widget which is 5× that height. For example, setting rowHeight to 50 will result in a picker wheel which has a base content height of 250 pixels.

local pickerWheel = widget.newPickerWheel( { style = "resizable", width = 280, rowHeight = 50,

Finally, as always, you’ll need to configure the columns of labels/indexes which will populate the picker wheel. This process won’t be repeated here, so if you’re not familiar with how to define columns, please see the documentation.

Feature enhancements

In addition to basic resizable construction, we’ve added some new features/methods which apply to all picker wheels (resizable and traditional):

Select value method

We’ve added a new method, object:selectValue(), which allows you to forcibly select any valid option within the picker wheel without any touch interaction from the user. This method can perform the selection either in an animated state — moving/easing the column to the desired row — or simply in an instantaneous “snap” to that position. This new method is extremely useful if you want some other element/button/event in your app to control the picker wheel.

Selection listener

You can now specify a listener function which will be triggered when the user selects an option in the picker wheel. This event will occur when the end user taps/selects any option, or if you call object:selectValue() in your code. To define this listener, simply specify the onValueSelected key in your widget constructor with a pointer to the function. Then, within the listener function itself, you will receive event.column and event.row indicating the numerical indexes of the column/row selected.

local function pickerSelectionListener( event ) print( "Column:", event.column ) print( "Row:", event.row ) end local pickerWheel = widget.newPickerWheel( { style = "resizable", width = 280, rowHeight = 50, onValueSelected = pickerSelectionListener,

Label padding

You can now adjust the label padding on a per-column basis for better alignment of labels within the picker wheel columns. As always, you can still align your column labels to either left, center, or right, but now you can also adjust the padding of labels with the labelPadding key, specified within the sub-table that defines the column’s options:

local columnData = { { align = "left", width = 120, labelPadding = 20, startIndex = 2, labels = { "Hoodie", "Short Sleeve", "Long Sleeve", "Sweatshirt" } },

Essentially, for left-aligned labels, this value will increase or decrease the padding from the left side of the column, while for right-aligned labels, this value will increase/decrease padding from the right side. Note that the default value is 6 (pixels) and that this key will be ignored for columns with "center" alignment.

Visual customization

For those developers who want to step even further ahead in visual styling, resizable pickers support a completely revamped visual customization method. This will allow you to set up just one image sheet and use its style across every picker wheel in your app, regardless of its size.

This flexible styling is accomplished through a “slice” configuration similar to the widget button’s 9-slice construction. For picker wheels, the following slices can be utilized:

widget-pickerwheel-resizable

  1. border/overlay corners
  2. border/overlay top-side and bottom-side spans
  3. border/overlay left-side and right-side spans
  4. top “fade” span which underlies the border/overlay
  5. bottom “fade” span which underlies the border/overlay
  6. top edge span for the central “selection” row
  7. bottom edge span for the central “selection” row
  8. separator/divider span to visually divide the picker wheel columns

For further customization power, you can even adjust the padding of the border/overlay frame on all sides with one key, borderPadding, allowing you to expand the border beyond the picker wheel’s defined width and constructed height. Also, you can adjust the spread of the central selection row edge spans with the middleSpanOffset value, allowing you to expand or contract the height of the selection area without adjusting your image sheet or rowHeight value whatsoever.

To fully understand how to implement visual customization for a resizable picker wheel, please see our documentation.

In conclusion

These updates to widget.newPickerWheel() bring a considerably higher degree of control, styling, and overall useability to Corona developers implementing picker wheels. Comments or feedback? Please contribute in the Corona Forums.

View the full article