How to use a native rail ?
Letโs try to create the content rail like a simple title and a list of tile composed by an image and a movie name.
Getting Started
Limitation
See current here
Architecture
The screen will declare a children <RailWithTitleView>
which will be the aggregation of TextPrimitive
and of the NativeRailElement
.
Step-by-step guide
Component declaration
First you can declare your view containing a rail with title.
Caution
landscapeTile
and portraitTile
are demonstration purpose tile that are embedded in the SDK.
export default $View.declare("RailWithTitleView", {
children: /** @lends RailWithTitleView.prototype */ {
title: {
class: $TextPrimitive,
text: ""
},
list: {
class: $NativeRailElement,
itemChooser: {
key: "ratio",
items: [
{
keyValue: "16-9",
item: "landscapeTile"
},
{
keyValue: "2-3",
item: "portraitTile"
}
],
defaultItem: "landscapeTile"
}
}
}
});
ItemChooser
Letโs take quick look at the important property itemChooser
.
- key is the name of the property in the provided data model that will be used to choose in between item type
- items declares the different type of item. Each item is composed of
- a keyValue: if data.key === keyValue, then this type of item
- an item: a type of tile that you will have to define
- defaultItem: will be used if no item is matched
If you provide the following json to the rail along with the previous itemChooser:
{
"name": "My movie",
"ratio": "2-3"
}
It would draw a portrait tile due to key โratioโ === โ2-3โ
Setting some data
Letโs imagine that we have a service returning data with the following structure:
const data = {
railName: "On Now",
listData: [
{
name: "Che tempo fa",
getImageUrl: function () {
//method to retrieve image
},
ratio: "16-9"
}
]
}
In the CatalogScreen
declare a children RailWithTitleView
, and get some data
export default $AppScreen.declare("CatalogScreen", {
children: /** @lends CatalogScreen.prototype */ {
railWithTitleView: {
class: $RailWithTitleView,
}
},
methods: {
prepareData: function () {
return myService.getMyRailData();
},
connectData: function () {
this.railWithTitleView.setData(this.data);
}
}
});
In RailWithTitleView
, implement a function setData.
Note
We also have to implement a convert. The more data youโll give the nativeRailElement, the slower it will get. This is why it is recommended to convert data before providing it to the nativeRailElement.
In a nutshell, know what you provide to the NativeRailElement.setData
.
export default $View.declare("RailWithTitleView", {
methods: {
setData: function (data, options) {
this.title.text = data.railName;
this.list.setData(this.__convertDataToListModel(data.listData));
},
__convertDataToListModel: function (data) {
const listModelData = [];
data.forEach(content => {
if (!content) {
return;
}
listModelData.push({
name: content.name,
imageUrl: content.getImageUrl && content.getImageUrl({height: 185, ratio: content.ratio}),
ratio: content.ratio
});
});
return listModelData;
}
,
}
});
Enjoy !
Launch your UI with a grunt serve
:champagne_glass: Tadaa, you should see some rail being displayed on your rail.
Handling ok on the rail
In the screen, declare that you are listening to an event.
export default $AppScreen.declare("CatalogScreen", {
listen: [
$NativeRailElement.onItemClicked,
]
});
Then in the method of the screen declare onNativeRailElementItemClicked
:
Caution
The name of the function matters as it is generated based on the name of the listener name.
export default $AppScreen.declare("CatalogScreen", {
methods: {
// Route to the fip for example
// The clicked item will be available in data.item
// You can also have the index of the item, in data.index
onNativeRailElementItemClicked: function (data) {
this.route("fipContent", {
name: data.item.name,
description: data.item.description,
imageUrl: data.item.backgroundUrl,
textGenres: data.item.genres.join(","),
releaseYear: data.item.releaseYear
});
}
}
});
Note
The data item that you receive will be one that you provided. You will need to add some info in the converter to receive the right info in the onClick listener.
Modifying other component depending on the focused view
We want to change the blue text to display info of the focused content when the rail is moved forward or backward.
In the screen, declare that you are listening to an event.
export default $AppScreen.declare("CatalogScreen", {
listen: [
$NativeRailElement.onItemClicked,
$NativeRailElement.onScroll
],
});
Then in the method of the screen declare onNativeRailElementScroll
:
Caution
The name of the function matters as it is generated based on the name of the listener name.
export default $AppScreen.declare("CatalogScreen", {
methods: {
onNativeRailElementScroll: function (data) {
// Access another view of the screen to be updated
// Example
return this.contentView.setAdditionnalContent(data.backgroundImageUrl)
}
}
});