- Creating a project
- Required files
- Developing a channel
- Showing the first view
- View UI setup
- Content Getters
- Opening next view
- Opening non-SGDEX view
This tutorial is for building a SceneGraph Developer Extensions (SGDEX) based channel. Developers who want to build their first Roku channel, or are interested in moving their existing channel to RSG, benefit from this guide.
SGDEX includes the following views:
- Video with endcard view
- Category list
Combining the views listed above, the developer can create their channel without a deep knowledge of Roku SceneGraph components.
Creating a project
Using an IDE, create a new project or use an existing project
Make sure the app manifest contains:
All views are developed in HD resolution and autoscaled to FHD and SD. Make sure to develop the views for the app in HD resolution as well.
In the source folder, create a file
main.brs and populate it with the following:
The code above creates the scene and is the first step in building an app.
Here, "MainScene" is the name of the scene.
Developing a channel
To develop a SGDEX channel, create a Scene that extends from BaseScene.
The XML file contains the following:
This function passes params from
main.brs and decides what view is displayed.
You can display a home screen(view), or create a deep linking screen(view) here by passing the proper params.
The scene has a ComponentController interface field that is used to show views and control flows.
A componentController is the component that controls all views.
|currentScreen||The view that is currently shown|
|shouldCloseLastScreenOnBack||Indicates if the last screen in the stack should be closed before the channel exits|
Manipulate this screen if the channel needs to implement deep linking or, a confirm exit dialog when the user presses back on the first screen.
|show||Used to add a new view to the stack|
Showing the first view
To show the first view, the developer needs to create the view, add content to it, and then display it.
/components/MainScene.brs, add the following to indicate the show(args) function:
The above code creates a simple grid view and displays it.
All views that extend Component have the following interfaces:
View UI setup
|style||The style to be used, see the documentation for each view|
|posterShape||The shape of the poster to be used in this view|
|overhang||Congifure the overhang node to customize each view of your channel. For example, some views can have options or another logo or title|
View visibility handling
|wasClosed||Triggered when the current view is closed. Use this when reading any value from a closed view. For example, itemFocused to set proper focus on the previous screen|
|saveState||Triggered when a new view is opened after the current view. It is useful when data needs to be saved before another view is opened. For example, pause audio or video when a new view is opened|
|wasShown||Triggered when the current view is opened for the first time or restored after the top view was closed|
|close||Use this field to manually close view. For example, during a registration flow, all registration views are closed after successful login|
If the developer does not have content for the grid, use HandlerConfigGrid that describes how to populate rows for grid view:
A content getter is a component responsible for populating content for views.
To load certain data for a view, use content getters.
To add root Content Getter, add it to the content of the created view:
Each SGDEX view has an Associative Array (AA) Content Getter field and contains the following:
name [required] - Project Content Getter component name
fields [optional] - Developer interface fields to be populated
Default Content Getter
Content getter provides a predefined list of interfaces:
|content||Contentto be modified by the content getter. This content can be the view's content field or a child of it when the content for the child needs to be loaded (Example, a row in the grid or an item in the details or video view)|
Config added by the developer. Use handlerConfig to read the value of the config or restore it to content if needed
Note: Content getter removes processed Configs. If data needs to be reloaded each time content is shown, restore the config for the content in the proper Content Getter
|offset||Indicates which offset is in use. Use offset for horizontal lazy loading of the grid row|
|pageSize||Indicates the page size configured by the developer. Used for horizontal lazy loading of the grid row|
Implementing Content Getter
To implement a Content Getter, create a component and extend it from ContentHandler.
Content Getter implements only one required function GetContent() that does not return anything:
Contents of the JSON file
Note: According to SceneGraph best practices, it is suggested to use
As this removes multiple rendezvous between the render thread and the task node.
Opening next view
To open a new view for a certain action, use the same mechanism to create and populate the view.
For example, to open details screen upon selection on a grid, use:
Assuming the following has been executed,
Implement the function
The above code creates new details view and passes grid row as the content for details. It also uses jumpToItem to set starting index.
If the developer does not want to pass a list of items but only one item, they can use the snippet below:
Details view interfaces
Details view provides several interfaces:
buttons type = "node"
Buttons content node
Buttons support same content meta-data fields as Label list which sets the title as well as a small icon for each button.
|TITLE||String||The label for the list item|
|HDLISTITEMICONURL||Uri||The image file for the icon displayed to the left of the list item label when the list item is not focused|
Tells details view how your content is structured
Defines the logic of showing content when pressing left on the first item or pressing right on the last item
If set to true, it starts playback from first item (when pressing right) or the last item (when pressing left)
|itemFocused||Integer||0||Indicates the item currently in focus|
|jumpToItem||Integer||0||Manually focus on the desired item|
|buttonFocused||Integer||0||Tells what button is focused|
|buttonSelected||Integer||0||Is set when the button is selected by a user|
|jumpToButton||Integer||0||Interface for setting the focused button|
Currently displayed item
This item is set when the Content Getter finishes loading extra meta-data
Getting extra metadata for details view
Sometimes when setting content to details view you are still pending some info to be loaded to properly show this item.
To resolve this issue you should use content getter for details screen.
Opening non-SGDEX view
SGDEX is not limited to use only SGDEX views; the channel can show its own view and observe its fields.
To open a non-SGDEX view, create, and populate interface fields, set observers and call:
This hides the current view (if any) and displays the non-SGDEX view.
Note: Component controller set's focus on your view, so your view should implement proper focus handling.
Whenever the view receives focus, it should be checked if it's in the focus chain and the node unfocused.
Focus handling is important as component controller sets focus to a non-SGDEX view in two cases:
- The view is just shown
- The view is restored after top view was closed
Component Controller is responsible for closing this view when the back button is pressed.
If the view needs to be closed manually, a new field called "close" should be added to the view.
yourView.close = true, the developer can close the current view and the previous view is opened.