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