Kart görünümü ekleyin
Koleksiyonlar ile düzeninizi koruyun
İçeriği tercihlerinize göre kaydedin ve kategorilere ayırın.
Compose ile daha iyi hizmet verin
Android TV OS için Jetpack Compose'u kullanarak minimum kodla etkileyici kullanıcı arayüzleri oluşturun.
Önceki derste bir göz atma parçasına uygulanmış,
medya öğelerinin listesini görüntüler. Bu derste, medya öğeleriniz için kart görünümleri oluşturup
bunları göz atma parçasında sunmalısınız.
BaseCardView
sınıfı ve alt sınıflar, bir medya öğesiyle ilişkili meta verileri görüntüler. İlgili içeriği oluşturmak için kullanılan
ImageCardView
.
sınıfı, medya öğesinin başlığıyla birlikte içeriğe ilişkin bir resmi görüntüler.
Ayrıca,
Leanback örnek uygulaması
,
Şekil 1. Seçildiğinde, Leanback örnek uygulaması resim kartı görünümü.
Kart sunucusu oluşturma
Presenter
, görünümler oluşturur ve nesneleri bunlara bağlar
isteğe bağlı. Uygulamanızın içeriğini kullanıcıya sunduğu göz atma parçasında,
İçerik kartları için Presenter
ve bunu adaptöre iletin.
içerik ekrana ekler. Aşağıdaki kodda CardPresenter
öğesi oluşturulmuştur
onLoadFinished()
içinde
LoaderManager
geri çağırması:
Kotlin
override fun onLoadFinished(loader: Loader<HashMap<String, List<Movie>>>, data: HashMap<String, List<Movie>>) {
rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
val cardPresenter = CardPresenter()
var i = 0L
data.entries.forEach { entry ->
val listRowAdapter = ArrayObjectAdapter(cardPresenter).apply {
entry.value.forEach { movie ->
add(movie)
}
}
val header = HeaderItem(i, entry.key)
i++
rowsAdapter.add(ListRow(header, listRowAdapter))
}
val gridHeader = HeaderItem(i, getString(R.string.more_samples))
val gridRowAdapter = ArrayObjectAdapter(GridItemPresenter()).apply {
add(getString(R.string.grid_view))
add(getString(R.string.error_fragment))
add(getString(R.string.personal_settings))
}
rowsAdapter.add(ListRow(gridHeader, gridRowAdapter))
adapter = rowsAdapter
updateRecommendations()
}
Java
@Override
public void onLoadFinished(Loader<HashMap<String, List<Movie>>> arg0,
HashMap<String, List<Movie>> data) {
rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
CardPresenter cardPresenter = new CardPresenter();
int i = 0;
for (Map.Entry<String, List<Movie>> entry : data.entrySet()) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
List<Movie> list = entry.getValue();
for (int j = 0; j < list.size(); j++) {
listRowAdapter.add(list.get(j));
}
HeaderItem header = new HeaderItem(i, entry.getKey());
i++;
rowsAdapter.add(new ListRow(header, listRowAdapter));
}
HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples));
GridItemPresenter gridPresenter = new GridItemPresenter();
ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
gridRowAdapter.add(getString(R.string.grid_view));
gridRowAdapter.add(getString(R.string.error_fragment));
gridRowAdapter.add(getString(R.string.personal_settings));
rowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
setAdapter(rowsAdapter);
updateRecommendations();
}
Kart görünümü oluştur
Bu adımda, kart görünümünü açıklayan bir görünüm tutucuyla kart sunucusunu
medya içeriği öğelerinizi kontrol edin. Her sunucunun yalnızca bir görünüm türü oluşturması gerektiğini unutmayın. İki
kart görünümü türündeyse iki kart sunucusu gerekir.
Presenter
içinde,
onCreateViewHolder()
geri çağırma işlevini içerir:
Kotlin
private const val CARD_WIDTH = 313
private const val CARD_HEIGHT = 176
class CardPresenter : Presenter() {
private lateinit var mContext: Context
private lateinit var defaultCardImage: Drawable
override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
mContext = parent.context
defaultCardImage = mContext.resources.getDrawable(R.drawable.movie)
...
Java
@Override
public class CardPresenter extends Presenter {
private Context context;
private static int CARD_WIDTH = 313;
private static int CARD_HEIGHT = 176;
private Drawable defaultCardImage;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
context = parent.getContext();
defaultCardImage = context.getResources().getDrawable(R.drawable.movie);
...
onCreateViewHolder()
yönteminde,
içerik öğeleri için kart görünümü oluşturabilirsiniz. Aşağıdaki örnekte
ImageCardView
Bir kart seçildiğinde, varsayılan davranış kartı daha büyük bir boyuta genişletir. Bir bütçe
belirlemek istiyorsanız
seçilen kart için farklı bir renk varsa setSelected()
işlevini çağırın
burada gösterildiği gibi:
Kotlin
...
val cardView = object : ImageCardView(context) {
override fun setSelected(selected: Boolean) {
val selected_background = context.resources.getColor(R.color.detail_background)
val default_background = context.resources.getColor(R.color.default_background)
val color = if (selected) selected_background else default_background
findViewById<View>(R.id.info_field).setBackgroundColor(color)
super.setSelected(selected)
}
}
...
Java
...
ImageCardView cardView = new ImageCardView(context) {
@Override
public void setSelected(boolean selected) {
int selected_background = context.getResources().getColor(R.color.detail_background);
int default_background = context.getResources().getColor(R.color.default_background);
int color = selected ? selected_background : default_background;
findViewById(R.id.info_field).setBackgroundColor(color);
super.setSelected(selected);
}
};
...
Kullanıcı uygulamanızı açtığında Presenter.ViewHolder
içerik öğelerinize ilişkin CardView
nesneleri gösterir. Şunları almak için bunları ayarlamanız gerekir:
setFocusable(true)
çağırarak d-pad kumandasından odaklan
ve setFocusableInTouchMode(true)
,
aşağıdaki kodda gösterildiği gibidir:
Kotlin
...
cardView.isFocusable = true
cardView.isFocusableInTouchMode = true
return ViewHolder(cardView)
}
Java
...
cardView.setFocusable(true);
cardView.setFocusableInTouchMode(true);
return new ViewHolder(cardView);
}
Kullanıcı ImageCardView
öğesini seçtiğinde genişler
ifadesini kullanın.
Bu sayfadaki içerik ve kod örnekleri, İçerik Lisansı sayfasında açıklanan lisanslara tabidir. Java ve OpenJDK, Oracle ve/veya satış ortaklarının tescilli ticari markasıdır.
Son güncelleme tarihi: 2025-07-27 UTC.
[[["Anlaması kolay","easyToUnderstand","thumb-up"],["Sorunumu çözdü","solvedMyProblem","thumb-up"],["Diğer","otherUp","thumb-up"]],[["İhtiyacım olan bilgiler yok","missingTheInformationINeed","thumb-down"],["Çok karmaşık / çok fazla adım var","tooComplicatedTooManySteps","thumb-down"],["Güncel değil","outOfDate","thumb-down"],["Çeviri sorunu","translationIssue","thumb-down"],["Örnek veya kod sorunu","samplesCodeIssue","thumb-down"],["Diğer","otherDown","thumb-down"]],["Son güncelleme tarihi: 2025-07-27 UTC."],[],[],null,["# Provide a card view\n\nBuild better with Compose \nCreate beautiful UIs with minimal code using Jetpack Compose for Android TV OS. \n[Compose for TV →](/training/tv/playback/compose) \n\nIn the previous lesson, you created a catalog browser, implemented in a browse fragment, that\ndisplays a list of media items. In this lesson, you create the card views for your media items and\npresent them in the browse fragment.\n\nThe [BaseCardView](/reference/androidx/leanback/widget/BaseCardView)\nclass and subclasses display the metadata associated with a media item. The\n[ImageCardView](/reference/androidx/leanback/widget/ImageCardView)\nclass used in this lesson displays an image for the content along with the media item's title.\n\nSee also the sample implementation in the\n[Leanback sample app](https://github.com/android/tv-samples/tree/main/Leanback)\n.\n\n**Figure 1.** The Leanback sample app image card view when selected.\n\nCreate a card presenter\n-----------------------\n\nA [Presenter](/reference/androidx/leanback/widget/Presenter) generates views and binds objects to them\non demand. In the browse fragment where your app presents its content to the user, you create a\n`Presenter` for the content cards and pass it to the adapter\nthat adds the content to the screen. In the following code, the `CardPresenter` is created\nin the [onLoadFinished()](/reference/androidx/loader/app/LoaderManager.LoaderCallbacks#onLoadFinished(androidx.loader.content.Loader%3CD%3E,D))\ncallback of the [LoaderManager](/reference/androidx/loader/app/LoaderManager): \n\n### Kotlin\n\n```kotlin\noverride fun onLoadFinished(loader: Loader\u003cHashMap\u003cString, List\u003cMovie\u003e\u003e\u003e, data: HashMap\u003cString, List\u003cMovie\u003e\u003e) {\n rowsAdapter = ArrayObjectAdapter(ListRowPresenter())\n val cardPresenter = CardPresenter()\n\n var i = 0L\n\n data.entries.forEach { entry -\u003e\n val listRowAdapter = ArrayObjectAdapter(cardPresenter).apply {\n entry.value.forEach { movie -\u003e\n add(movie)\n }\n }\n\n val header = HeaderItem(i, entry.key)\n i++\n rowsAdapter.add(ListRow(header, listRowAdapter))\n }\n\n val gridHeader = HeaderItem(i, getString(R.string.more_samples))\n\n val gridRowAdapter = ArrayObjectAdapter(GridItemPresenter()).apply {\n add(getString(R.string.grid_view))\n add(getString(R.string.error_fragment))\n add(getString(R.string.personal_settings))\n }\n rowsAdapter.add(ListRow(gridHeader, gridRowAdapter))\n\n adapter = rowsAdapter\n\n updateRecommendations()\n}\n```\n\n### Java\n\n```java\n@Override\npublic void onLoadFinished(Loader\u003cHashMap\u003cString, List\u003cMovie\u003e\u003e\u003e arg0,\n HashMap\u003cString, List\u003cMovie\u003e\u003e data) {\n\n rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());\n CardPresenter cardPresenter = new CardPresenter();\n\n int i = 0;\n\n for (Map.Entry\u003cString, List\u003cMovie\u003e\u003e entry : data.entrySet()) {\n ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);\n List\u003cMovie\u003e list = entry.getValue();\n\n for (int j = 0; j \u003c list.size(); j++) {\n listRowAdapter.add(list.get(j));\n }\n HeaderItem header = new HeaderItem(i, entry.getKey());\n i++;\n rowsAdapter.add(new ListRow(header, listRowAdapter));\n }\n\n HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples));\n\n GridItemPresenter gridPresenter = new GridItemPresenter();\n ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);\n gridRowAdapter.add(getString(R.string.grid_view));\n gridRowAdapter.add(getString(R.string.error_fragment));\n gridRowAdapter.add(getString(R.string.personal_settings));\n rowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));\n\n setAdapter(rowsAdapter);\n\n updateRecommendations();\n}\n```\n\nCreate a card view\n------------------\n\nIn this step, you build the card presenter with a view holder for the card view that describes\nyour media content items. Note that each presenter must create only one view type. If you have two\ncard view types, then you need two card presenters.\n\nIn the [Presenter](/reference/androidx/leanback/widget/Presenter), implement an\n[onCreateViewHolder()](/reference/androidx/leanback/widget/Presenter#onCreateViewHolder(android.view.ViewGroup))\ncallback that creates a view holder that can be used to display a content item: \n\n### Kotlin\n\n```kotlin\nprivate const val CARD_WIDTH = 313\nprivate const val CARD_HEIGHT = 176\n\nclass CardPresenter : Presenter() {\n\n private lateinit var mContext: Context\n private lateinit var defaultCardImage: Drawable\n\n override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {\n mContext = parent.context\n defaultCardImage = mContext.resources.getDrawable(R.drawable.movie)\n ...\n```\n\n### Java\n\n```java\n@Override\npublic class CardPresenter extends Presenter {\n\n private Context context;\n private static int CARD_WIDTH = 313;\n private static int CARD_HEIGHT = 176;\n private Drawable defaultCardImage;\n\n @Override\n public ViewHolder onCreateViewHolder(ViewGroup parent) {\n context = parent.getContext();\n defaultCardImage = context.getResources().getDrawable(R.drawable.movie);\n...\n```\n\nIn the [onCreateViewHolder()](/reference/androidx/leanback/widget/Presenter#onCreateViewHolder(android.view.ViewGroup)) method,\ncreate a card view for content items. The following sample uses an\n[ImageCardView](/reference/androidx/leanback/widget/ImageCardView).\n\nWhen a card is selected, the default behavior expands it to a larger size. If you want to designate\na different color for the selected card, call [setSelected()](/reference/androidx/leanback/widget/BaseCardView#setSelected(boolean))\nas shown here: \n\n### Kotlin\n\n```kotlin\n ...\n val cardView = object : ImageCardView(context) {\n override fun setSelected(selected: Boolean) {\n val selected_background = context.resources.getColor(R.color.detail_background)\n val default_background = context.resources.getColor(R.color.default_background)\n val color = if (selected) selected_background else default_background\n findViewById\u003cView\u003e(R.id.info_field).setBackgroundColor(color)\n super.setSelected(selected)\n }\n }\n ...\n```\n\n### Java\n\n```java\n...\n ImageCardView cardView = new ImageCardView(context) {\n @Override\n public void setSelected(boolean selected) {\n int selected_background = context.getResources().getColor(R.color.detail_background);\n int default_background = context.getResources().getColor(R.color.default_background);\n int color = selected ? selected_background : default_background;\n findViewById(R.id.info_field).setBackgroundColor(color);\n super.setSelected(selected);\n }\n };\n...\n```\n\nWhen the user opens your app, the [Presenter.ViewHolder](/reference/androidx/leanback/widget/Presenter.ViewHolder)\ndisplays the `CardView` objects for your content items. You need to set these to receive\nfocus from the D-pad controller by calling [setFocusable(true)](/reference/android/view/View#setFocusable(boolean))\nand [setFocusableInTouchMode(true)](/reference/android/view/View#setFocusableInTouchMode(boolean)),\nas shown in the following code: \n\n### Kotlin\n\n```kotlin\n ...\n cardView.isFocusable = true\n cardView.isFocusableInTouchMode = true\n return ViewHolder(cardView)\n}\n```\n\n### Java\n\n```java\n...\n cardView.setFocusable(true);\n cardView.setFocusableInTouchMode(true);\n return new ViewHolder(cardView);\n}\n```\n\nWhen the user selects the [ImageCardView](/reference/androidx/leanback/widget/ImageCardView), it expands\nto reveal its text area with the background color you specify, as shown in figure 1."]]