Step 4: Edit the User Interface Through Presenters (Fire TV)
Let's explore the Presenter
class. The Presenter
class allows us to define the look and feel of our Leanback-enabled app without editing the underlying data structure.
The Presenter Class
The Leanback template we created was built following a custom version of the common development pattern, Model-view-controller (MVC), in which the Presenter
class acts as the View
. The Presenters
are passed to the ArrayObjectAdapter
as arguments and define how the content of the Adapter should be displayed
The Leanback approach provides a variety of predefined Presenters:
-
CardPresenter
defines singular content -
ListRowPresenter
defines how various content in a row should be displayed and arranged -
DetailsDescriptionPresenter
defines the UI of theDetailsFragment
.
Implementing the Presenters are quite similar: they all follow the ViewHolder
pattern and are mostly composed by Custom Views with methods to set the fields of the views.
Let's take a closer look at the customizing the CardPresenter
as an example.
Customizing the CardPresenter
In the BrowseFragment
, we see that the CardPresenter
defines the UI of a single item of the adapter.
public
class
MainFragment
extends
BrowseFragment
{
CardPresenter
cardPresenter
=
new
CardPresenter
();
//Create the adapter for the row and add all the movies
ArrayObjectAdapter
listRowAdapter
=
new
ArrayObjectAdapter
(
cardPresenter
);
}
The highlighted view in the previous image is a custom view called ImageCardView
and is used in the CardPresenter
to define the UI of a single component.
Let's analyze how views are initialized in the CardPresenter
.
public
class
CardPresenter
extends
Presenter
{
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
)
{
...
ImageCardView
cardView
=
new
ImageCardView
(
parent
.
getContext
);
cardView
.
setFocusable
(
true
);
cardView
.
setFocusableInTouchMode
(
true
);
return
new
ViewHolder
(
cardView
);
...
}
}
There are two things to notice here:
-
As we mentioned before, the
CardPresenter
is built on theViewHolder
pattern. This ensures views are correctly recycled and memory is not wasted. -
The
CardView
is set toSetFocusable(true)
andsetFocusableInTouchMode(true)
. Although there is no existing touch interaction on a TV screen, this step is necessary because this is how Android currently manages the focus-ability of views.
Now, let's take a look at how the components of the ImageCardView
(and of the Presenter
) are set:
public
void
onBindViewHolder
(
Presenter
.
ViewHolder
viewHolder
,
Object
item
)
{
Movie
movie
=
(
Movie
)
item
;
ImageCardView
cardView
=
(
ImageCardView
)
viewHolder
.
view
;
if
(
movie
.
getCardImageUrl
()
!=
null
)
{
cardView
.
setTitleText
(
movie
.
getTitle
());
cardView
.
setContentText
(
movie
.
getDescription
());
Glide
.
with
(
viewHolder
.
view
.
getContext
())
.
load
(
movie
.
getCardImageUrl
())
.
centerCrop
()
.
into
(
cardView
.
getMainImageView
());
}
}
In this example, we use our own custom class "Movie" to retrieve the information we want to display.
The cardView
is retrieved from the ViewHolder
, then we have the simple setters setTitleText()
and setContentText()
, to edit the main fields of the view.
To retrieve the image for the thumbnail, Leanback automatically uses the Glide library (but you can easily replace it with the image loading library of your choice).
Next Steps
Continue on to the next step: Step 5: Provide the Details of the App Content Through the DetailsFragment .
Last updated: Oct 29, 2020