1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package com.example.android.leanback; 15 16 import android.content.Intent; 17 import android.os.Bundle; 18 import android.util.Log; 19 20 import androidx.core.app.ActivityOptionsCompat; 21 import androidx.leanback.paging.PagingDataAdapter; 22 import androidx.leanback.widget.ArrayObjectAdapter; 23 import androidx.leanback.widget.ClassPresenterSelector; 24 import androidx.leanback.widget.HeaderItem; 25 import androidx.leanback.widget.ImageCardView; 26 import androidx.leanback.widget.ListRow; 27 import androidx.leanback.widget.ListRowPresenter; 28 import androidx.leanback.widget.OnItemViewClickedListener; 29 import androidx.leanback.widget.OnItemViewSelectedListener; 30 import androidx.leanback.widget.Presenter; 31 import androidx.leanback.widget.Row; 32 import androidx.leanback.widget.RowPresenter; 33 import androidx.leanback.widget.TitleHelper; 34 import androidx.recyclerview.widget.DiffUtil; 35 36 import org.jspecify.annotations.NonNull; 37 38 public class RowsFragment extends androidx.leanback.app.RowsFragment { 39 40 private static final String TAG = "leanback.RowsFragment"; 41 42 private static final int NUM_ROWS = 10; 43 // Row heights default to wrap content 44 private static final boolean USE_FIXED_ROW_HEIGHT = false; 45 46 private TitleHelper mTitleHelper; 47 setTitleHelper(TitleHelper titleHelper)48 public void setTitleHelper(TitleHelper titleHelper) { 49 mTitleHelper = titleHelper; 50 } 51 52 @Override onCreate(Bundle savedInstanceState)53 public void onCreate(Bundle savedInstanceState) { 54 Log.i(TAG, "onCreate"); 55 super.onCreate(savedInstanceState); 56 57 setupRows(); 58 setOnItemViewClickedListener(new ItemViewClickedListener()); 59 setOnItemViewSelectedListener(new OnItemViewSelectedListener() { 60 @Override 61 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 62 RowPresenter.ViewHolder rowViewHolder, Row row) { 63 Log.i(TAG, "onItemSelected: " + item + " row " + row); 64 if (mTitleHelper != null) { 65 mTitleHelper.showTitle(getAdapter() == null || getAdapter().size() == 0 || 66 getAdapter().get(0) == row); 67 } 68 } 69 }); 70 } 71 setupRows()72 private void setupRows() { 73 ClassPresenterSelector cs = new ClassPresenterSelector(); 74 ListRowPresenter lrp = new ListRowPresenter(); 75 PagedRowPresenter prp = new PagedRowPresenter(); 76 77 // For good performance, it's important to use a single instance of 78 // a card presenter for all rows using that presenter. 79 final CardPresenter cardPresenter = new CardPresenter(); 80 81 if (USE_FIXED_ROW_HEIGHT) { 82 lrp.setRowHeight(cardPresenter.getRowHeight(getActivity())); 83 lrp.setExpandedRowHeight(cardPresenter.getExpandedRowHeight(getActivity())); 84 prp.setRowHeight(cardPresenter.getRowHeight(getActivity())); 85 prp.setExpandedRowHeight(cardPresenter.getExpandedRowHeight(getActivity())); 86 } 87 88 ArrayObjectAdapter rowsAdapter = new ArrayObjectAdapter(cs); 89 90 for (int i = 0; i < NUM_ROWS; ++i) { 91 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); 92 listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1)); 93 listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2)); 94 listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3)); 95 listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4)); 96 listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_5)); 97 listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_6)); 98 listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_7)); 99 listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_8)); 100 HeaderItem header = new HeaderItem(i, "Row " + i); 101 rowsAdapter.add(new ListRow(header, listRowAdapter)); 102 } 103 104 rowsAdapter.add(getLiveDataRow(NUM_ROWS, cardPresenter)); 105 cs.addClassPresenter(ListRow.class, lrp); 106 cs.addClassPresenter(LiveDataListRow.class, prp); 107 setAdapter(rowsAdapter); 108 } 109 110 private final class ItemViewClickedListener implements OnItemViewClickedListener { 111 @Override onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row)112 public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, 113 RowPresenter.ViewHolder rowViewHolder, Row row) { 114 Intent intent = new Intent(getActivity(), DetailsSupportActivity.class); 115 intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item); 116 117 Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( 118 getActivity(), 119 ((ImageCardView) itemViewHolder.view).getMainImageView(), 120 DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle(); 121 getActivity().startActivity(intent, bundle); 122 } 123 } 124 getLiveDataRow(int index, CardPresenter cardPresenter)125 private ListRow getLiveDataRow(int index, CardPresenter cardPresenter) { 126 PagingDataAdapter<PhotoItem> pagedListAdapter = 127 new PagingDataAdapter<PhotoItem>(cardPresenter, 128 new DiffUtil.ItemCallback<PhotoItem>() { 129 @Override 130 public boolean areItemsTheSame(@NonNull PhotoItem oldItem, 131 @NonNull PhotoItem newItem) { 132 return oldItem.getId() == newItem.getId(); 133 } 134 @Override 135 public boolean areContentsTheSame(@NonNull PhotoItem oldItem, 136 @NonNull PhotoItem newItem) { 137 return oldItem.equals(newItem); 138 } 139 }); 140 141 HeaderItem header = new HeaderItem(index, "Row with paging data adapter"); 142 return new LiveDataListRow(header, pagedListAdapter); 143 } 144 } 145