יצירת דפדפן של קטלוג

אפליקציית מדיה שפועלת בטלוויזיה צריכה לאפשר למשתמשים לעיין באפשרויות התוכן שלה, לבחור אפשרות ולהתחיל להפעיל תוכן. חוויית הגלישה בתוכן באפליקציות מהסוג הזה צריכה להיות פשוטה, אינטואיטיבית, נעימה מבחינה ויזואלית ומעניינת.

דפדפן של קטלוג מדיה בדרך כלל מורכב מכמה קטעים, וכל קטע מכיל רשימה של תוכן מדיה. דוגמאות לקטעים בקטלוג מדיה: פלייליסטים, תוכן נבחר, קטגוריות מומלצות.

איור 1. מסך קטלוג אופייני. המשתמשים יכולים לעיין בנתונים של קטלוג הסרטונים.

אתם יכולים להשתמש בפונקציות של Compose for TV כדי להטמיע ממשק משתמש לגלישה במוזיקה או בסרטונים מתוך קטלוג המדיה של האפליקציה.

יצירת פונקציה הניתנת להגדרה לקטלוג

כל מה שמופיע במסך מיושם כפונקציה שניתנת ליצירה ב-Compose for TV. מתחילים בהגדרת פונקציה שניתנת ליצירה בדפדפן של קטלוג המדיה:

@Composable
fun CatalogBrowser(
   featuredContentList: List<Movie>,
   sectionList: List<Section>,
   modifier: Modifier = Modifier,
   onItemSelected: (Movie) -> Unit = {},
) {
// ToDo: add implementation
}

CatalogBrowser היא הפונקציה הניתנת להגדרה שמטמיעה את הדפדפן של קטלוג המדיה. הפונקציה מקבלת את הארגומנטים הבאים:

  • רשימת התוכן המומלץ.
  • רשימת קטעים.
  • אובייקט Modifier.
  • פונקציית קריאה חוזרת שמפעילה מעבר מסך.

הגדרת רכיבים בממשק המשתמש

Compose for TV מציע רשימות 'לאט', רכיב להצגת מספר גדול של פריטים (או רשימה באורך לא ידוע). כדי למקם את הקטעים אנכית, צריך להפעיל את הפונקציה LazyColumn. LazyColumn מספק בלוק LazyListScope.() -> Unit שמציע שפת DSL להגדרת תוכן הפריטים. בדוגמה הבאה, כל קטע ממוקם ברשימה אנכית עם רווח של 16dp בין קטעים:

@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)
    }
  }
}

בדוגמה, הפונקציה הניתנת לקיפול Section מגדירה איך להציג את הקטעים. בפונקציה הבאה, LazyRow ממחישה איך משתמשים בגרסת LazyColumn האופקית באופן דומה כדי להגדיר רשימה אופקית עם בלוק LazyListScope.() -> Unit, על ידי קריאה ל-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) }
       )
    }
  }
}

ב-composable של Section נעשה שימוש ברכיב Text. טקסט ורכיבים אחרים שמוגדרים ב-Material Design זמינים בספרייה tv-material . אפשר לשנות את הסגנון של הטקסטים כפי שהוגדר בעיצוב החדשני התלת-ממדי, על ידי הפניה לאובייקט MaterialTheme. האובייקט הזה מסופק גם על ידי ספריית tv-material. Card הוא חלק מספריית tv-material. MovieCard מגדיר את אופן העיבוד של כל נתוני הסרט בקטלוג, כפי שמוגדר בקטע הקוד הבא:

@Composable
fun MovieCard(
   movie: Movie,
   modifier: Modifier = Modifier,
   onClick: () -> Unit = {}
) {
   Card(modifier = modifier, onClick = onClick){
    AsyncImage(
       model = movie.thumbnailUrl,
       contentDescription = movie.title,
     )
   }
}

בדוגמה שצוינה למעלה, כל הסרטים מוצגים באופן שווה. הם מכסים את אותו אזור, ואין הבדל חזותי ביניהם. אפשר לסמן חלק מהן באמצעות Carousel.

בקרוסלה, המידע מוצג בקבוצת פריטים שיכולים להחליק, לדעוך או לנוע אל תוך התצוגה. אפשר להשתמש ברכיב כדי להבליט תוכן נבחר, כמו סרטים חדשים שזמינים או פרקים חדשים של תוכניות טלוויזיה.

ב-Carousel צריך לציין לפחות את מספר הפריטים בקרוסלה ואת אופן הצגת כל פריט. אפשר לציין את האפשרות הראשונה באמצעות itemCount. אפשר להעביר את השני כ-lambda. מספר האינדקס של הפריט המוצג מוענק לפונקציית הלמהדה. אפשר לקבוע את הפריט המוצג לפי ערך האינדקס הנתון:

@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 יכול להיות פריט ברשימת עצלנים, כמו TvLazyColumn. קטע הקוד הבא מציג את ה-composable של FeaturedCarousel מעל כל ה-composables של 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)
    }
  }
}