1 // CHECKSTYLE:OFF Generated code 2 /* This file is auto-generated from NewDetailsFragment.java. DO NOT MODIFY. */ 3 4 /* 5 * Copyright (C) 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 8 * in compliance with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed under the License 13 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 * or implied. See the License for the specific language governing permissions and limitations under 15 * the License. 16 */ 17 package com.example.android.leanback; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.graphics.Bitmap; 22 import android.graphics.drawable.Drawable; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.os.Handler; 26 import android.util.Log; 27 import android.view.LayoutInflater; 28 import android.view.View; 29 import android.view.ViewGroup; 30 31 import androidx.core.app.ActivityOptionsCompat; 32 import androidx.core.content.res.ResourcesCompat; 33 import androidx.leanback.app.DetailsSupportFragmentBackgroundController; 34 import androidx.leanback.media.MediaPlayerAdapter; 35 import androidx.leanback.media.MediaPlayerGlue; 36 import androidx.leanback.media.PlaybackGlue; 37 import androidx.leanback.media.PlaybackTransportControlGlue; 38 import androidx.leanback.widget.Action; 39 import androidx.leanback.widget.ArrayObjectAdapter; 40 import androidx.leanback.widget.ClassPresenterSelector; 41 import androidx.leanback.widget.DetailsOverviewRow; 42 import androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter; 43 import androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper; 44 import androidx.leanback.widget.HeaderItem; 45 import androidx.leanback.widget.ImageCardView; 46 import androidx.leanback.widget.ListRow; 47 import androidx.leanback.widget.ListRowPresenter; 48 import androidx.leanback.widget.OnActionClickedListener; 49 import androidx.leanback.widget.OnItemViewClickedListener; 50 import androidx.leanback.widget.OnItemViewSelectedListener; 51 import androidx.leanback.widget.Presenter; 52 import androidx.leanback.widget.Row; 53 import androidx.leanback.widget.RowPresenter; 54 import androidx.leanback.widget.SparseArrayObjectAdapter; 55 56 import org.jspecify.annotations.NonNull; 57 58 public class NewDetailsSupportFragment extends androidx.leanback.app.DetailsSupportFragment { 59 60 private static final String TAG = "leanback.DetailsSupportFragment"; 61 62 private static final int NUM_ROWS = 3; 63 private ArrayObjectAdapter mRowsAdapter; 64 private PhotoItem mPhotoItem; 65 final CardPresenter cardPresenter = new CardPresenter(); 66 67 private static final int ACTION_PLAY = 1; 68 private static final int ACTION_RENT = 2; 69 private static final int ACTION_BUY = 3; 70 71 private boolean TEST_SHARED_ELEMENT_TRANSITION = true; 72 private boolean TEST_BACKGROUND_PLAYER; 73 74 private static final long TIME_TO_LOAD_OVERVIEW_ROW_MS = 1000; 75 private static final long TIME_TO_LOAD_RELATED_ROWS_MS = 2000; 76 77 private Action mActionPlay; 78 private Action mActionRent; 79 private Action mActionBuy; 80 81 private FullWidthDetailsOverviewSharedElementHelper mHelper; 82 private BackgroundHelper mBackgroundHelper; // used to download bitmap async. 83 private final DetailsSupportFragmentBackgroundController mDetailsBackground = 84 new DetailsSupportFragmentBackgroundController(this); 85 setupTrailerVideo()86 void setupTrailerVideo() { 87 MediaPlayerGlue mediaPlayerGlue = new MediaPlayerGlue(getActivity()); 88 mDetailsBackground.setupVideoPlayback(mediaPlayerGlue); 89 mediaPlayerGlue.setMode(MediaPlayerGlue.REPEAT_ONE); 90 mediaPlayerGlue.setArtist("A Googler"); 91 mediaPlayerGlue.setTitle("Diving with Sharks Trailer"); 92 mediaPlayerGlue.setMediaSource(Uri.parse("android.resource://com.example.android.leanback/" 93 + "raw/browse")); 94 } 95 setupMainVideo()96 void setupMainVideo() { 97 Context context = getActivity(); 98 MediaPlayerAdapter adapter = new MediaPlayerAdapter(context); 99 PlaybackTransportControlGlue<MediaPlayerAdapter> mediaPlayerGlue = 100 new PlaybackTransportControlGlue(context, adapter); 101 mDetailsBackground.setupVideoPlayback(mediaPlayerGlue); 102 mediaPlayerGlue.setSubtitle("A Googler"); 103 mediaPlayerGlue.setTitle("Diving with Sharks"); 104 mediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse( 105 "https://storage.googleapis.com/android-tv/Sample videos/April Fool's " 106 + "2013/Explore Treasure Mode with Google Maps.mp4")); 107 mediaPlayerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 108 @Override 109 public void onPreparedStateChanged(@NonNull PlaybackGlue glue) { 110 super.onPreparedStateChanged(glue); 111 PlaybackTransportControlGlue controlGlue = (PlaybackTransportControlGlue) glue; 112 controlGlue.setSeekProvider(new PlaybackSeekDiskDataProvider( 113 controlGlue.getDuration(), 1000, 114 "/sdcard/seek/frame_%04d.jpg")); 115 } 116 }); 117 } 118 119 @Override onCreate(Bundle savedInstanceState)120 public void onCreate(Bundle savedInstanceState) { 121 Log.i(TAG, "onCreate"); 122 super.onCreate(savedInstanceState); 123 124 mBackgroundHelper = new BackgroundHelper(getActivity()); 125 mDetailsBackground.enableParallax(); 126 if (TEST_BACKGROUND_PLAYER) { 127 if (MovieData.sStatus == MovieData.STATUS_INIT) { 128 // not own/rented, play trailer 129 setupTrailerVideo(); 130 } else { 131 // bought or rented, play the main content 132 setupMainVideo(); 133 // hide details main ui 134 mDetailsBackground.switchToVideo(); 135 } 136 } 137 138 final Context context = getActivity(); 139 setBadgeDrawable(ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_title, 140 context.getTheme())); 141 setTitle("Leanback Sample App"); 142 if (!TEST_BACKGROUND_PLAYER) { 143 setOnSearchClickedListener(new View.OnClickListener() { 144 @Override 145 public void onClick(View view) { 146 Intent intent = new Intent(getActivity(), SearchSupportActivity.class); 147 startActivity(intent); 148 } 149 }); 150 } 151 152 mActionPlay = new Action(ACTION_PLAY, "Play"); 153 mActionRent = new Action(ACTION_RENT, "Rent", "$3.99", ResourcesCompat.getDrawable( 154 context.getResources(), R.drawable.ic_action_a, context.getTheme())); 155 mActionBuy = new Action(ACTION_BUY, "Buy $9.99"); 156 157 ClassPresenterSelector ps = new ClassPresenterSelector(); 158 FullWidthDetailsOverviewRowPresenter dorPresenter = 159 new FullWidthDetailsOverviewRowPresenter(new DetailsDescriptionPresenter()); 160 dorPresenter.setOnActionClickedListener(new OnActionClickedListener() { 161 @Override 162 public void onActionClicked(Action action) { 163 final Context context = getActivity(); 164 DetailsOverviewRow dor = (DetailsOverviewRow) mRowsAdapter.get(0); 165 if (action.getId() == ACTION_BUY) { 166 // on the UI thread, we can modify actions adapter directly 167 SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter) 168 dor.getActionsAdapter(); 169 actions.set(ACTION_PLAY, mActionPlay); 170 actions.clear(ACTION_RENT); 171 actions.clear(ACTION_BUY); 172 boolean previousRented = MovieData.sStatus == MovieData.STATUS_RENTED; 173 MovieData.sStatus = MovieData.STATUS_OWN; 174 dor.setItem(getDisplayTitle(mPhotoItem.getTitle())); 175 dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(), 176 R.drawable.details_img_16x9, context.getTheme())); 177 if (TEST_BACKGROUND_PLAYER) { 178 if (!previousRented) { 179 setupMainVideo(); 180 mDetailsBackground.switchToVideo(); 181 } 182 } else { 183 Intent intent = new Intent(context, PlaybackActivity.class); 184 getActivity().startActivity(intent); 185 } 186 } else if (action.getId() == ACTION_RENT) { 187 // on the UI thread, we can modify actions adapter directly 188 SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter) 189 dor.getActionsAdapter(); 190 actions.set(ACTION_PLAY, mActionPlay); 191 actions.clear(ACTION_RENT); 192 MovieData.sStatus = MovieData.STATUS_RENTED; 193 dor.setItem(getDisplayTitle(mPhotoItem.getTitle())); 194 if (TEST_BACKGROUND_PLAYER) { 195 setupMainVideo(); 196 mDetailsBackground.switchToVideo(); 197 } else { 198 Intent intent = new Intent(context, PlaybackActivity.class); 199 getActivity().startActivity(intent); 200 } 201 } else if (action.getId() == ACTION_PLAY) { 202 if (TEST_BACKGROUND_PLAYER) { 203 mDetailsBackground.switchToVideo(); 204 } else { 205 Intent intent = new Intent(context, PlaybackActivity.class); 206 getActivity().startActivity(intent); 207 } 208 } 209 } 210 }); 211 212 ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter); 213 ps.addClassPresenter(ListRow.class, new ListRowPresenter()); 214 215 mRowsAdapter = new ArrayObjectAdapter(ps); 216 updateAdapter(); 217 218 setOnItemViewClickedListener(new OnItemViewClickedListener() { 219 @Override 220 public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, 221 RowPresenter.ViewHolder rowViewHolder, Row row) { 222 Log.i(TAG, "onItemClicked: " + item + " row " + row); 223 if (item instanceof PhotoItem) { 224 Intent intent = new Intent(getActivity(), DetailsSupportActivity.class); 225 intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item); 226 227 Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( 228 getActivity(), 229 ((ImageCardView) itemViewHolder.view).getMainImageView(), 230 DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle(); 231 getActivity().startActivity(intent, bundle); 232 } 233 } 234 }); 235 setOnItemViewSelectedListener(new OnItemViewSelectedListener() { 236 @Override 237 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 238 RowPresenter.ViewHolder rowViewHolder, Row row) { 239 Log.i(TAG, "onItemSelected: " + item + " row " + row); 240 } 241 }); 242 243 if (TEST_SHARED_ELEMENT_TRANSITION) { 244 mHelper = new FullWidthDetailsOverviewSharedElementHelper(); 245 mHelper.setSharedElementEnterTransition(getActivity(), 246 DetailsSupportActivity.SHARED_ELEMENT_NAME); 247 dorPresenter.setListener(mHelper); 248 dorPresenter.setParticipatingEntranceTransition(false); 249 } else { 250 dorPresenter.setParticipatingEntranceTransition(true); 251 } 252 } 253 254 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)255 public View onCreateView(LayoutInflater inflater, ViewGroup container, 256 Bundle savedInstanceState) { 257 View view = super.onCreateView(inflater, container, savedInstanceState); 258 return view; 259 } 260 setBackgroundVideo(boolean backgroundVideo)261 public void setBackgroundVideo(boolean backgroundVideo) { 262 TEST_BACKGROUND_PLAYER = backgroundVideo; 263 } 264 setItem(PhotoItem photoItem)265 public void setItem(PhotoItem photoItem) { 266 mPhotoItem = photoItem; 267 updateAdapter(); 268 } 269 getDisplayTitle(String title)270 static String getDisplayTitle(String title) { 271 switch (MovieData.sStatus) { 272 case MovieData.STATUS_OWN: 273 title = title + "(Owned)"; 274 break; 275 case MovieData.STATUS_RENTED: 276 title = title + "(Rented)"; 277 break; 278 case MovieData.STATUS_INIT: 279 default: 280 } 281 return title; 282 } 283 updateAdapter()284 void updateAdapter() { 285 if (mRowsAdapter == null) { 286 return; 287 } 288 mRowsAdapter.clear(); 289 new Handler().postDelayed(new Runnable() { 290 @Override 291 public void run() { 292 final Context context = getActivity(); 293 if (context == null) { 294 return; 295 } 296 297 DetailsOverviewRow dor = new DetailsOverviewRow( 298 getDisplayTitle(mPhotoItem.getTitle())); 299 dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(), 300 mPhotoItem.getImageResourceId(), context.getTheme())); 301 SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(); 302 switch (MovieData.sStatus) { 303 case MovieData.STATUS_INIT: 304 adapter.set(ACTION_RENT, mActionRent); 305 adapter.set(ACTION_BUY, mActionBuy); 306 break; 307 case MovieData.STATUS_OWN: 308 adapter.set(ACTION_PLAY, mActionPlay); 309 break; 310 case MovieData.STATUS_RENTED: 311 adapter.set(ACTION_PLAY, mActionPlay); 312 adapter.set(ACTION_BUY, mActionBuy); 313 break; 314 } 315 // one line text with icon 316 Drawable d = ResourcesCompat.getDrawable(context.getResources(), 317 R.drawable.ic_action_a, context.getTheme()); 318 adapter.set(202, new Action(202, "Top", null, d)); 319 dor.setActionsAdapter(adapter); 320 mRowsAdapter.add(0, dor); 321 setSelectedPosition(0, true); 322 if (TEST_SHARED_ELEMENT_TRANSITION) { 323 if (mHelper != null && !mHelper.getAutoStartSharedElementTransition()) { 324 mHelper.startPostponedEnterTransition(); 325 } 326 } 327 } 328 }, TIME_TO_LOAD_OVERVIEW_ROW_MS); 329 330 new Handler().postDelayed(new Runnable() { 331 @Override 332 public void run() { 333 if (getActivity() == null) { 334 return; 335 } 336 for (int i = 0; i < NUM_ROWS; ++i) { 337 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); 338 listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1)); 339 listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2)); 340 listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3)); 341 listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4)); 342 HeaderItem header = new HeaderItem(i, "Row " + i); 343 mRowsAdapter.add(new ListRow(header, listRowAdapter)); 344 } 345 } 346 }, TIME_TO_LOAD_RELATED_ROWS_MS); 347 setAdapter(mRowsAdapter); 348 } 349 350 @Override onStart()351 public void onStart() { 352 super.onStart(); 353 354 // Restore background drawable in onStart(): 355 mBackgroundHelper.loadBitmap(R.drawable.spiderman, 356 new BackgroundHelper.BitmapLoadCallback() { 357 @Override 358 public void onBitmapLoaded(Bitmap bitmap) { 359 mDetailsBackground.setCoverBitmap(bitmap); 360 } 361 }); 362 } 363 364 @Override onStop()365 public void onStop() { 366 mDetailsBackground.setCoverBitmap(null); 367 super.onStop(); 368 } 369 } 370