Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

카드 보기 제공

이전 과정에서는 탐색 프래그먼트에서 구현되고 미디어 항목 목록을 표시하는 카탈로그 브라우저를 만들어 보았습니다. 이번 과정에서는 미디어 항목의 카드 보기를 만들고 탐색 프래그먼트에 표시해 보겠습니다.

BaseCardView 클래스 및 서브클래스는 미디어 항목과 관련된 메타 데이터를 표시합니다. 이 과정에 사용된 ImageCardView 클래스는 미디어 항목의 제목과 함께 콘텐츠 이미지를 표시합니다.

이 과정에서는 Android TV GitHub 저장소에 있는 Android Leanback 샘플 앱의 코드를 설명합니다. 이 샘플 코드를 사용하여 나만의 앱을 시작하세요.

앱 카드 보기

그림 1. 선택할 때 표시되는 Leanback 샘플 앱 이미지 카드 보기

카드 프레젠터 만들기

Presenter는 뷰를 생성하고 요청 시 객체를 이 뷰에 결합합니다. 앱에서 사용자에게 콘텐츠를 제공하는 탐색 프래그먼트에서 콘텐츠 카드용 Presenter를 만들어 화면에 콘텐츠를 추가하는 어댑터에 전달합니다. 다음 코드에서는 LoaderManageronLoadFinished() 콜백에 CardPresenter가 생성됩니다.

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

자바

    @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() 콜백을 구현합니다.

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

자바

    @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()를 호출합니다.

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

자바

    ...
        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 객체가 표시됩니다. setFocusable(true)setFocusableInTouchMode(true)를 호출하여 D패드 컨트롤러에서 포커스를 받도록 이렇게 설정해야 합니다.

Kotlin

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

자바

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

사용자가 ImageCardView를 선택하면 이 클래스는 확장되어 그림 1과 같이 지정된 배경 색상으로 텍스트 영역을 표시합니다.