Предоставить представление карты

Создавайте лучше с помощью Compose
Создавайте красивые пользовательские интерфейсы с минимальным количеством кода, используя Jetpack Compose для ОС Android TV.

На предыдущем уроке вы создали браузер каталога, реализованный во фрагменте просмотра, который отображает список элементов мультимедиа. На этом уроке вы создадите представления карточек для своих медиа-элементов и представите их во фрагменте просмотра.

Класс BaseCardView и его подклассы отображают метаданные, связанные с элементом мультимедиа. Класс ImageCardView , используемый в этом уроке, отображает изображение содержимого вместе с заголовком элемента мультимедиа.

См. также пример реализации в примере приложения Leanback .

Просмотр карточки приложения

Рис. 1. Изображение карточки примера приложения Leanback при выборе.

Создать предъявителя карты

Presenter генерирует представления и привязывает к ним объекты по требованию. Во фрагменте просмотра, где ваше приложение представляет свой контент пользователю, вы создаете Presenter для карточек контента и передаете его адаптеру, который добавляет контент на экран. В следующем коде CardPresenter создается в обратном вызове onLoadFinished() LoaderManager :

Котлин

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

Ява

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

Создать представление карточки

На этом этапе вы создаете презентатор карты с держателем представления для представления карты, описывающего элементы вашего медиаконтента. Обратите внимание, что каждый докладчик должен создать только один тип представления. Если у вас есть два типа просмотра карточек, вам понадобятся два предъявителя карточек.

В Presenter реализуйте обратный вызов onCreateViewHolder() , который создает держатель представления, который можно использовать для отображения элемента контента:

Котлин

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

Ява

@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() создайте представление карточки для элементов контента. В следующем примере используется ImageCardView .

Когда карточка выбрана, поведение по умолчанию расширяет ее до большего размера. Если вы хотите назначить другой цвет для выбранной карты, вызовите setSelected() как показано здесь:

Котлин

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

Ява

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

Когда пользователь открывает ваше приложение, Presenter.ViewHolder отображает объекты CardView для ваших элементов контента. Вам необходимо настроить их для получения фокуса от контроллера D-pad, вызвав setFocusable(true) и setFocusableInTouchMode(true) , как показано в следующем коде:

Котлин

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

Ява

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

Когда пользователь выбирает ImageCardView , он расширяется, открывая текстовую область с указанным вами цветом фона, как показано на рисунке 1.