[FREE] Custom Spinner Extension

1. Overview

CustomSpinner is a non-visible Kodular extension that creates a customizable dropdown menu using a PopupWindow.

Unlike the standard Spinner, the dropdown is completely controlled by the extension. You can attach it to any visible component and customize its appearance, position, items, selection, spacing, padding, text size, colors, and font.

The extension does not occupy space in the screen layout.

2. Extension Information

Property Value
Extension Name CustomSpinner
Package com.trickylabx.customspinner
Component Type Non-visible Extension
Category Extension
Minimum Android Depends on Kodular project

3. Basic Workflow

The normal workflow is:

CustomSpinner
      β”‚
      β”œβ”€β”€ SetAnchor(Button)
      β”‚
      β”œβ”€β”€ SetItems(List)
      β”‚
      └── Open()
             ↓
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚ Item 1       β”‚
       β”‚ Item 2       β”‚
       β”‚ Item 3       β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

For example:

Screen.Initialize
    ↓
CustomSpinner1.SetAnchor(Button1)
    ↓
CustomSpinner1.SetItems(...)
    ↓
Button1.Click
    ↓
CustomSpinner1.Open

When the user selects an item, the ItemSelected event fires.

4. Designer Properties

4.1 BackgroundColor

Controls the background color of the dropdown.

Type: Color

Default:

White

Example:

BackgroundColor = #FFFFFF

Changing this property while the popup is open rebuilds the popup with the new background.


4.2 TextColor

Controls the text color of every dropdown item.

Type: Color

Default:

Black

Example:

TextColor = #000000

4.3 TextSize

Controls the text size of dropdown items.

Type: Integer

Unit: sp

Default:

16

Example:

TextSize = 18

Values below 1 are automatically changed to 1.


4.4 CornerRadius

Controls the corner radius of the dropdown background.

Type: Integer

Unit: dp

Default:

8

Example:

CornerRadius = 12

Setting it to 0 creates square corners.


4.5 Elevation

Controls the Android elevation/shadow of the popup.

Type: Integer

Unit: dp

Default:

4

Example:

Elevation = 8

Higher values generally produce a stronger shadow on supported Android versions.


4.6 ItemPaddingLeft

Controls the left padding inside every dropdown item.

Type: Integer

Unit: dp

Default:

0

Example:

ItemPaddingLeft = 16

4.7 ItemPaddingRight

Controls the right padding inside every dropdown item.

Type: Integer

Unit: dp

Default:

0

Example:

ItemPaddingRight = 16

4.8 ItemSpacing

Controls the vertical space between dropdown items.

Type: Integer

Unit: dp

Default:

0

For example:

ItemSpacing = 8

Produces approximately:

Item 1

        8dp

Item 2

        8dp

Item 3

The spacing is applied only between items, not before the first item or after the last item.


5. Position Property

Position

Controls where the dropdown appears relative to the anchor component.

Type: Choice

Available values:

Below
Above

Below

The dropdown opens underneath the anchor.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Button     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Item 1       β”‚
β”‚ Item 2       β”‚
β”‚ Item 3       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Above

The dropdown opens above the anchor.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Item 1       β”‚
β”‚ Item 2       β”‚
β”‚ Item 3       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↑
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Button     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

6. Functions

6.1 SetAnchor

Sets the component that the dropdown will attach to.

Input

Component

Example:

CustomSpinner1.SetAnchor(Button1)

The button does not automatically open the spinner. You can use any event or logic to call Open().


7. SetItems

Sets all dropdown items at once.

Input

List

Example:

CustomSpinner1.SetItems
    make a list
        "Apple"
        "Banana"
        "Orange"

The previous items are removed and replaced with the new list.

Important

The order of the list determines the item index.

Example:

List:

Apple
Banana
Orange

Corresponds to:

1 β†’ Apple
2 β†’ Banana
3 β†’ Orange

8. AddItem

Adds a single item to the end of the dropdown.

Input

Text

Example:

CustomSpinner1.AddItem("Apple")
CustomSpinner1.AddItem("Banana")
CustomSpinner1.AddItem("Orange")

Result:

Apple
Banana
Orange

Unlike SetItems, AddItem does not remove existing items.


9. Remove Item by Name

The extension can remove an item using its text/name.

Example:

RemoveItem("Banana")

If the list is:

Apple
Banana
Orange

the result becomes:

Apple
Orange

If the specified item does not exist, nothing is removed.

If duplicate names exist, the implementation should define whether the first matching item or all matching items are removed. For predictable behavior, removing the first matching item is recommended.


10. Remove Item by Index

An item can also be removed using its index.

The index is 1-based, consistent with SelectedIndex.

Example:

1 β†’ Apple
2 β†’ Banana
3 β†’ Orange

Calling:

RemoveItemAt(2)

produces:

Apple
Orange

An invalid index should simply do nothing rather than causing the app to crash.


11. ClearItems

Removes all items from the dropdown.

Example:

CustomSpinner1.ClearItems

Before:

Apple
Banana
Orange

After:

No items

The current selection is also cleared.


12. Open

Opens the dropdown.

Example:

Button1.Click

    CustomSpinner1.Open

The dropdown will appear relative to the component specified by SetAnchor.

If:

  • no anchor is assigned, or
  • there are no items,

the dropdown does not open.

If the dropdown is already open, calling Open() closes it in the current implementation.


13. Close

Closes the dropdown if it is currently open.

Example:

CustomSpinner1.Close

Calling Close() when the dropdown is already closed is safe.


14. SelectedIndex

Returns the currently selected item’s 1-based index.

Example:

Apple
Banana
Orange

If Banana is selected:

SelectedIndex = 2

If nothing has been selected:

SelectedIndex = 0

Important

The extension intentionally uses 1-based indexing, which is more convenient for App Inventor/Kodular list operations.


15. SelectedItem

Returns the currently selected item’s text.

Example:

Apple
Banana
Orange

If Banana is selected:

SelectedItem = "Banana"

If nothing is selected:

SelectedItem = ""

16. ItemSelected Event

The ItemSelected event fires when the user taps an item.

Event parameters

Item
Index

Example:

when CustomSpinner1.ItemSelected item index

If the user selects Banana:

item  = "Banana"
index = 2

The index is 1-based.


17. Recommended Block Structure

A typical implementation would look like:

when Screen1.Initialize

    call CustomSpinner1.SetAnchor
        Button1

    call CustomSpinner1.SetItems
        make a list
            "Home"
            "Profile"
            "Settings"
            "About"

Then:

when Button1.Click

    call CustomSpinner1.Open

And:

when CustomSpinner1.ItemSelected item index

    set Label1.Text to item

AIX:
CustomSpinner.aix (20.4 KB)

2 Likes

Thank you for your contribution. I would appreciate it if you could upload the blocks and provide some demonstrations.

1 Like