Create class-based custom item renderers for Feathers UI data containers

🚧 Under construction! This documentation is still being written.

Developers may create a subclass of any of the core UI components to create a custom item renderer for a Feathers UI data container. A class-based item renderer provides the most control over how an item renderer looks and behaves, but it also requires a bit more advanced knowledge of UI component archictecture and internals than is required when using ItemRenderer or LayoutGroupItemRenderer directly with DisplayObjectRecycler.

Subclassing LayoutGroup or LayoutGroupItemRenderer is often the quickest easiest way to create a custom class-based item renderer, since they provide built-in capabilities like background skins and layouts to position sub-components. However, in cases where more control over optimizing measurement and layout is necessary, subclassing FeathersControl provides the most flexibility, at the expense of requiring more low level code that needs to be written from scratch.

It's highly recommended to read through How to create a custom UI component to familiarize yourself with the UI component lifecycle and low-level APIs that are available.

Special interfaces

If a class-based custom item renderer implements certain built-in interfaces, the data container will populate the interface's properties automatically, and the item renderer may use that data when updating sub-components or graphics.

For example, if a custom item renderer implements IDataRenderer interface, its data property will be populated with an item from the container's data provider.

class MyCustomItemRenderer extends LayoutGroup implements IDataRenderer {
    public function new() {
        super();
    }

    private var _data:Dynamic;

    public var data(get, set):Dynamic;

    private function get_data():Dynamic {
        return _data;
    }

    private function set_data(value:Dynamic):Dynamic {
        if (_data == value) {
            return _data;
        }
        _data = value;
        setInvalid(DATA);
        return _data;
    }

    private var label:Label;

    override private function initialize():Void {
        super.initialize();
        label = new Label();
        addChild(label);
    }

    override private function update():Void {
        var dataInvalid = isInvalid(DATA);
        if (dataInvalid) {
            if (_data != null) {
                label.text = _data.title;
            }
            else {
                label.text = null;
            }
        }
        super.update();
    }
}

Some interfaces, described below, are supported by all data containers, such as IDataRenderer, while others are created with a specific data container in mind, such as IListViewItemRenderer for ListView.

Interfaces for all data containers

The following interfaces are supported by all data containers.

  • IDataRenderer - The data container automatically sets the item renderer's data property to an item from the collection.
  • ILayoutIndexObject The data container automatically updates the layoutIndex property to indicate where the item is located within the layout's order.
  • IToggle - The data container automatically updates the item renderer's selected property when the selected item changes.
  • ITriggerView - The data container will listen for TriggerEvent.TRIGGER instead of MouseEvent.CLICK and TouchEvent.TOUCH_TAP to determine when selection changes.
  • IUIControl automatically updates the enabled property.

A few more interfaces are designed for a specific container only and will be ignored by other containers.

Interfaces for GridView

Interfaces for GroupListView

Interfaces for ListView

Interfaces for TreeView

Interfaces for TreeGridView