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 contentListRowPresenter
defines how various content in a row should be displayed and arrangedDetailsDescriptionPresenter
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