Menyediakan tampilan kartu

Membangun aplikasi dengan lebih baik menggunakan Compose
Membuat UI yang menarik dengan kode minimal menggunakan Jetpack Compose untuk Android TV OS.

Di pelajaran sebelumnya, Anda membuat browser katalog, yang diimplementasikan dalam fragmen jelajah, yang menampilkan daftar item media. Dalam pelajaran ini, Anda akan membuat tampilan kartu untuk item media dan menyajikannya di fragmen jelajah.

BaseCardView dan subclass menampilkan metadata yang terkait dengan item media. Tujuan ImageCardView yang digunakan dalam tutorial ini menampilkan gambar konten bersama dengan judul item media.

Lihat juga contoh implementasi di Aplikasi contoh Leanback kami.

Tampilan kartu aplikasi

Gambar 1. Tampilan kartu gambar aplikasi contoh Leanback saat dipilih.

Membuat presenter kartu

Presenter menghasilkan tampilan dan mengikat objek ke tampilan tersebut sesuai permintaan. Di fragmen jelajah tempat aplikasi Anda menyajikan kontennya kepada pengguna, Anda membuat Presenter untuk kartu konten dan meneruskannya ke adaptor yang menambahkan konten ke layar. Dalam kode berikut, CardPresenter dibuat dalam onLoadFinished() callback dari LoaderManager:

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();
}

Membuat tampilan kartu

Pada langkah ini, Anda akan membuat presenter kartu dengan holder tampilan untuk tampilan kartu yang menjelaskan item konten media Anda. Perhatikan bahwa setiap presenter hanya boleh membuat satu jenis tampilan. Jika Anda memiliki dua tampilan kartu, Anda memerlukan dua presenter kartu.

Di Presenter, implementasikan metode onCreateViewHolder() callback yang membuat holder tampilan yang dapat digunakan untuk menampilkan item konten:

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);
...

Dalam metode onCreateViewHolder(), membuat tampilan kartu untuk item konten. Contoh berikut menggunakan ImageCardView.

Saat kartu dipilih, perilaku default akan memperluasnya menjadi ukuran yang lebih besar. Jika Anda ingin menetapkan warna lain untuk kartu yang dipilih, panggil setSelected() sebagaimana ditunjukkan di sini:

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);
        }
    };
...

Saat pengguna membuka aplikasi Anda, Presenter.ViewHolder menampilkan objek CardView untuk item konten Anda. Anda perlu mengaturnya untuk menerima fokus dari pengontrol D-pad dengan memanggil setFocusable(true) dan setFocusableInTouchMode(true), seperti yang ditunjukkan pada kode berikut:

Kotlin

    ...
    cardView.isFocusable = true
    cardView.isFocusableInTouchMode = true
    return ViewHolder(cardView)
}

Java

...
    cardView.setFocusable(true);
    cardView.setFocusableInTouchMode(true);
    return new ViewHolder(cardView);
}

Saat pengguna memilih ImageCardView, tindakan ini akan memperluas untuk menampilkan area teks dengan warna latar belakang yang Anda tetapkan, seperti yang ditunjukkan pada gambar 1.