Aplikacja multimedialna działająca na telewizorze musi umożliwiać użytkownikom przeglądanie oferowanych treści, wybieranie ich i odtwarzanie. Przeglądanie treści w przypadku tego typu aplikacji powinno być proste, intuicyjne, atrakcyjne wizualnie i zachęcające do interakcji.
Przeglądarka katalogu multimediów składa się zwykle z kilku sekcji, a każda z nich zawiera listę multimediów. Przykłady sekcji w katalogu multimediów: playlisty, polecane treści, polecane kategorie.
Używaj funkcji udostępnianych przez Compose for TV, aby zaimplementować interfejs użytkownika umożliwiający przeglądanie muzyki lub filmów z katalogu multimediów aplikacji.
Tworzenie funkcji typu „composable” dla katalogu
Wszystko, co pojawia się na wyświetlaczu, jest implementowane jako funkcja składana w Compose for TV. Zacznij od zdefiniowania funkcji składania dla przeglądarki katalogu multimediów:
@Composable
fun CatalogBrowser(
featuredContentList: List<Movie>,
sectionList: List<Section>,
modifier: Modifier = Modifier,
onItemSelected: (Movie) -> Unit = {},
) {
// ToDo: add implementation
}
CatalogBrowser
to funkcja typu „composable” implementująca przeglądarkę katalogu mediów. Funkcja przyjmuje te argumenty:
- Lista polecanych treści.
- Lista sekcji.
- Obiekt Modifier.
- Funkcja wywołania zwrotnego, która uruchamia przejście między ekranami.
Ustawianie elementów interfejsu
Edytor na potrzeby kompozycji na telewizory oferuje listy leniwych zasobów, czyli komponent do wyświetlania dużej liczby elementów (lub listy o nieznanej długości). Aby umieścić sekcje w pionie, użyj funkcji LazyColumn
. LazyColumn
udostępnia blok LazyListScope.() -> Unit
, który oferuje DSL do definiowania zawartości elementu. W tym przykładzie każda sekcja jest umieszczona na liście pionowej z przedziałem 16 pikseli między sekcjami:
@Composable
fun CatalogBrowser(
featuredContentList: List<Movie>,
sectionList: List<Section>,
modifier: Modifier = Modifier,
onItemSelected: (Movie) -> Unit = {},
) {
LazyColumn(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(sectionList) { section ->
Section(section, onItemSelected = onItemSelected)
}
}
}
W tym przykładzie funkcja kompozytowa Section
określa sposób wyświetlania sekcji.
W następującej funkcji LazyRow
pokazujemy, jak ta pozioma wersja funkcji LazyColumn
jest używana do definiowania listy poziomej z blokiem LazyListScope.() -> Unit
przez wywołanie udostępnionego języka DSL:
@Composable
fun Section(
section: Section,
modifier: Modifier = Modifier,
onItemSelected: (Movie) -> Unit = {},
) {
Text(
text = section.title,
style = MaterialTheme.typography.headlineSmall,
)
LazyRow(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(section.movieList){ movie ->
MovieCard(
movie = movie,
onClick = { onItemSelected(movie) }
)
}
}
}
W komponowalnym elemencie Section
używany jest komponent Text
.
Tekst i inne komponenty zdefiniowane w Material Design są dostępne w bibliotece tv-material . Możesz zmienić styl tekstów zdefiniowany w Material Design, odwołując się do obiektu MaterialTheme
.
Ten obiekt jest też udostępniany przez bibliotekę tv-material.
Card
należy do biblioteki tv-material.
MovieCard
określa, jak dane każdego filmu są renderowane w katalogu zdefiniowanym w tym fragmencie kodu:
@Composable
fun MovieCard(
movie: Movie,
modifier: Modifier = Modifier,
onClick: () -> Unit = {}
) {
Card(modifier = modifier, onClick = onClick){
AsyncImage(
model = movie.thumbnailUrl,
contentDescription = movie.title,
)
}
}
Wyróżnianie polecanych treści
W przypadku opisanego wcześniej przykładu wszystkie filmy są wyświetlane w takim samym stopniu.
Mają ten sam obszar i nie różnią się wizualnie.
Niektóre z nich możesz wyróżnić za pomocą Carousel
.
Karuzela wyświetla informacje w układzie elementów, które mogą się przesuwać, zanikać lub pojawiać na ekranie. Za pomocą tego komponentu możesz wyróżnić polecane treści, takie jak nowo dostępne filmy lub nowe odcinki programów telewizyjnych.
Carousel
oczekuje, że określisz co najmniej liczbę elementów w karuzeli oraz sposób ich wyświetlania. Pierwszy z nich można określić za pomocą parametru itemCount
. Drugi może być przekazywany jako funkcja lambda. Lambda otrzymuje numer indeksu wyświetlanego elementu. Wyświetlany element możesz określić za pomocą podanej wartości indeksu:
@Composable
function FeaturedCarousel(
featuredContentList: List<Movie>,
modifier: Modifier = Modifier,
) {
Carousel(
itemCount = featuredContentList.size,
modifier = modifier,
) { index ->
val content = featuredContentList[index]
Box {
AsyncImage(
model = content.backgroundImageUrl,
contentDescription = content.description,
placeholder = painterResource(
id = R.drawable.placeholder
),
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
Text(text = content.title)
}
}
}
Carousel
może być elementem listy leniwej, np. TvLazyColumn
.
Ten fragment kodu pokazuje komponent FeaturedCarousel
na wierzchu wszystkich komponentów Section
:
@Composable
fun CatalogBrowser(
featuredContentList: List<Movie>,
sectionList: List<Section>,
modifier: Modifier = Modifier,
onItemSelected: (Movie) -> Unit = {},
) {
TvLazyColumn(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
item {
FeaturedCarousel(featuredContentList)
}
items(sectionList) { section ->
Section(section, onItemSelected = onItemSelected)
}
}
}