From 63dcb5b4bde0a6db5797d8f763b9a9e13663b76b Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Fri, 29 May 2015 17:03:44 -0700 Subject: Implemented Card-, DetailView-, GridView-, Music- & Video, Wizard-, Dialog examples The Launcher card needs to be animated. When expanding cards with an animation some animation artifacts might occur since the transition system moves the cards to be centered again. Thus, the two animations are competing with each other. Currently I'm waiting for a change on leanback's transition system or another way to animate cards. Another animation artifact occurs when collapsing the SideInfo-cards, which I hope to be resolved once we clarified how to do proper card animations in the framework. There are some minor issues with in the DetailView since some API methods are missing for customization such as setting the details- and ActionBars background color. Removed obsolete package. Finished music example. Finished video example. Bug 22362006 Added Dialog example. WIP Testing new ImageCardView XML styling. WIP Settings example. WIP Wizard example. Finished Dialog example. Gradle uses environment variable to reference support libraries. Change-Id: I8f911d2e5aeb1fb8764f45d20fda1dc0fc69773a --- samples/SupportLeanbackShowcase/app/.gitignore | 1 + samples/SupportLeanbackShowcase/app/app.iml | 103 ++++ samples/SupportLeanbackShowcase/app/build.gradle | 36 ++ .../SupportLeanbackShowcase/app/proguard-rules.pro | 17 + .../supportleanbackshowcase/ApplicationTest.java | 13 + .../app/src/main/AndroidManifest.xml | 44 ++ .../BrowserExample01Fragment.java | 88 ++++ .../CardExampleFragment.java | 91 ++++ .../supportleanbackshowcase/CardListRow.java | 44 ++ .../supportleanbackshowcase/Constants.java | 17 + .../DetailViewExampleFragment.java | 139 +++++ .../supportleanbackshowcase/DetailedCard.java | 71 +++ .../DetailsDescriptionPresenter.java | 59 +++ .../DialogExampleActivity.java | 36 ++ .../DialogExampleFragment.java | 66 +++ .../supportleanbackshowcase/GridExample.java | 56 +++ .../supportleanbackshowcase/MainActivity.java | 38 ++ .../supportleanbackshowcase/MainFragment.java | 266 ++++++++++ .../supportleanbackshowcase/MediaPlayerGlue.java | 446 ++++++++++++++++ .../leanback/supportleanbackshowcase/Movie.java | 36 ++ .../MusicConsumptionExampleFragment.java | 150 ++++++ .../PicassoBackgroundManagerTarget.java | 61 +++ .../supportleanbackshowcase/ResourceCache.java | 22 + .../SettingsExampleActivity.java | 30 ++ .../SettingsExampleFragment.java | 87 ++++ .../ShadowRowPresenterSelector.java | 43 ++ .../supportleanbackshowcase/SongListRow.java | 20 + .../supportleanbackshowcase/TrackListHeader.java | 49 ++ .../leanback/supportleanbackshowcase/Utils.java | 95 ++++ .../VideoConsumptionExampleFragment.java | 113 +++++ .../VideoMediaPlayerGlue.java | 56 +++ .../VideoSurfaceFragment.java | 38 ++ .../WizardExample1stStepFragment.java | 81 +++ .../WizardExample2ndStepFragment.java | 94 ++++ .../WizardExample3rdStepFragment.java | 92 ++++ .../WizardExample4thStepFragment.java | 57 +++ .../WizardExampleActivity.java | 71 +++ .../WizardExampleBaseStepFragment.java | 49 ++ .../supportleanbackshowcase/cards/models/Card.java | 128 +++++ .../cards/models/CardRow.java | 44 ++ .../supportleanbackshowcase/cards/models/Song.java | 116 +++++ .../cards/models/SongList.java | 31 ++ .../cards/presenters/AbstractCardPresenter.java | 80 +++ .../presenters/AbstractFooterCardPresenter.java | 95 ++++ .../cards/presenters/CardPresenterSelector.java | 108 ++++ .../cards/presenters/CharacterCardPresenter.java | 87 ++++ .../cards/presenters/GameBannerCardPresenter.java | 44 ++ .../cards/presenters/IconCardPresenter.java | 66 +++ .../cards/presenters/ImageCardViewPresenter.java | 141 ++++++ .../cards/presenters/ImageCardViewPresenter1.java | 64 +++ .../cards/presenters/LauncherCardPresenter.java | 97 ++++ .../cards/presenters/MovieRatingCardPresenter.java | 42 ++ .../cards/presenters/SideInfoCardPresenter.java | 81 +++ .../cards/presenters/SingleLineCardPresenter.java | 60 +++ .../cards/presenters/StringPresenter.java | 44 ++ .../cards/presenters/TextCardPresenter.java | 88 ++++ .../cards/views/BaseCardViewEx.java | 54 ++ .../cards/views/FooterLayoutCardView.java | 70 +++ .../cards/views/ImageCardViewReplacement.java | 63 +++ .../cards/views/OnActivateStateChangeHandler.java | 17 + .../drawable-v21/song_row_background_focused.xml | 20 + .../main/res/drawable-xhdpi/background_canyon.jpg | Bin 0 -> 610277 bytes .../src/main/res/drawable-xhdpi/background_sax.jpg | Bin 0 -> 224765 bytes .../res/drawable-xhdpi/card_image_dummy_16_9_l.png | Bin 0 -> 3937 bytes .../res/drawable-xhdpi/card_image_movie_01.png | Bin 0 -> 389440 bytes .../res/drawable-xhdpi/card_image_movie_02.png | Bin 0 -> 286778 bytes .../res/drawable-xhdpi/card_image_movie_03.png | Bin 0 -> 126637 bytes .../res/drawable-xhdpi/card_image_movie_04.png | Bin 0 -> 302881 bytes .../res/drawable-xhdpi/card_image_movie_05.png | Bin 0 -> 303924 bytes .../res/drawable-xhdpi/card_image_movie_06.png | Bin 0 -> 368153 bytes .../res/drawable-xhdpi/card_image_movie_07.png | Bin 0 -> 219069 bytes .../res/drawable-xhdpi/card_image_movie_08.png | Bin 0 -> 269862 bytes .../res/drawable-xhdpi/card_image_movie_09.png | Bin 0 -> 277175 bytes .../res/drawable-xhdpi/card_image_music_01.jpg | Bin 0 -> 173059 bytes .../res/drawable-xhdpi/card_image_music_02.jpg | Bin 0 -> 188294 bytes .../res/drawable-xhdpi/card_image_music_03.jpg | Bin 0 -> 96252 bytes .../res/drawable-xhdpi/card_image_music_04.jpg | Bin 0 -> 84782 bytes .../res/drawable-xhdpi/card_image_music_05.jpg | Bin 0 -> 187373 bytes .../res/drawable-xhdpi/card_image_music_06.jpg | Bin 0 -> 131330 bytes .../res/drawable-xhdpi/card_image_music_07.jpg | Bin 0 -> 120184 bytes .../res/drawable-xhdpi/card_image_music_08.jpg | Bin 0 -> 79576 bytes .../res/drawable-xhdpi/card_image_music_09.jpg | Bin 0 -> 80383 bytes .../res/drawable-xhdpi/card_image_music_10.jpg | Bin 0 -> 129864 bytes .../res/drawable-xhdpi/card_image_music_11.jpg | Bin 0 -> 110962 bytes .../res/drawable-xhdpi/card_image_music_12.jpg | Bin 0 -> 137199 bytes .../res/drawable-xhdpi/card_image_music_13.jpg | Bin 0 -> 84534 bytes .../main/res/drawable-xhdpi/category_action.png | Bin 0 -> 19388 bytes .../main/res/drawable-xhdpi/category_animation.png | Bin 0 -> 20711 bytes .../main/res/drawable-xhdpi/category_classics.png | Bin 0 -> 18841 bytes .../main/res/drawable-xhdpi/category_comedy.png | Bin 0 -> 19503 bytes .../src/main/res/drawable-xhdpi/category_crime.png | Bin 0 -> 19844 bytes .../res/drawable-xhdpi/category_documentary.png | Bin 0 -> 20660 bytes .../src/main/res/drawable-xhdpi/category_drama.png | Bin 0 -> 19306 bytes .../main/res/drawable-xhdpi/coffee_and_tea_01.png | Bin 0 -> 223879 bytes .../main/res/drawable-xhdpi/coffee_and_tea_02.png | Bin 0 -> 330472 bytes .../main/res/drawable-xhdpi/coffee_and_tea_03.png | Bin 0 -> 314348 bytes .../main/res/drawable-xhdpi/coffee_and_tea_04.png | Bin 0 -> 343150 bytes .../main/res/drawable-xhdpi/coffee_and_tea_05.png | Bin 0 -> 288062 bytes .../main/res/drawable-xhdpi/coffee_and_tea_06.png | Bin 0 -> 367936 bytes .../main/res/drawable-xhdpi/coffee_and_tea_07.png | Bin 0 -> 293103 bytes .../main/res/drawable-xhdpi/coffee_and_tea_08.png | Bin 0 -> 339101 bytes .../app/src/main/res/drawable-xhdpi/food_01.png | Bin 0 -> 368998 bytes .../app/src/main/res/drawable-xhdpi/food_02.png | Bin 0 -> 535491 bytes .../app/src/main/res/drawable-xhdpi/food_03.png | Bin 0 -> 526847 bytes .../app/src/main/res/drawable-xhdpi/food_04.png | Bin 0 -> 680355 bytes .../app/src/main/res/drawable-xhdpi/food_05.png | Bin 0 -> 532167 bytes .../app/src/main/res/drawable-xhdpi/food_06.png | Bin 0 -> 521465 bytes .../app/src/main/res/drawable-xhdpi/food_07.png | Bin 0 -> 509352 bytes .../app/src/main/res/drawable-xhdpi/food_08.png | Bin 0 -> 568748 bytes .../app/src/main/res/drawable-xhdpi/food_09.png | Bin 0 -> 344469 bytes .../app/src/main/res/drawable-xhdpi/food_10.png | Bin 0 -> 422496 bytes .../app/src/main/res/drawable-xhdpi/food_11.png | Bin 0 -> 613934 bytes .../app/src/main/res/drawable-xhdpi/food_12.png | Bin 0 -> 390241 bytes .../app/src/main/res/drawable-xhdpi/food_13.png | Bin 0 -> 392126 bytes .../app/src/main/res/drawable-xhdpi/food_14.png | Bin 0 -> 422442 bytes .../main/res/drawable-xhdpi/game_angry_bird_w.png | Bin 0 -> 137211 bytes .../src/main/res/drawable-xhdpi/game_badland_w.png | Bin 0 -> 285313 bytes .../res/drawable-xhdpi/game_leos_fortune_w.png | Bin 0 -> 338385 bytes .../main/res/drawable-xhdpi/game_minion_rush_w.png | Bin 0 -> 230633 bytes .../res/drawable-xhdpi/game_monument_valley_w.png | Bin 0 -> 162442 bytes .../app/src/main/res/drawable-xhdpi/ic_cc.png | Bin 0 -> 1252 bytes .../src/main/res/drawable-xhdpi/ic_installed.png | Bin 0 -> 507 bytes .../main/res/drawable-xhdpi/ic_settings_apps.png | Bin 0 -> 1436 bytes .../main/res/drawable-xhdpi/ic_settings_more.png | Bin 0 -> 629 bytes .../ic_settings_parental_control.png | Bin 0 -> 1453 bytes .../res/drawable-xhdpi/ic_settings_settings.png | Bin 0 -> 1893 bytes .../main/res/drawable-xhdpi/ic_settings_time.png | Bin 0 -> 2317 bytes .../res/drawable-xhdpi/ic_settings_wifi_3_bar.png | Bin 0 -> 1806 bytes .../res/drawable-xhdpi/ic_settings_wifi_4_bar.png | Bin 0 -> 1372 bytes .../src/main/res/drawable-xhdpi/ic_star_off.png | Bin 0 -> 1236 bytes .../main/res/drawable-xhdpi/ic_star_on_yellow.png | Bin 0 -> 1265 bytes .../main/res/drawable-xhdpi/movie_poster_01.png | Bin 0 -> 371243 bytes .../app/src/main/res/drawable-xhdpi/stars_red.png | Bin 0 -> 2053 bytes .../src/main/res/drawable-xhdpi/stars_white.png | Bin 0 -> 2081 bytes .../drawable-xhdpi/thumbnail_example_browse.png | Bin 0 -> 2939 bytes .../res/drawable-xhdpi/thumbnail_example_cards.png | Bin 0 -> 1768 bytes .../drawable-xhdpi/thumbnail_example_custom_01.png | Bin 0 -> 2189 bytes .../drawable-xhdpi/thumbnail_example_detail.png | Bin 0 -> 1603 bytes .../drawable-xhdpi/thumbnail_example_dialog.png | Bin 0 -> 1258 bytes .../res/drawable-xhdpi/thumbnail_example_grid.png | Bin 0 -> 2509 bytes .../thumbnail_example_music_consumption.png | Bin 0 -> 1771 bytes .../drawable-xhdpi/thumbnail_example_settings.png | Bin 0 -> 1367 bytes .../thumbnail_example_video_consumption.png | Bin 0 -> 2326 bytes .../drawable-xhdpi/thumbnail_example_wizard.png | Bin 0 -> 1250 bytes .../main/res/drawable-xhdpi/title_android_tv.png | Bin 0 -> 5641 bytes .../main/res/drawable/app_icon_your_company.png | Bin 0 -> 12416 bytes .../app/src/main/res/drawable/bg_living_room.jpg | Bin 0 -> 136080 bytes .../src/main/res/drawable/bg_living_room_wide.jpg | Bin 0 -> 166393 bytes .../src/main/res/drawable/character_focused.xml | 7 + .../main/res/drawable/character_not_focused.xml | 11 + .../res/drawable/character_not_focused_padding.xml | 11 + .../src/main/res/drawable/default_background.xml | 9 + .../app/src/main/res/drawable/face_01.png | Bin 0 -> 29995 bytes .../app/src/main/res/drawable/face_02.png | Bin 0 -> 32856 bytes .../app/src/main/res/drawable/face_03.png | Bin 0 -> 28412 bytes .../app/src/main/res/drawable/face_04.png | Bin 0 -> 25692 bytes .../app/src/main/res/drawable/face_05.png | Bin 0 -> 15358 bytes .../app/src/main/res/drawable/face_06.png | Bin 0 -> 28374 bytes .../app/src/main/res/drawable/face_07.png | Bin 0 -> 19390 bytes .../app/src/main/res/drawable/face_08.png | Bin 0 -> 26494 bytes .../app/src/main/res/drawable/icon_focused.xml | 9 + .../main/res/drawable/icon_focused_selector.xml | 5 + .../app/src/main/res/drawable/icon_not_focused.xml | 21 + .../app/src/main/res/drawable/overlay_black.xml | 4 + .../src/main/res/drawable/song_row_background.xml | 7 + .../res/drawable/song_row_background_focused.xml | 9 + .../res/drawable/wizard_background_blackned.xml | 5 + .../wizard_important_action_item_background.xml | 5 + ...rd_important_action_item_background_focused.xml | 6 + ...mportant_action_item_background_not_focused.xml | 6 + .../app/src/main/res/layout/activity_main.xml | 10 + .../main/res/layout/activity_settings_example.xml | 11 + .../app/src/main/res/layout/character_card.xml | 36 ++ .../app/src/main/res/layout/detail_view.xml | 82 +++ .../app/src/main/res/layout/icon_card.xml | 22 + .../app/src/main/res/layout/icon_card_footer.xml | 20 + .../app/src/main/res/layout/image_card.xml | 9 + .../app/src/main/res/layout/image_card_footer.xml | 53 ++ .../app/src/main/res/layout/row_song.xml | 62 +++ .../src/main/res/layout/row_track_list_header.xml | 29 ++ .../app/src/main/res/layout/side_info_card.xml | 53 ++ .../main/res/layout/single_line_card_footer.xml | 33 ++ .../app/src/main/res/layout/text_icon_card.xml | 29 ++ .../src/main/res/layout/text_icon_card_footer.xml | 56 +++ .../src/main/res/layout/video_surface_fragment.xml | 6 + .../layout/wizard_progress_action_container.xml | 35 ++ .../res/layout/wizard_progress_action_item.xml | 42 ++ .../app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes .../app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes .../res/mipmap-xhdpi/app_banner_sample_app.png | Bin 0 -> 3492 bytes .../app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../app/src/main/res/raw/browsing_example_01.json | 356 +++++++++++++ .../app/src/main/res/raw/cards_card_example.json | 559 +++++++++++++++++++++ .../app/src/main/res/raw/cards_launcher.json | 70 +++ .../app/src/main/res/raw/detail_example.json | 106 ++++ .../app/src/main/res/raw/grid_example.json | 88 ++++ ...an_view_from_above_i_know_its_super_awesome.mp3 | Bin 0 -> 10415387 bytes .../main/res/raw/music_consumption_example.json | 76 +++ .../app/src/main/res/raw/music_example.json | 106 ++++ .../app/src/main/res/raw/track_01.mp3 | Bin 0 -> 6950210 bytes .../app/src/main/res/raw/track_02.mp3 | Bin 0 -> 8017184 bytes .../app/src/main/res/raw/track_03.mp3 | Bin 0 -> 3320646 bytes .../app/src/main/res/raw/track_04.mp3 | Bin 0 -> 4153235 bytes .../app/src/main/res/raw/track_05.mp3 | Bin 0 -> 4516029 bytes .../app/src/main/res/raw/track_06.mp3 | Bin 0 -> 366592 bytes .../app/src/main/res/raw/track_07.mp3 | Bin 0 -> 6972648 bytes .../app/src/main/res/raw/track_08.mp3 | Bin 0 -> 5779145 bytes .../app/src/main/res/raw/track_09.mp3 | Bin 0 -> 5321271 bytes .../app/src/main/res/raw/wizard_example.json | 6 + .../app/src/main/res/values/arrays.xml | 36 ++ .../app/src/main/res/values/colors.xml | 29 ++ .../app/src/main/res/values/dims.xml | 32 ++ .../app/src/main/res/values/strings.xml | 73 +++ .../app/src/main/res/values/styles.xml | 41 ++ .../app/src/main/res/values/themes.xml | 32 ++ .../app/src/main/res/xml/prefs.xml | 90 ++++ 217 files changed, 6918 insertions(+) create mode 100644 samples/SupportLeanbackShowcase/app/.gitignore create mode 100644 samples/SupportLeanbackShowcase/app/app.iml create mode 100644 samples/SupportLeanbackShowcase/app/build.gradle create mode 100644 samples/SupportLeanbackShowcase/app/proguard-rules.pro create mode 100644 samples/SupportLeanbackShowcase/app/src/androidTest/java/android/support/v17/leanback/supportleanbackshowcase/ApplicationTest.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-v21/song_row_background_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_canyon.jpg create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_sax.jpg create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_dummy_16_9_l.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_01.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_02.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_03.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_04.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_05.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_06.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_07.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_08.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_09.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_01.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_02.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_03.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_04.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_05.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_06.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_07.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_08.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_09.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_10.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_11.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_12.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_13.jpg create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_action.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_animation.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_classics.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_comedy.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_crime.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_documentary.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_drama.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_01.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_02.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_03.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_04.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_05.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_06.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_07.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_08.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_01.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_02.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_03.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_04.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_05.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_06.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_07.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_08.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_09.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_10.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_11.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_12.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_13.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_14.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_angry_bird_w.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_badland_w.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_leos_fortune_w.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_minion_rush_w.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_monument_valley_w.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_cc.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_installed.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_apps.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_more.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_parental_control.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_settings.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_time.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_3_bar.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_4_bar.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_off.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_on_yellow.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/movie_poster_01.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_red.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_white.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_browse.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_cards.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_custom_01.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_detail.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_dialog.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_grid.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_music_consumption.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_settings.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_video_consumption.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_wizard.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/title_android_tv.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/app_icon_your_company.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room.jpg create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room_wide.jpg create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_01.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_02.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_03.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_04.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_05.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_06.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_07.png create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_08.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused_selector.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/row_track_list_header.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_container.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_item.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/app_banner_sample_app.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/grid_example.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/music_consumption_example.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/music_example.json create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_01.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_02.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_03.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_04.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_05.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_06.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_07.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_08.mp3 create mode 100755 samples/SupportLeanbackShowcase/app/src/main/res/raw/track_09.mp3 create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/wizard_example.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/.gitignore b/samples/SupportLeanbackShowcase/app/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/samples/SupportLeanbackShowcase/app/app.iml b/samples/SupportLeanbackShowcase/app/app.iml new file mode 100644 index 000000000..3bc8a329a --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/app.iml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/build.gradle b/samples/SupportLeanbackShowcase/app/build.gradle new file mode 100644 index 000000000..d632d8f12 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/build.gradle @@ -0,0 +1,36 @@ +apply plugin: 'com.android.application' + + +android { + compileSdkVersion 'android-MNC' + buildToolsVersion "22.0.1" + + defaultConfig { + applicationId "android.support.v17.leanback.supportleanbackshowcase" + minSdkVersion 17 + targetSdkVersion 'MNC' + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:recyclerview-v7:23.0.0-rc1' + compile 'com.android.support:leanback-v17:23.0.0-rc1' + compile 'com.android.support:appcompat-v7:23.0.0-rc1' + + compile 'com.android.support:preference-v7:23.0.0-rc1' + compile 'com.android.support:preference-leanback-v17:23.0.0-rc1' + compile 'com.android.support:preference-v14:23.0.0-rc1' + + compile 'com.google.code.gson:gson:1.7.2' + compile 'com.squareup.picasso:picasso:2.3.2' + compile 'com.android.support:palette-v7:23.0.0-rc1' +} diff --git a/samples/SupportLeanbackShowcase/app/proguard-rules.pro b/samples/SupportLeanbackShowcase/app/proguard-rules.pro new file mode 100644 index 000000000..cf489a517 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/hahnr/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/samples/SupportLeanbackShowcase/app/src/androidTest/java/android/support/v17/leanback/supportleanbackshowcase/ApplicationTest.java b/samples/SupportLeanbackShowcase/app/src/androidTest/java/android/support/v17/leanback/supportleanbackshowcase/ApplicationTest.java new file mode 100644 index 000000000..f3cdd6fb0 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/androidTest/java/android/support/v17/leanback/supportleanbackshowcase/ApplicationTest.java @@ -0,0 +1,13 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..71f1b7d28 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java new file mode 100644 index 000000000..2d3353fe2 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.SearchOrbView; +import android.view.View; +import android.widget.Toast; + +import com.google.gson.Gson; + + +public class BrowserExample01Fragment extends BrowseFragment { + + private static final String TAG = "BrowserExample01Fragment"; + + private ArrayObjectAdapter mRowsAdapter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupRowAdapter(); + } + + private void setupUi() { + setHeadersState(HEADERS_ENABLED); + setHeadersTransitionOnBackEnabled(true); + setSearchAffordanceColors( + new SearchOrbView.Colors(getResources().getColor(R.color.search_color), + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + setTitle("Browser Example 01"); + setOnSearchClickedListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.implement_search), + Toast.LENGTH_LONG).show(); + } + }); + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.browsing_example_01)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(final CardRow cardRow) { + // Build main row using the ImageCardViewPresenter. + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + HeaderItem header = new HeaderItem(cardRow.getTitle()); + return new CardListRow(header, listRowAdapter, cardRow); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java new file mode 100644 index 000000000..b47caf172 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.SearchOrbView; +import android.view.View; +import android.widget.Toast; + +import com.google.gson.Gson; + +/** + * This fragment will be shown when the "Card Examples" card is selected at the home menu. It will + * display multiple card types. + */ +public class CardExampleFragment extends BrowseFragment { + + private static final String TAG = "CardExampleFragment"; + + private ArrayObjectAdapter mRowsAdapter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupRowAdapter(); + } + + private void setupUi() { + setHeadersState(HEADERS_ENABLED); + setHeadersTransitionOnBackEnabled(true); + setSearchAffordanceColors( + new SearchOrbView.Colors(getResources().getColor(R.color.search_color), + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + setTitle(getString(R.string.card_examples_title)); + setOnSearchClickedListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.implement_search), + Toast.LENGTH_LONG).show(); + } + }); + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.cards_card_example)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(final CardRow cardRow) { + // Build main row using the ImageCardViewPresenter. + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + HeaderItem header = new HeaderItem(cardRow.getTitle()); + return new CardListRow(header, listRowAdapter, cardRow); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java new file mode 100644 index 000000000..d23bd39b7 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ObjectAdapter; + +/** + * The {@link CardListRow} allows the {@link ShadowRowPresenterSelector} to access the {@link CardRow} + * held by the row and determine whether to use a {@link android.support.v17.leanback.widget.Presenter} + * with or without a shadow. + */ +public class CardListRow extends ListRow { + + private CardRow mCardRow; + + public CardListRow(HeaderItem header, ObjectAdapter adapter, CardRow cardRow) { + super(header, adapter); + setCardRow(cardRow); + } + + public CardRow getCardRow() { + return mCardRow; + } + + public void setCardRow(CardRow cardRow) { + this.mCardRow = cardRow; + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java new file mode 100644 index 000000000..2effa72b9 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +public class Constants { + + public static final boolean LOCAL_LOGD = true; + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java new file mode 100644 index 000000000..10ceceb38 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.v17.leanback.app.DetailsFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.DetailsOverviewRow; +import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.google.gson.Gson; + +/** + * Displays a card with more details. + */ +public class DetailViewExampleFragment extends DetailsFragment implements OnItemViewClickedListener, + OnItemViewSelectedListener { + + private static final String TAG = "DetailViewExampleFragment"; + private ArrayObjectAdapter mRowsAdapter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupEventListeners(); + } + + private void setupUi() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.detail_example)); + DetailedCard data = new Gson().fromJson(json, DetailedCard.class); + setTitle(getString(R.string.detail_view_title)); + + FullWidthDetailsOverviewRowPresenter rowPresenter = new FullWidthDetailsOverviewRowPresenter( + new DetailsDescriptionPresenter(getActivity())) { + @Override protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { + RowPresenter.ViewHolder viewHolder = super.createRowViewHolder(parent); + + // TODO: hahnr@ replace with API calls (they don't exist yet) + View actionsView = viewHolder.view.findViewById(R.id.details_overview_actions); + actionsView.setBackgroundColor(getActivity().getResources().getColor( + R.color.detail_view_actionbar_background)); + + View detailsView = viewHolder.view.findViewById(R.id.details_frame); + detailsView.setBackgroundColor( + getActivity().getResources().getColor(R.color.detail_view_background)); + return viewHolder; + } + }; + ListRowPresenter shadowDisabledRowPresenter = new ListRowPresenter(); + shadowDisabledRowPresenter.setShadowEnabled(false); + + // Setup PresenterSelector to distinguish between the different rows. + ClassPresenterSelector rowPresenterSelector = new ClassPresenterSelector(); + rowPresenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter); + rowPresenterSelector.addClassPresenter(CardListRow.class, shadowDisabledRowPresenter); + rowPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter()); + mRowsAdapter = new ArrayObjectAdapter(rowPresenterSelector); + + // Setup action and detail row. + DetailsOverviewRow detailsOverview = new DetailsOverviewRow(data); + int imageResId = data.getLocalImageResourceId(getActivity()); + detailsOverview.setImageDrawable(getResources().getDrawable(imageResId, null)); + ArrayObjectAdapter actionAdapter = new ArrayObjectAdapter(); + actionAdapter.add(new Action(1, getString(R.string.action_buy) + data.getPrice())); + actionAdapter.add(new Action(2, getString(R.string.action_wishlist))); + actionAdapter.add(new Action(3, getString(R.string.action_related))); + detailsOverview.setActionsAdapter(actionAdapter); + mRowsAdapter.add(detailsOverview); + + // Setup related row. + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter( + new CardPresenterSelector(getActivity())); + for (Card characterCard : data.getCharacters()) listRowAdapter.add(characterCard); + HeaderItem header = new HeaderItem(0, getString(R.string.header_related)); + mRowsAdapter.add(new CardListRow(header, listRowAdapter, null)); + + // Setup recommended row. + listRowAdapter = new ArrayObjectAdapter(new CardPresenterSelector(getActivity())); + for (Card card : data.getRecommended()) listRowAdapter.add(card); + header = new HeaderItem(1, getString(R.string.header_recommended)); + mRowsAdapter.add(new ListRow(header, listRowAdapter)); + + setAdapter(mRowsAdapter); + } + + private void setupEventListeners() { + // FIXME: leanbackteam@ The item & itemViewHolder parameters in onItemSelected are null in the DetailsOverviewRow as long as the user navigates top or down. After navigating left or right it will be the actual item rather than null. + setOnItemViewSelectedListener(this); + setOnItemViewClickedListener(this); + } + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (!(item instanceof Action)) return; + Action action = (Action) item; + if (action.getId() == 3) { + setSelectedPosition(1); + } else Toast.makeText(getActivity(), getString(R.string.action_cicked), Toast.LENGTH_LONG) + .show(); + } + + @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (mRowsAdapter.indexOf(row) > 0) { + getView().setBackgroundColor( + getResources().getColor(R.color.detail_view_related_background)); + } else { + getView().setBackgroundResource(R.drawable.background_canyon); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java new file mode 100644 index 000000000..56cbd3679 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; + +import com.google.gson.annotations.SerializedName; + +public class DetailedCard { + + @SerializedName("title") private String mTitle = ""; + @SerializedName("description") private String mDescription = ""; + @SerializedName("text") private String mText = ""; + @SerializedName("localImageResource") private String mLocalImageResource = null; + @SerializedName("price") private String mPrice = null; + @SerializedName("characters") private Card[] mCharacters = null; + @SerializedName("recommended") private Card[] mRecommended = null; + @SerializedName("year") private int mYear = 0; + + + public String getPrice() { + return mPrice; + } + + public int getYear() { + return mYear; + } + + public String getLocalImageResource() { + return mLocalImageResource; + } + + public String getText() { + return mText; + } + + public String getDescription() { + return mDescription; + } + + public String getTitle() { + return mTitle; + } + + public Card[] getCharacters() { + return mCharacters; + } + + public Card[] getRecommended() { + return mRecommended; + } + + public int getLocalImageResourceId(Context context) { + return context.getResources() + .getIdentifier(getLocalImageResource(), "drawable", context.getPackageName()); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java new file mode 100644 index 000000000..678b3d578 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.content.Context; +import android.support.v17.leanback.widget.Presenter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +/** + * This presenter is used to render a {@link DetailedCard} in the {@link + * DetailViewExampleFragment}. + */ +public class DetailsDescriptionPresenter extends Presenter { + + private ResourceCache mResourceCache = new ResourceCache(); + private Context mContext; + + public DetailsDescriptionPresenter(Context context) { + mContext = context; + } + + @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view, null); + return new ViewHolder(view); + } + + @Override public void onBindViewHolder(ViewHolder viewHolder, Object item) { + TextView primaryText = mResourceCache.getViewById(viewHolder.view, R.id.primary_text); + TextView sndText1 = mResourceCache.getViewById(viewHolder.view, R.id.secondary_text_first); + TextView sndText2 = mResourceCache.getViewById(viewHolder.view, R.id.secondary_text_second); + TextView extraText = mResourceCache.getViewById(viewHolder.view, R.id.extra_text); + + DetailedCard card = (DetailedCard) item; + primaryText.setText(card.getTitle()); + sndText1.setText(card.getDescription()); + sndText2.setText(card.getYear() + ""); + extraText.setText(card.getText()); + } + + @Override public void onUnbindViewHolder(ViewHolder viewHolder) { + // Nothing to do here. + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java new file mode 100644 index 000000000..f106df28c --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Activity; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.support.v17.leanback.app.GuidedStepFragment; + +/** + * TODO: Javadoc + */ +public class DialogExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#21272A"))); + + GuidedStepFragment fragment = new DialogExampleFragment(); + GuidedStepFragment.add(getFragmentManager(), fragment); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java new file mode 100644 index 000000000..384839f62 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist.Guidance; +import android.support.v17.leanback.widget.GuidedAction; +import android.widget.Toast; + +import java.util.List; + +/** + * TODO: Javadoc + */ +public class DialogExampleFragment extends GuidedStepFragment { + + private static final int ACTION_ID_POSITIVE = 1; + private static final int ACTION_ID_NEGATIVE = ACTION_ID_POSITIVE + 1; + + @NonNull + @Override + public Guidance onCreateGuidance(Bundle savedInstanceState) { + Guidance guidance = new Guidance(getString(R.string.dialog_example_title), + getString(R.string.dialog_example_description), + "", null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_POSITIVE) + .title(getString(R.string.dialog_example_button_positive)).build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_NEGATIVE) + .title(getString(R.string.dialog_example_button_negative)).build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_POSITIVE == action.getId()) { + Toast.makeText(getActivity(), R.string.dialog_example_button_toast_positive_clicked, + Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getActivity(), R.string.dialog_example_button_toast_negative_clicked, + Toast.LENGTH_SHORT).show(); + } + getActivity().finish(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java new file mode 100644 index 000000000..507a56c2f --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.v17.leanback.app.VerticalGridFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.FocusHighlight; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.VerticalGridPresenter; + +import com.google.gson.Gson; + +/** + * An example how to use leanback's {@link VerticalGridFragment}. + */ +public class GridExample extends VerticalGridFragment { + + private static final String TAG = "GridExample"; + private static final int COLUMNS = 4; + private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_NONE; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(getString(R.string.grid_example_title)); + setupRowAdapter(); + } + + private void setupRowAdapter() { + VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); + gridPresenter.setNumberOfColumns(COLUMNS); + setGridPresenter(gridPresenter); + + PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); + String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); + CardRow row = new Gson().fromJson(json, CardRow.class); + adapter.addAll(0, row.getCards()); + setAdapter(adapter); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java new file mode 100644 index 000000000..e1f5623fb --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; + +/* + * MainActivity class that loads MainFragment + */ +public class MainActivity extends Activity { + + /** + * Called when the activity is first created. + */ + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + if (savedInstanceState == null) { + Fragment fragment = new MainFragment(); + getFragmentManager().beginTransaction().replace(R.id.fragmentContainer, fragment) + .commit(); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java new file mode 100644 index 000000000..3522d0b45 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Fragment; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.support.v17.leanback.app.BackgroundManager; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.DisplayMetrics; +import android.util.Log; + +import com.google.gson.Gson; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +import java.net.URI; +import java.util.Timer; +import java.util.TimerTask; + + +public class MainFragment extends BrowseFragment { + + public static final String VIDEO_SURFACE_FRAGMENT_TAG = "VIDEO_SURFACE"; + private static final String TAG = "MainFragment"; + private static final int BACKGROUND_UPDATE_DELAY = 300; + private static final int DEFAULT_BACKGROUND_IMAGE = R.drawable.default_background; + private final Handler mHandler = new Handler(); + private ArrayObjectAdapter mRowsAdapter; + private Target mBackgroundTarget; + private Timer mBackgroundTimer; + private URI mBackgroundURI; + private BackgroundManager mBackgroundManager; + private DisplayMetrics mMetrics; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onActivityCreated"); + super.onActivityCreated(savedInstanceState); + + setupBackgroundManager(); + setupUIElements(); + setupRowAdapter(); + setupEventListeners(); + } + + @Override public void onDestroy() { + super.onDestroy(); + if (null != mBackgroundTimer) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onDestroy: " + mBackgroundTimer.toString()); + mBackgroundTimer.cancel(); + } + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.cards_launcher)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(CardRow cardRow) { + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + return new ListRow(listRowAdapter); + } + + private void setupBackgroundManager() { + mBackgroundManager = BackgroundManager.getInstance(getActivity()); + mBackgroundManager.setThemeDrawableResourceId(DEFAULT_BACKGROUND_IMAGE); + mBackgroundManager.attach(getActivity().getWindow()); + + mBackgroundTarget = new PicassoBackgroundManagerTarget(mBackgroundManager); + mMetrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); + getView().setBackgroundResource(R.drawable.bg_living_room_wide); + //updateBackgroundImage(R.drawable.bg_living_room_wide); + } + + private void setupUIElements() { + setTitle(getString(R.string.browse_title)); + setBadgeDrawable(getResources().getDrawable(R.drawable.title_android_tv, null)); + setHeadersState(HEADERS_DISABLED); + setHeadersTransitionOnBackEnabled(false); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + } + + private void setupEventListeners() { + setOnItemViewClickedListener(new ItemViewClickedListener()); + setOnItemViewSelectedListener(new ItemViewSelectedListener()); + } + + protected void updateBackgroundImage(URI uri) { + // Deactivated until we decide whether to load a background image from an URL or resource. @hahnr + if (true) return; + Picasso.with(getActivity()).load(uri.toString()) + .resize(mMetrics.widthPixels, mMetrics.heightPixels).centerCrop() + .error(DEFAULT_BACKGROUND_IMAGE).into(mBackgroundTarget); + } + + protected void updateBackgroundImage(Drawable drawable) { + mBackgroundManager.setDrawable(drawable); + } + + protected void updateBackgroundImage(int resId) { + mBackgroundManager.setDrawable(getResources().getDrawable(resId, null)); + } + + private void startBackgroundTimer() { + if (null != mBackgroundTimer) { + mBackgroundTimer.cancel(); + } + mBackgroundTimer = new Timer(); + mBackgroundTimer.schedule(new UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY); + } + + private final class ItemViewClickedListener implements OnItemViewClickedListener { + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + Card card = (Card) item; + int id = card.getId(); + switch (id) { + case 0: { + updateBackgroundImage(new ColorDrawable( + getResources().getColor(R.color.card_examples_background))); + Fragment fragment = new CardExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 2: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_canyon, null)); + Fragment fragment = new GridExample(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 3: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_canyon, null)); + Fragment fragment = new DetailViewExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 4: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_canyon, null)); + Fragment fragment = new VideoConsumptionExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, new VideoSurfaceFragment(), + VIDEO_SURFACE_FRAGMENT_TAG) + .add(R.id.fragmentContainer, fragment).addToBackStack(null) + .commit(); + break; + } + case 5: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_sax, null)); + Fragment fragment = new MusicConsumptionExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 6: { + // Let's create a new Wizard for a given Movie. The movie can come from any sort + // of data source. To simplify this example we decode it from a JSON source + // which might be loaded from a server in a real world example. + Intent intent = new Intent(getActivity().getBaseContext(), + WizardExampleActivity.class); + + // Prepare extras which contains the Movie and will be passed to the Activity + // which is started through the Intent/. + Bundle extras = new Bundle(); + String json = Utils.inputStreamToString( + getResources().openRawResource(R.raw.wizard_example)); + Movie movie = new Gson().fromJson(json, Movie.class); + extras.putSerializable("movie", movie); + intent.putExtras(extras); + + // Finally, start the wizard Activity. + startActivity(intent); + break; + } + case 7: { + Intent intent = new Intent(getActivity().getBaseContext(), + SettingsExampleActivity.class); + startActivity(intent); + break; + } + case 8: { + Intent intent = new Intent(getActivity().getBaseContext(), + DialogExampleActivity.class); + startActivity(intent); + break; + } + default: + break; + } + } + } + + private final class ItemViewSelectedListener implements OnItemViewSelectedListener { + + @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + } + } + + private class UpdateBackgroundTask extends TimerTask { + + @Override public void run() { + mHandler.post(new Runnable() { + @Override public void run() { + if (mBackgroundURI != null) { + updateBackgroundImage(mBackgroundURI); + } + } + }); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java new file mode 100644 index 000000000..89d81ee5d --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Handler; +import android.support.v17.leanback.app.PlaybackControlGlue; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ControlButtonPresenterSelector; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.Log; +import android.view.KeyEvent; +import android.view.SurfaceHolder; +import android.view.View; + +import java.io.IOException; + +/** + * This glue extends the {@link PlaybackControlGlue} with a {@link MediaPlayer} synchronization. It + * supports 7 actions:
  • {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction}
  • + *
  • {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction}
+ *

+ */ +public abstract class MediaPlayerGlue extends PlaybackControlGlue implements + OnItemViewSelectedListener { + + public static final int FAST_FORWARD_REWIND_STEP = 10 * 1000; // in milliseconds + public static final int FAST_FORWARD_REWIND_REPEAT_DELAY = 200; // in milliseconds + private static final String TAG = "MediaPlayerGlue"; + protected final PlaybackControlsRow.ThumbsDownAction mThumbsDownAction; + protected final PlaybackControlsRow.ThumbsUpAction mThumbsUpAction; + private final Context mContext; + private final MediaPlayer mPlayer = new MediaPlayer(); + private final PlaybackControlsRow.RepeatAction mRepeatAction; + private final PlaybackControlsRow.ShuffleAction mShuffleAction; + private PlaybackControlsRow mControlsRow; + private Runnable mRunnable; + private Handler mHandler = new Handler(); + private boolean mPaused = false; + private boolean mInitialized = false; // true when the MediaPlayer is prepared/initialized + private OnMediaFileFinishedPlayingListener mMediaFileFinishedPlayingListener; + private Action mSelectedAction; // the action which is currently selected by the user + private long mLastKeyDownEvent = 0L; // timestamp when the last DPAD_CENTER KEY_DOWN occurred + private MetaData mMetaData; + private Uri mMediaSourceUri = null; + private String mMediaSourcePath = null; + + public MediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { + super(context, fragment, new int[]{1}); + mContext = context; + + // Instantiate secondary actions + mShuffleAction = new PlaybackControlsRow.ShuffleAction(mContext); + mRepeatAction = new PlaybackControlsRow.RepeatAction(mContext); + mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(mContext); + mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(mContext); + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + + // Setup controls and notify UI about change. + setFadingEnabled(false); + onStateChanged(); + + // Register selected listener such that we know what action the user currently has focused. + fragment.setOnItemViewSelectedListener(this); + } + + /** + * Will reset the {@link MediaPlayer} and the glue such that a new file can be played. You are + * not required to call this method before playing the first file. However you have to call it + * before playing a second one. + */ + public void reset() { + mPaused = mInitialized = false; + mPlayer.reset(); + } + + public void setOnMediaFileFinishedPlayingListener(OnMediaFileFinishedPlayingListener listener) { + mMediaFileFinishedPlayingListener = listener; + } + + /** + * Override this method in case you need to add different secondary actions. + * + * @param secondaryActionsAdapter The adapter you need to add the {@link Action}s to. + */ + protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { + secondaryActionsAdapter.add(mShuffleAction); + secondaryActionsAdapter.add(mRepeatAction); + secondaryActionsAdapter.add(mThumbsDownAction); + secondaryActionsAdapter.add(mThumbsUpAction); + } + + /** + * @see MediaPlayer#setDisplay(SurfaceHolder) + */ + public void setDisplay(SurfaceHolder surfaceHolder) { + mPlayer.setDisplay(surfaceHolder); + } + + /** + * Use this method to setup the {@link PlaybackControlsRowPresenter}. It'll be called + * after the {@link PlaybackControlsRowPresenter} has been created and the primary and + * secondary actions have been added. + * + * @param presenter The PlaybackControlsRowPresenter used to display the controls. + */ + public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { + // TODO: hahnr@ move into resources + presenter.setProgressColor(Color.parseColor("#feab91")); + presenter.setBackgroundColor(Color.parseColor("#db2a0f")); + } + + @Override public PlaybackControlsRowPresenter createControlsRowAndPresenter() { + PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter(); + mControlsRow = getControlsRow(); + + // Add secondary actions and change the control row color. + ArrayObjectAdapter secondaryActions = new ArrayObjectAdapter( + new ControlButtonPresenterSelector()); + mControlsRow.setSecondaryActionsAdapter(secondaryActions); + addSecondaryActions(secondaryActions); + setupControlsRowPresenter(presenter); + return presenter; + } + + @Override public void enableProgressUpdating(final boolean enabled) { + if (!enabled) { + if (mRunnable != null) mHandler.removeCallbacks(mRunnable); + return; + } + mRunnable = new Runnable() { + @Override public void run() { + updateProgress(); + Log.d(TAG, "enableProgressUpdating(boolean)"); + mHandler.postDelayed(this, getUpdatePeriod()); + } + }; + mHandler.postDelayed(mRunnable, getUpdatePeriod()); + } + + @Override public void onActionClicked(Action action) { + // If either 'Shuffle' or 'Repeat' has been clicked we need to make sure the acitons index + // is incremented and the UI updated such that we can display the new state. + super.onActionClicked(action); + if (action instanceof PlaybackControlsRow.ShuffleAction) { + mShuffleAction.nextIndex(); + } else if (action instanceof PlaybackControlsRow.RepeatAction) { + mRepeatAction.nextIndex(); + } else if (action instanceof PlaybackControlsRow.ThumbsUpAction) { + if (mThumbsUpAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } else { + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } + } else if (action instanceof PlaybackControlsRow.ThumbsDownAction) { + if (mThumbsDownAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } else { + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } + } + onMetadataChanged(); + } + + @Override public boolean onKey(View v, int keyCode, KeyEvent event) { + // This method is overridden in order to make implement fast forwarding and rewinding when + // the user keeps the corresponding action pressed. + // We only consume DPAD_CENTER Action_DOWN events on the Fast-Forward and Rewind action and + // only if it has not been pressed in the last X milliseconds. + boolean consume = mSelectedAction instanceof PlaybackControlsRow.RewindAction; + consume = consume || mSelectedAction instanceof PlaybackControlsRow.FastForwardAction; + consume = consume && mInitialized; + consume = consume && event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER; + consume = consume && event.getAction() == KeyEvent.ACTION_DOWN; + consume = consume && System + .currentTimeMillis() - mLastKeyDownEvent > FAST_FORWARD_REWIND_REPEAT_DELAY; + if (consume) { + mLastKeyDownEvent = System.currentTimeMillis(); + int newPosition = getCurrentPosition() + FAST_FORWARD_REWIND_STEP; + if (mSelectedAction instanceof PlaybackControlsRow.RewindAction) { + newPosition = getCurrentPosition() - FAST_FORWARD_REWIND_STEP; + } + // Make sure the new calculated duration is in the range 0 >= X >= MediaDuration + if (newPosition < 0) newPosition = 0; + if (newPosition > getMediaDuration()) newPosition = getMediaDuration(); + seekTo(newPosition); + return true; + } + return super.onKey(v, keyCode, event); + } + + @Override public boolean hasValidMedia() { + return mMetaData != null; + } + + @Override public boolean isMediaPlaying() { + return mPlayer.isPlaying(); + } + + @Override public CharSequence getMediaTitle() { + return hasValidMedia() ? mMetaData.getTitle() : "N/a"; + } + + @Override public CharSequence getMediaSubtitle() { + return hasValidMedia() ? mMetaData.getArtist() : "N/a"; + } + + @Override public int getMediaDuration() { + return mInitialized ? mPlayer.getDuration() : 0; + } + + @Override public Drawable getMediaArt() { + return hasValidMedia() ? mMetaData.getCover() : null; + } + + @Override public long getSupportedActions() { + return PlaybackControlGlue.ACTION_PLAY_PAUSE | PlaybackControlGlue.ACTION_FAST_FORWARD | PlaybackControlGlue.ACTION_REWIND; + } + + @Override public int getCurrentSpeedId() { + // 0 = Pause, 1 = Normal Playback Speed + return mPlayer.isPlaying() ? 1 : 0; + } + + @Override public int getCurrentPosition() { + return mInitialized ? mPlayer.getCurrentPosition() : 0; + } + + @Override protected void startPlayback(int speed) throws IllegalStateException { + if (mPaused) { + mPlayer.start(); + } else if (!isMediaPlaying()) { + reset(); + try { + if (mMediaSourceUri != null) mPlayer.setDataSource(getContext(), mMediaSourceUri); + else mPlayer.setDataSource(mMediaSourcePath); + } catch (IOException e) { + throw new RuntimeException(e); + } + mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override public void onPrepared(MediaPlayer mp) { + mInitialized = true; + mPaused = false; + mPlayer.start(); + onMetadataChanged(); + onStateChanged(); + updateProgress(); + } + }); + mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override public void onCompletion(MediaPlayer mp) { + if (mInitialized && mMediaFileFinishedPlayingListener != null) + mMediaFileFinishedPlayingListener.onMediaFileFinishedPlaying(mMetaData); + } + }); + mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { + @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { + mControlsRow.setBufferedProgress((int) (mp.getDuration() * (percent / 100f))); + } + }); + mPlayer.prepareAsync(); + onStateChanged(); + } + } + + @Override protected void pausePlayback() { + if (mPlayer.isPlaying()) { + mPlayer.pause(); + mPaused = true; + } + } + + @Override protected void skipToNext() { + // Not supported. + } + + @Override protected void skipToPrevious() { + // Not supported. + } + + /** + * Called whenever the user presses fast-forward/rewind or when the user keeps the corresponding + * action pressed. + * + * @param newPosition The new position of the media track in milliseconds. + */ + protected void seekTo(int newPosition) { + mPlayer.seekTo(newPosition); + } + + /** + * @see MediaPlayer#setDataSource(Context, Uri) + */ + public void setMediaSource(Uri uri) { + mMediaSourceUri = uri; + } + + /** + * @see MediaPlayer#setDataSource(String) + */ + public void setMediaSource(String path) { + mMediaSourcePath = path; + } + + /** + * Call to startPlayback(1). + * + * @throws IllegalStateException See {@link MediaPlayer} for further information about it's + * different states when setting a data source and preparing it to be played. + */ + public void startPlayback() throws IllegalStateException { + startPlayback(1); + } + + /** + * @return Returns true iff 'Shuffle' is ON. + */ + public boolean useShuffle() { + return mShuffleAction.getIndex() == PlaybackControlsRow.ShuffleAction.ON; + } + + /** + * @return Returns true iff 'Repeat-One' is ON. + */ + public boolean repeatOne() { + return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ONE; + } + + /** + * @return Returns true iff 'Repeat-All' is ON. + */ + public boolean repeatAll() { + return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ALL; + } + + public void setMetaData(MetaData metaData) { + mMetaData = metaData; + onMetadataChanged(); + } + + /** + * This is a listener implementation for the {@link OnItemViewSelectedListener} of the {@link + * PlaybackOverlayFragment}. This implementation is required in order to detect KEY_DOWN events + * on the {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction} and + * {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}. Thus you should + * NOT set another {@link OnItemViewSelectedListener} on your {@link + * PlaybackOverlayFragment}. Instead, override this method and call its super (this) + * implementation. + * + * @see OnItemViewSelectedListener#onItemSelected(Presenter.ViewHolder, Object, + * RowPresenter.ViewHolder, Row) + */ + @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (item instanceof Action) { + mSelectedAction = (Action) item; + } else { + mSelectedAction = null; + } + } + + /** + * A listener which will be called whenever a track is finished playing. + */ + public interface OnMediaFileFinishedPlayingListener { + + /** + * Called when a track is finished playing. + * + * @param metaData The track's {@link MetaData} which just finished playing. + */ + void onMediaFileFinishedPlaying(MetaData metaData); + + } + + /** + * Holds the meta data such as track title, artist and cover art. It'll be used by the {@link + * MediaPlayerGlue}. + */ + public static class MetaData { + + private String mTitle; + private String mArtist; + private Drawable mCover; + + + public String getTitle() { + return mTitle; + } + + public void setTitle(String title) { + this.mTitle = title; + } + + public String getArtist() { + return mArtist; + } + + public void setArtist(String artist) { + this.mArtist = artist; + } + + public Drawable getCover() { + return mCover; + } + + public void setCover(Drawable cover) { + this.mCover = cover; + } + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java new file mode 100644 index 000000000..3fc9d6955 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java @@ -0,0 +1,36 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +public class Movie implements Serializable { + + private static final long serialVersionUID = 133742L; + + @SerializedName("title") + private String mTitle = ""; + @SerializedName("price_hd") + private String mPriceHd = "n/a"; + @SerializedName("price_sd") + private String mPriceSd = "n/a"; + @SerializedName("breadcrump") + private String mBreadcrump = ""; + + public String getTitle() { + return mTitle; + } + + public String getBreadcrump() { + return mBreadcrump; + } + + public String getPriceHd() { + return mPriceHd; + } + + public String getPriceSd() { + return mPriceSd; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java new file mode 100644 index 000000000..17e010a93 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.net.Uri; +import android.os.Bundle; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Song; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.SongList; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.Log; + +import com.google.gson.Gson; + +import java.util.List; + +/** + * This example shows how to play music files and build a simple track list. + */ +public class MusicConsumptionExampleFragment extends PlaybackOverlayFragment implements + OnItemViewClickedListener, Song.OnSongRowClickListener, + MediaPlayerGlue.OnMediaFileFinishedPlayingListener { + + private static final String TAG = "MusicConsumptionExampleFragment"; + private ArrayObjectAdapter mRowsAdapter; + private MediaPlayerGlue mGlue; + private int mCurrentSongIndex = 0; + private List mSongList; + private boolean mAdapterNotified = false; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreate"); + + mGlue = new MediaPlayerGlue(getActivity(), this) { + + @Override protected void onRowChanged(PlaybackControlsRow row) { + if (mRowsAdapter == null || mAdapterNotified) return; + //mAdapterNotified = true; + mRowsAdapter.notifyArrayItemRangeChanged(0, 1); + } + }; + mGlue.setOnMediaFileFinishedPlayingListener(this); + + String json = Utils.inputStreamToString( + getResources().openRawResource(R.raw.music_consumption_example)); + mSongList = new Gson().fromJson(json, SongList.class).getSongs(); + Song song = mSongList.get(mCurrentSongIndex); + MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); + metaData.setArtist(song.getDescription()); + metaData.setTitle(song.getTitle()); + metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); + Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); + mGlue.setMetaData(metaData); + mGlue.setMediaSource(uri); + + setBackgroundType(PlaybackOverlayFragment.BG_LIGHT); + addPlaybackControlsRow(); + } + + @Override public void onStart() { + super.onStart(); + mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); + } + + @Override public void onStop() { + super.onStop(); + mGlue.enableProgressUpdating(false); + mGlue.reset(); + } + + private void addPlaybackControlsRow() { + final PlaybackControlsRowPresenter controlsPresenter = mGlue + .createControlsRowAndPresenter(); + ClassPresenterSelector selector = new ClassPresenterSelector(); + Song.Presenter songPresenter = new Song.Presenter(getActivity()); + songPresenter.setOnClickListener(this); + selector.addClassPresenter(Song.class, songPresenter); + selector.addClassPresenter(TrackListHeader.class, + new TrackListHeader.Presenter(getActivity())); + selector.addClassPresenter(PlaybackControlsRow.class, controlsPresenter); + mRowsAdapter = new ArrayObjectAdapter(selector); + mRowsAdapter.add(mGlue.getControlsRow()); + mRowsAdapter.add(new TrackListHeader()); + mRowsAdapter.addAll(2, mSongList); + setAdapter(mRowsAdapter); + setOnItemViewClickedListener(this); + } + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (!(item instanceof Action)) return; + mGlue.onActionClicked((Action) item); + } + + + @Override public void onSongRowClicked(Song song) { + mCurrentSongIndex = mSongList.indexOf(song); + startPlayback(); + } + + + @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData song) { + if (mGlue.repeatOne()) { + startPlayback(); + return; + } + if (mGlue.useShuffle()) { + mCurrentSongIndex = (int) (Math.random() * mSongList.size()); + } else mCurrentSongIndex++; + if (mCurrentSongIndex >= mSongList.size()) { + mCurrentSongIndex = 0; + if (!mGlue.repeatAll()) return; + } + startPlayback(); + } + + private void startPlayback() { + Song song = mSongList.get(mCurrentSongIndex); + MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); + metaData.setArtist(song.getDescription()); + metaData.setTitle(song.getTitle()); + metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); + + Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); + mGlue.setMetaData(metaData); + mGlue.setMediaSource(uri); + mGlue.startPlayback(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java new file mode 100644 index 000000000..012c08e6d --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.support.v17.leanback.app.BackgroundManager; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +/** + * Picasso target for updating default_background images + */ +public class PicassoBackgroundManagerTarget implements Target { + + private BackgroundManager mBackgroundManager; + + public PicassoBackgroundManagerTarget(BackgroundManager backgroundManager) { + this.mBackgroundManager = backgroundManager; + } + + @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) { + this.mBackgroundManager.setBitmap(bitmap); + } + + @Override public void onBitmapFailed(Drawable drawable) { + this.mBackgroundManager.setDrawable(drawable); + } + + @Override public void onPrepareLoad(Drawable drawable) { + // Do nothing, default_background manager has its own transitions + } + + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PicassoBackgroundManagerTarget that = (PicassoBackgroundManagerTarget) o; + + if (!mBackgroundManager.equals(that.mBackgroundManager)) return false; + + return true; + } + + @Override public int hashCode() { + return mBackgroundManager.hashCode(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java new file mode 100644 index 000000000..bee5cbbec --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java @@ -0,0 +1,22 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import android.util.SparseArray; +import android.view.View; + +/** + * ResourceCache allows retrieving children from a given view and caches the resulting views in + * order to prevent future lookups. + */ +public class ResourceCache { + + private final SparseArray mCachedViews = new SparseArray(); + + public ViewType getViewById(View view, int resId) { + View child = mCachedViews.get(resId, null); + if (child == null) { + child = view.findViewById(resId); + mCachedViews.put(resId, child); + } + return (ViewType) child; + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java new file mode 100644 index 000000000..dee2cab92 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; + +/* + * TODO: Javadoc + */ +public class SettingsExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java new file mode 100644 index 000000000..fef91b108 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java @@ -0,0 +1,87 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.support.v14.preference.PreferenceFragment; +import android.support.v17.preference.LeanbackPreferenceDialogFragment; +import android.support.v17.preference.LeanbackPreferenceFragment; +import android.support.v17.preference.LeanbackSettingsFragment; +import android.support.v7.preference.DialogPreference; +import android.support.v7.preference.ListPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.util.Log; + +import java.util.Stack; + +public class SettingsExampleFragment extends LeanbackSettingsFragment implements DialogPreference.TargetFragment { + + public static final String TAG = "SettingsExampleFragment"; + private final Stack fragments = new Stack(); + + @Override + public void onPreferenceStartInitialScreen() { + startPreferenceFragment(buildPreferenceFragment(R.xml.prefs, null)); + } + + @Override + public boolean onPreferenceStartFragment(PreferenceFragment preferenceFragment, + Preference preference) { + return false; + } + + @Override + public boolean onPreferenceStartScreen(PreferenceFragment preferenceFragment, + PreferenceScreen preferenceScreen) { + PreferenceFragment frag = buildPreferenceFragment(R.xml.prefs, preferenceScreen.getKey()); + if ("prefs_wifi_screen_key".equals(preferenceScreen.getKey())) { + ListPreference pref = (ListPreference)preferenceScreen.findPreference("prefs_wifi_key"); + pref.setEntries(new String[] {"Wi-Fi Network 01"}); + pref.setEntryValues(new String[] {"01"}); + if (Constants.LOCAL_LOGD) Log.d(TAG, "pref: " + pref); + } + startPreferenceFragment(frag); + return true; + } + + @Override + public Preference findPreference(CharSequence prefKey) { + return ((PreferenceFragment) fragments.peek()).findPreference(prefKey); + } + + private PreferenceFragment buildPreferenceFragment(int preferenceResId, String root) { + PreferenceFragment fragment = new PrefFragment(); + Bundle args = new Bundle(); + args.putInt("preferenceResource", preferenceResId); + args.putString("root", root); + fragment.setArguments(args); + return fragment; + } + + private class PrefFragment extends LeanbackPreferenceFragment { + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + String root = getArguments().getString("root", null); + int prefResId = getArguments().getInt("preferenceResource"); + if (root == null) { + addPreferencesFromResource(prefResId); + } else { + setPreferencesFromResource(prefResId, root); + } + } + + @Override + public void onAttach(Context context) { + fragments.push(this); + super.onAttach(context); + } + + @Override + public void onDetach() { + fragments.pop(); + super.onDetach(); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java new file mode 100644 index 000000000..f11a26cd8 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.PresenterSelector; + +/** + * This {@link PresenterSelector} will return a {@link ListRowPresenter} which has shadow support + * enabled or not depending on {@link CardRow#useShadow()} for a given row. + */ +public class ShadowRowPresenterSelector extends PresenterSelector { + + private ListRowPresenter mShadowEnabledRowPresenter = new ListRowPresenter(); + private ListRowPresenter mShadowDisabledRowPresenter = new ListRowPresenter(); + + public ShadowRowPresenterSelector() { + mShadowDisabledRowPresenter.setShadowEnabled(false); + } + + @Override public Presenter getPresenter(Object item) { + if (!(item instanceof CardListRow)) return mShadowDisabledRowPresenter; + CardListRow listRow = (CardListRow) item; + CardRow row = listRow.getCardRow(); + if (row.useShadow()) return mShadowEnabledRowPresenter; + return mShadowDisabledRowPresenter; + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java new file mode 100644 index 000000000..53a60d770 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.support.v17.leanback.widget.Row; + +public class SongListRow extends Row {} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java new file mode 100644 index 000000000..a68a37479 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.content.Context; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class TrackListHeader extends Row { + + public static class Presenter extends RowPresenter { + + private final Context mContext; + + public Presenter(Context context) { + mContext = context; + setHeaderPresenter(null); + } + + @Override public boolean isUsingDefaultSelectEffect() { + return false; + } + + @Override protected ViewHolder createRowViewHolder(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.row_track_list_header, parent, false); + view.setFocusable(false); + view.setFocusableInTouchMode(false); + return new ViewHolder(view); + } + } + + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java new file mode 100644 index 000000000..61efee9e8 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.content.ContentResolver; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.widget.ImageView; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.RequestCreator; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +/** + * A collection of utility methods, all static. + */ +public class Utils { + + public static int convertDpToPixel(Context ctx, int dp) { + float density = ctx.getResources().getDisplayMetrics().density; + return Math.round((float) dp * density); + } + + /** + * Will read the content from a given {@link InputStream} and return it as a {@link String}. + * + * @param inputStream The {@link InputStream} which should be read. + * @return Returns null if the the {@link InputStream} could not be read. Else + * returns the content of the {@link InputStream} as {@link String}. + */ + public static String inputStreamToString(InputStream inputStream) { + try { + byte[] bytes = new byte[inputStream.available()]; + inputStream.read(bytes, 0, bytes.length); + String json = new String(bytes); + return json; + } catch (IOException e) { + return null; + } + } + + /** + * The method uses {@link Picasso} to fetch an image from a given url, resize it (if required) + * and display it inside an {@link ImageView}. + * + * @param context Context which is used to create a {@link Picasso} instance. + * @param uri The {@link URI} to fetch the image from. + * @param target The {@link ImageView} which shall display the image. + * @param resizeWidthInDp The target width of the image. Pass -1 if you don't want + * to resize the image. + * @param resizeHeightInDp The target height of the image. Pass -1 if you don't + * want to resize the image. + * @param centerCrop Centers and scales an image to fit the requested bounds. + * @param errorDrawable A drawable which will be shown in case the image could not be fetched + * from the server. + * @see {@link Picasso#with(Context)} + * @see {@link RequestCreator#resize(int, int)} + * @see {@link RequestCreator#centerCrop()} + * @see {@link RequestCreator#error(Drawable)} + */ + public static void loadImageFromUri(Context context, URI uri, ImageView target, + int resizeWidthInDp, int resizeHeightInDp, + boolean centerCrop, Drawable errorDrawable) { + if (uri == null) return; + RequestCreator builder = Picasso.with(context).load(uri.toString()); + if (resizeHeightInDp != -1 && resizeWidthInDp != -1) + builder.resize(Utils.convertDpToPixel(context, resizeWidthInDp), + Utils.convertDpToPixel(context, resizeHeightInDp)); + if (centerCrop) builder.centerCrop(); + builder.error(errorDrawable).into(target); + } + + public static Uri getResourceUri(Context context, int resID) { + return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + + context.getResources().getResourcePackageName(resID) + '/' + + context.getResources().getResourceTypeName(resID) + '/' + + context.getResources().getResourceEntryName(resID)); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java new file mode 100644 index 000000000..058f759fa --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + + +public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment implements + OnItemViewClickedListener, MediaPlayerGlue.OnMediaFileFinishedPlayingListener { + + private static final String URL = "http://techslides.com/demos/sample-videos/small.mp4"; + private static final String TAG = "VideoConsumptionExampleFragment"; + private ArrayObjectAdapter mRowsAdapter; + private MediaPlayerGlue mGlue; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreate"); + + mGlue = new VideoMediaPlayerGlue(getActivity(), this) { + + @Override protected void onRowChanged(PlaybackControlsRow row) { + if (mRowsAdapter == null) return; + mRowsAdapter.notifyArrayItemRangeChanged(0, 1); + } + }; + mGlue.setOnMediaFileFinishedPlayingListener(this); + MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); + metaData.setArtist("A Googler"); + metaData.setTitle("Diving with Sharks"); + mGlue.setMetaData(metaData); + mGlue.setMediaSource(URL); + + Fragment videoSurfaceFragment = getFragmentManager() + .findFragmentByTag(MainFragment.VIDEO_SURFACE_FRAGMENT_TAG); + SurfaceView surface = (SurfaceView) videoSurfaceFragment.getView(); + surface.getHolder().addCallback(new SurfaceHolder.Callback() { + @Override public void surfaceCreated(SurfaceHolder holder) { + Log.d(TAG, "surfaceCreated(SurfaceHolder)"); + mGlue.setDisplay(holder); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + // Nothing to do + } + + @Override public void surfaceDestroyed(SurfaceHolder holder) { + Log.d(TAG, "surfaceDestroyed(SurfaceHolder)"); + } + }); + + setBackgroundType(PlaybackOverlayFragment.BG_LIGHT); + addPlaybackControlsRow(); + } + + @Override public void onStart() { + super.onStart(); + mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); + } + + @Override public void onStop() { + super.onStop(); + mGlue.enableProgressUpdating(false); + mGlue.reset(); + } + + private void addPlaybackControlsRow() { + final PlaybackControlsRowPresenter controlsPresenter = mGlue + .createControlsRowAndPresenter(); + mRowsAdapter = new ArrayObjectAdapter(controlsPresenter); + mRowsAdapter.add(mGlue.getControlsRow()); + setAdapter(mRowsAdapter); + setOnItemViewClickedListener(this); + } + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (!(item instanceof Action)) return; + mGlue.onActionClicked((Action) item); + } + + + @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData metaData) { + mGlue.startPlayback(); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java new file mode 100644 index 000000000..79aacd310 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.content.Context; +import android.graphics.Color; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; + +public abstract class VideoMediaPlayerGlue extends MediaPlayerGlue { + + private final PlaybackControlsRow.ClosedCaptioningAction mClosedCaptioningAction; + + public VideoMediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { + super(context, fragment); + + // Instantiate secondary actions + mClosedCaptioningAction = new PlaybackControlsRow.ClosedCaptioningAction(context); + setFadingEnabled(true); + } + + @Override protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { + secondaryActionsAdapter.add(mClosedCaptioningAction); + secondaryActionsAdapter.add(mThumbsDownAction); + secondaryActionsAdapter.add(mThumbsUpAction); + } + + @Override public void onActionClicked(Action action) { + super.onActionClicked(action); + if (action == mClosedCaptioningAction) { + mClosedCaptioningAction.nextIndex(); + } + } + + public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { + // TODO: hahnr@ move into resources + presenter.setProgressColor(Color.parseColor("#EEFF41")); + presenter.setBackgroundColor(Color.parseColor("#007236")); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java new file mode 100644 index 000000000..5f25c2806 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + +public class VideoSurfaceFragment extends Fragment { + + private static final String TAG = "VideoSurfaceFragment"; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.video_surface_fragment, null); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java new file mode 100644 index 000000000..4c4200ed8 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.support.v17.leanback.widget.GuidedActionsStylist; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_BUY_HD = 1; + private static final int ACTION_ID_BUY_SD = ACTION_ID_BUY_HD + 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(1); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + getString(R.string.wizard_example_choose_rent_options), + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_BUY_HD) + .title(getString(R.string.wizard_example_rent_hd)) + .description(mMovie.getPriceHd() + " " + + getString(R.string.wizard_example_watch_hd)) + .build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_BUY_SD) + .title(getString(R.string.wizard_example_rent_sd)) + .description(mMovie.getPriceSd() + " " + + getString(R.string.wizard_example_watch_sd)) + .build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + GuidedStepFragment fragment = new WizardExample2ndStepFragment(); + Bundle args = getArguments(); // Reuse the same arguments this fragment was given. + args.putBoolean("hd", ACTION_ID_BUY_HD == action.getId()); + fragment.setArguments(args); + add(getFragmentManager(), fragment); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java new file mode 100644 index 000000000..4d54a6a7e --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java @@ -0,0 +1,94 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.support.v17.leanback.widget.GuidedActionsStylist; +import android.widget.Toast; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_CONFIRM = 1; + private static final int ACTION_ID_PAYMENT_METHOD = ACTION_ID_CONFIRM + 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(2); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + getString(R.string.wizard_example_rental_period), + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public GuidedActionsStylist onCreateActionsStylist() { + GuidedActionsStylist stylist = new GuidedActionsStylist() { + + @Override + public void onBindViewHolder(ViewHolder vh, GuidedAction action) { + super.onBindViewHolder(vh, action); + + if (ACTION_ID_CONFIRM == action.getId()) { + Drawable background = getResources().getDrawable( + R.drawable.wizard_important_action_item_background, null); + vh.view.setBackground(background); + vh.getTitleView().setTextColor(Color.parseColor("#666666")); + vh.getDescriptionView().setTextColor(Color.parseColor("#666666")); + } else { + vh.view.setBackground(null); + vh.getTitleView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, + getActivity().getTheme())); + vh.getDescriptionView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, + getActivity().getTheme())); + } + } + }; + return stylist; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + boolean rentHighDefinition = getArguments().getBoolean("hd"); + + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_CONFIRM) + .title(getString(R.string.wizard_example_rent)) + .description(rentHighDefinition ? mMovie.getPriceHd() : mMovie.getPriceSd()) + .build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_PAYMENT_METHOD) + .title(getString(R.string.wizard_example_payment_method)) + .description("Visa - 1234 Balance $60.00") + .build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_PAYMENT_METHOD == action.getId()) { + Toast.makeText(getActivity(), + getString(R.string.wizard_example_toast_payment_method_clicked), + Toast.LENGTH_SHORT).show(); + } else { + GuidedStepFragment fragment = new WizardExample3rdStepFragment(); + fragment.setArguments(getArguments()); + add(getFragmentManager(), fragment); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java new file mode 100644 index 000000000..4838301fb --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java @@ -0,0 +1,92 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.support.v17.leanback.widget.GuidedActionsStylist; +import android.util.Log; + +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +/** + * TODO: JavaDoc + */ +public class WizardExample3rdStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_PROCESSING = 1; + private final Handler mFakeHttpHandler = new Handler(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(3); + } + + @Override + public void onStart() { + super.onStart(); + + // Fake Http call by creating some sort of delay. + mFakeHttpHandler.postDelayed(fakeHttpRequestRunnable, 4000L); + } + + @Override + public GuidedActionsStylist onCreateActionsStylist() { + GuidedActionsStylist stylist = new GuidedActionsStylist() { + @Override + public int onProvideItemLayoutId() { + return R.layout.wizard_progress_action_item; + } + + @Override + public int onProvideLayoutId() { + return R.layout.wizard_progress_action_container; + } + }; + return stylist; + } + + @Override + public void onStop() { + super.onStop(); + + // Make sure to cancel the execution of the Runnable in case the fragment is stopped. + mFakeHttpHandler.removeCallbacks(fakeHttpRequestRunnable); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + "Just a second...", + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_PROCESSING) + .title(getString(R.string.wizard_example_processing)) + .infoOnly(true) + .build(); + actions.add(action); + } + + private final Runnable fakeHttpRequestRunnable = new Runnable() { + @Override + public void run() { + GuidedStepFragment fragment = new WizardExample4thStepFragment(); + fragment.setArguments(getArguments()); + add(getFragmentManager(), fragment); + } + }; + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java new file mode 100644 index 000000000..623de26ca --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java @@ -0,0 +1,57 @@ +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.widget.Toast; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_WATCH = 1; + private static final int ACTION_ID_LATER = ACTION_ID_WATCH + 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(4); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + getString(R.string.wizard_example_rental_period), + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_WATCH) + .title(getString(R.string.wizard_example_watch_now)) + .build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_LATER) + .title(getString(R.string.wizard_example_later)) + .build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_WATCH == action.getId()) { + Toast.makeText(getActivity(), getString(R.string.wizard_example_watch_now_clicked), + Toast.LENGTH_SHORT).show(); + } + getActivity().finish(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java new file mode 100644 index 000000000..819fc774c --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.support.v17.leanback.app.BackgroundManager; +import android.support.v17.leanback.app.GuidedStepFragment; + +/** + * TODO: Javadoc + */ +public class WizardExampleActivity extends Activity { + + // When the user 'bought' the product and presses back, we don't want to show the 'Processing..' + // screen again, instead we want to go back to the very first step or close the wizard. Thus, we + // have to save the current step of the wizard and make it accessible to it's children. + private int mStep = 0; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setBackgroundDrawableResource(R.drawable.wizard_background_blackned); + + // Recover old step state. + if (savedInstanceState != null) { + mStep = savedInstanceState.getInt("step"); + } + + GuidedStepFragment fragment = new WizardExample1stStepFragment(); + fragment.setArguments(getIntent().getExtras()); // Delegate Movie to first step. + GuidedStepFragment.add(getFragmentManager(), fragment); + } + + public int getStep() { + return mStep; + } + + public void setStep(int step) { + mStep = step; + } + + @Override + public void onBackPressed() { + if (4 == getStep()) { + // The user 'bought' the product. When he presses 'Back' the Wizard will be closed and + // he will not be send back to 'Processing Payment...'-Screen. + finish(); + } else super.onBackPressed(); + } + + @Override + public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { + // Save current step persitently. + outPersistentState.putInt("step", mStep); + super.onSaveInstanceState(outState, outPersistentState); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java new file mode 100644 index 000000000..0b0be50e2 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExampleBaseStepFragment extends GuidedStepFragment { + + protected Movie mMovie; + + @Override + public int onProvideTheme() { + return R.style.Theme_Example_LeanbackWizard; + } + + WizardExampleActivity getWizardActivity() { + if (!(getActivity() instanceof WizardExampleActivity)) { + throw new IllegalStateException(WizardExampleActivity.class.getName() + " expected."); + } + return (WizardExampleActivity)getActivity(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + mMovie = (Movie)getArguments().getSerializable("movie"); + super.onCreate(savedInstanceState); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java new file mode 100644 index 000000000..c0b79c7e0 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.models; + +import android.content.Context; +import android.graphics.Color; +import android.util.Log; + +import com.google.gson.annotations.SerializedName; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * This is a generic example of a custom data object, containing info we might want to keep with + * each card on the home screen + */ +public class Card { + + @SerializedName("title") private String mTitle = ""; + @SerializedName("description") private String mDescription = ""; + @SerializedName("extraText") private String mExtraText = ""; + @SerializedName("imageUrl") private String mImageUrl; + @SerializedName("footerColor") private String mFooterColor = null; + @SerializedName("selectedColor") private String mSelectedColor = null; + @SerializedName("localImageResource") private String mLocalImageResource = null; + @SerializedName("footerIconLocalImageResource") private String mFooterResource = null; + @SerializedName("type") private Card.Type mType; + @SerializedName("id") private int mId; + @SerializedName("width") private int mWidth; + @SerializedName("height") private int mHeight; + + public String getTitle() { + return mTitle; + } + + public int getWidth() { + return mWidth; + } + + public int getHeight() { + return mHeight; + } + + public int getId() { + return mId; + } + + public Card.Type getType() { + return mType; + } + + public String getDescription() { + return mDescription; + } + + public String getExtraText() { + return mExtraText; + } + + public int getFooterColor() { + if (mFooterColor == null) return -1; + return Color.parseColor(mFooterColor); + } + + public int getSelectedColor() { + if (mSelectedColor == null) return -1; + return Color.parseColor(mSelectedColor); + } + + public String getImageUrl() { + return mImageUrl; + } + + public URI getImageURI() { + if (getImageUrl() == null) return null; + try { + return new URI(getImageUrl()); + } catch (URISyntaxException e) { + Log.d("URI exception: ", getImageUrl()); + return null; + } + } + + public int getLocalImageResourceId(Context context) { + return context.getResources().getIdentifier(getLocalImageResourceName(), "drawable", + context.getPackageName()); + } + + public String getLocalImageResourceName() { + return mLocalImageResource; + } + + public String getFooterLocalImageResourceName() { + return mFooterResource; + } + + public enum Type { + + THIN, + THIN_RATING, + ICON, + SQUARE_BIG, + SQUARE, + WIDE_SHORT, + SQUARE_SMALL, + DEFAULT, + SIDE_INFO, + SIDE_INFO_TEST_1, + TEXT, + CHARACTER, + GRID_SQUARE + + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java new file mode 100644 index 000000000..b2312cd61 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.models; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * This class represents a row of cards. In a real world application you might want to store more + * data than in this example. + */ +public class CardRow { + + // Used to determine whether the row shall use shadows when displaying its cards or not. + @SerializedName("shadow") private boolean mShadow = true; + @SerializedName("title") private String mTitle; + @SerializedName("cards") private List mCards; + + public String getTitle() { + return mTitle; + } + + public boolean useShadow() { + return mShadow; + } + + public List getCards() { + return mCards; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java new file mode 100644 index 000000000..0445a1bd4 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.models; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.google.gson.annotations.SerializedName; + +public class Song extends Row { + + @SerializedName("title") private String mTitle = ""; + @SerializedName("description") private String mDescription = ""; + @SerializedName("text") private String mText = ""; + @SerializedName("image") private String mImage = null; + @SerializedName("file") private String mFile = null; + @SerializedName("duration") private String mDuration = null; + @SerializedName("number") private int mNumber = 0; + + + public String getDuration() { + return mDuration; + } + + public int getNumber() { + return mNumber; + } + + public String getText() { + return mText; + } + + public String getDescription() { + return mDescription; + } + + public String getTitle() { + return mTitle; + } + + public int getFileResource(Context context) { + return context.getResources() + .getIdentifier(mFile, "raw", context.getPackageName()); + } + + public int getImageResource(Context context) { + return context.getResources() + .getIdentifier(mImage, "drawable", context.getPackageName()); + } + + public interface OnSongRowClickListener { + + void onSongRowClicked(Song song); + + } + + public static class Presenter extends RowPresenter implements View.OnClickListener { + + private final Context mContext; + private OnSongRowClickListener mClickListener; + + + public Presenter(Context context) { + mContext = context; + setHeaderPresenter(null); + } + + public void setOnClickListener(OnSongRowClickListener listener) { + mClickListener = listener; + } + + @Override protected ViewHolder createRowViewHolder(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.row_song, parent, false); + view.findViewById(R.id.rowContainer).setOnClickListener(this); + return new ViewHolder(view); + } + + @Override public boolean isUsingDefaultSelectEffect() { + return false; + } + + @Override protected void onBindRowViewHolder(ViewHolder vh, Object item) { + super.onBindRowViewHolder(vh, item); + Song song = (Song) item; + ((TextView) vh.view.findViewById(R.id.trackNumber)).setText("" + song.getNumber()); + ((TextView) vh.view.findViewById(R.id.trackDuration)).setText(song.getDuration()); + String text = song.getTitle() + " / " + song.getDescription(); + ((TextView) vh.view.findViewById(R.id.trackName)).setText(text); + vh.view.findViewById(R.id.rowContainer).setTag(item); + } + + @Override public void onClick(View v) { + if (mClickListener == null) return; + mClickListener.onSongRowClicked((Song) v.getTag()); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java new file mode 100644 index 000000000..603f9aa41 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.models; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + */ +public class SongList { + + @SerializedName("songs") private List mSongs; + + public List getSongs() { + return mSongs; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java new file mode 100644 index 000000000..574968c07 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; +import android.support.v17.leanback.widget.BaseCardView; +import android.support.v17.leanback.widget.Presenter; +import android.view.ViewGroup; + +/** + * This abstract, generic class will create and manage the + * ViewHolder and will provide typed Presenter callbacks such that you do not have to perform casts + * on your own. + * + * @param The cards' View Type. + */ +public abstract class AbstractCardPresenter extends Presenter { + + private static final String TAG = "AbstractCardPresenter"; + private final Context mContext; + + /** + * @param context The current context. + */ + public AbstractCardPresenter(Context context) { + mContext = context; + } + + public Context getContext() { + return mContext; + } + + @Override public final ViewHolder onCreateViewHolder(ViewGroup parent) { + CardViewType cardView = onCreateView(); + return new ViewHolder(cardView); + } + + @Override public final void onBindViewHolder(ViewHolder viewHolder, Object item) { + Card card = (Card) item; + onBindViewHolder(card, (CardViewType) viewHolder.view); + } + + @Override public final void onUnbindViewHolder(ViewHolder viewHolder) { + onUnbindViewHolder((CardViewType) viewHolder.view); + } + + public void onUnbindViewHolder(CardViewType cardView) { + // Nothing to clean up. Override if necessary. + } + + /** + * Invoked when a new view is created. + * + * @return Returns the newly created view. + */ + protected abstract CardViewType onCreateView(); + + /** + * Implement this method to update your card's view with the data bound to it. + * + * @param card The model containing the data for the card. + * @param cardView The view the card is bound to. + * @see Presenter#onBindViewHolder(Presenter.ViewHolder, Object) + */ + public abstract void onBindViewHolder(Card card, CardViewType cardView); + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java new file mode 100644 index 000000000..adfda2407 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.FooterLayoutCardView; +import android.support.v17.leanback.widget.Presenter; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.squareup.picasso.Picasso; + +/** + * A custom and abstract card {@link Presenter} which allows to create a card consisting of an image + * and a custom footer. The footer is passed as a layout and will be inflated automatically. + */ +public abstract class AbstractFooterCardPresenter extends + AbstractCardPresenter { + + private static final String TAG = "AbstractFooterCardPresenter"; + private final Drawable mLoadingErrorDrawable; + private final int mFooterLayoutd; + private final int mImageWidth; + private final int mImageHeight; + + /** + * @param context Used to retrieve default values such as error drawables. + * @param footerLayoutId The layout which represents the footer. + * @param imageWidth The width of the card's main image. This width defines the card's width + * too. + * @param imageHeight The height of the card's main image. The card's height will be + * imageHeight + footerHeight + */ + public AbstractFooterCardPresenter(Context context, int footerLayoutId, int imageWidth, + int imageHeight) { + super(context); + mFooterLayoutd = footerLayoutId; + mImageWidth = imageWidth; + mImageHeight = imageHeight; + + // In case the image could not be fetched from the server we want to make sure something is show. In this case, a solid color. + int color = context.getResources().getColor(R.color.loading_error_card_background); + mLoadingErrorDrawable = new ColorDrawable(color); + } + + @Override public final FooterLayoutCardView onCreateView() { + FooterLayoutCardView cardView = new FooterLayoutCardView(getContext(), mFooterLayoutd, + mImageWidth, mImageHeight); + onViewCreated(cardView); + return cardView; + } + + @Override public void onBindViewHolder(Card card, FooterLayoutCardView cardView) { + // Load the card's image. This can be either an image on a remote server or a local one stored in the resources. + ImageView imageView = cardView.getImageView(); + if (card.getImageURI() != null) { + Utils.loadImageFromUri(getContext(), card.getImageURI(), imageView, mImageWidth, + mImageHeight, true, mLoadingErrorDrawable); + } else if (card.getLocalImageResourceName() != null) { + int resourceId = getContext().getResources() + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); + Picasso.with(getContext()).load(resourceId).resize(mImageWidth, mImageHeight) + .centerCrop().into(imageView); + } + } + + /** + * Override this method to react to creations of new card views. + * + * @param cardView The view which has been created. + * @see Presenter#onCreateViewHolder(ViewGroup) + */ + public void onViewCreated(FooterLayoutCardView cardView) { + // Nothing to clean up. Override if necessary. + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java new file mode 100644 index 000000000..491fb2f72 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.PresenterSelector; + +import java.util.HashMap; + +/** + * This PresenterSelector will decide what Presenter to use depending on a given card's type. + *

+ * TODO: leanbackteam@ Discuss whether leanback's PresenterSelector should be renamed to + * AbstractPresenterSelector. + */ +public class CardPresenterSelector extends PresenterSelector { + + private final Context mContext; + private final HashMap presenters = new HashMap(); + + public CardPresenterSelector(Context context) { + mContext = context; + } + + @Override public Presenter getPresenter(Object item) { + if (!(item instanceof Card)) throw new RuntimeException( + String.format("The PresenterSelector only supports data items of type '%s'", + Card.class.getName())); + Card card = (Card) item; + Presenter presenter = presenters.get(card.getType()); + if (presenter == null) switch (card.getType()) { + case SQUARE: + presenter = new SingleLineCardPresenter(mContext); + break; + case THIN_RATING: + presenter = new MovieRatingCardPresenter(mContext); + break; + case SIDE_INFO: + presenter = new SideInfoCardPresenter(mContext); + break; + case SIDE_INFO_TEST_1: + presenter = new LauncherCardPresenter(mContext); + break; + case TEXT: + presenter = new TextCardPresenter(mContext); + break; + case ICON: + presenter = new IconCardPresenter(mContext); + break; + case CHARACTER: + presenter = new CharacterCardPresenter(mContext); + break; + case THIN: { + int width = (int) mContext.getResources() + .getDimension(R.dimen.thin_image_card_width); + int height = (int) mContext.getResources() + .getDimension(R.dimen.thin_image_card_height); + presenter = new ImageCardViewPresenter1(mContext, width, height); + } + break; + case SQUARE_BIG: { + int width = (int) mContext.getResources() + .getDimension(R.dimen.big_square_image_card_width); + int height = (int) mContext.getResources() + .getDimension(R.dimen.big_square_image_card_height); + presenter = new ImageCardViewPresenter(mContext, width, height); + } + break; + case GRID_SQUARE: { + int width = (int) mContext.getResources().getDimension(R.dimen.grid_card_width); + int height = (int) mContext.getResources().getDimension(R.dimen.grid_card_height); + presenter = new ImageCardViewPresenter(mContext, width, height); + } + break; + case WIDE_SHORT: { + presenter = new GameBannerCardPresenter(mContext); + } + break; + default: { + int width = (int) mContext.getResources() + .getDimension(R.dimen.default_image_card_width); + int height = (int) mContext.getResources() + .getDimension(R.dimen.default_image_card_height); + presenter = new ImageCardViewPresenter(mContext, width, height); + } + break; + } + presenters.put(card.getType(), presenter); + return presenter; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java new file mode 100644 index 000000000..5514674cb --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.support.v17.leanback.supportleanbackshowcase.Constants; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; +import android.support.v4.graphics.drawable.RoundedBitmapDrawable; +import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; +import android.util.Log; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +/** + * This Presenter is used to display the characters card row in the DetailView examples. + */ +public class CharacterCardPresenter extends AbstractCardPresenter { + + private static final String TAG = "CharacterCardPresenter"; + private final SparseArray mImageCache = new SparseArray(); + + public CharacterCardPresenter(Context context) { + super(context); + } + + @Override protected BaseCardViewEx onCreateView() { + final BaseCardViewEx cardView = new BaseCardViewEx(getContext()); + LayoutInflater.from(getContext()).inflate(R.layout.character_card, cardView); + cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override public void onFocusChange(View v, boolean hasFocus) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onFocusChanged(" + hasFocus + ")"); + ImageView mainImage = cardView.getViewById(R.id.main_image); + View container = cardView.getViewById(R.id.container); + if (hasFocus) { + container.setBackgroundResource(R.drawable.character_focused); + mainImage.setBackgroundResource(R.drawable.character_focused); + } else { + container.setBackgroundResource(R.drawable.character_not_focused_padding); + mainImage.setBackgroundResource(R.drawable.character_not_focused); + } + } + }); + return cardView; + } + + @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onBindViewHolder"); + TextView primaryText = cardView.getViewById(R.id.primary_text); + final ImageView imageView = cardView.getViewById(R.id.main_image); + + primaryText.setText(card.getTitle()); + if (card.getLocalImageResourceName() != null) { + int resourceId = card.getLocalImageResourceId(getContext()); + RoundedBitmapDrawable drawable = mImageCache.get(resourceId, null); + if (drawable == null) { + Bitmap bitmap = BitmapFactory + .decodeResource(getContext().getResources(), resourceId); + drawable = RoundedBitmapDrawableFactory.create(getContext().getResources(), bitmap); + drawable.setAntiAlias(true); + drawable.setCornerRadius(Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); + mImageCache.put(resourceId, drawable); + } + imageView.setImageDrawable(drawable); + if (Constants.LOCAL_LOGD) Log.d(TAG, "Round image created and set."); + } + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java new file mode 100644 index 000000000..d6e3d0e26 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.graphics.Color; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; +import android.widget.TextView; + +/** + * This presenter will display the cards representing a gamer banners. It inherits from {@link + * ImageCardViewPresenter} and will set a footer icon as well as a secondary text color. + */ +public class GameBannerCardPresenter extends ImageCardViewPresenter { + + private static final String TAG = "GameBannerCardPresenter"; + + public GameBannerCardPresenter(Context context) { + super(context, + (int) context.getResources().getDimension(R.dimen.wide_short_image_card_width), + (int) context.getResources().getDimension(R.dimen.wide_short_image_card_height)); + } + + @Override protected ImageCardViewReplacement onCreateView() { + ImageCardViewReplacement cardView = super.onCreateView(); + TextView secondaryText = cardView.getSecondaryTextView(); + secondaryText.setTextColor(Color.parseColor("#80c349")); + return cardView; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java new file mode 100644 index 000000000..0154743db --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; + +/** + * This Presenter will display cards which consists of a single icon which will be highlighted by a + * surrounding circle when the card is focused. AndroidTV uses these cards for entering settings + * menu. + */ +public class IconCardPresenter extends AbstractCardPresenter { + + private static final String TAG = "IconCardPresenter"; + + public IconCardPresenter(Context context) { + super(context); + } + + @Override protected BaseCardViewEx onCreateView() { + final BaseCardViewEx cardView = new BaseCardViewEx(getContext()); + LayoutInflater.from(getContext()).inflate(R.layout.icon_card, cardView); + LayoutInflater.from(getContext()).inflate(R.layout.icon_card_footer, cardView); + cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) cardView.getViewById(R.id.container) + .setBackgroundResource(R.drawable.icon_focused); + else cardView.getViewById(R.id.container).setBackground(null); + } + }); + return cardView; + } + + @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { + TextView primaryText = cardView.getViewById(R.id.primary_text); + ImageView imageView = cardView.getViewById(R.id.main_image); + + primaryText.setText(card.getTitle()); + if (card.getLocalImageResourceName() != null) { + int resourceId = card.getLocalImageResourceId(getContext()); + Picasso.with(getContext()).load(resourceId).into(imageView); + } + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java new file mode 100644 index 000000000..f467dad70 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.support.v17.leanback.supportleanbackshowcase.Constants; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; +import android.util.Log; +import android.view.View; + +import com.squareup.picasso.Picasso; + +import java.util.HashMap; + +/** + * A ImageCardViewPresenter is used to generate Views and bind Objects to them on demand. It + * contains an {@link ImageCardViewReplacement}. + */ +public class ImageCardViewPresenter extends AbstractCardPresenter { + + private static final String TAG = "ImageCardViewPresenter"; + private final int mImageWidthInDp; + private final int mImageHeightDp; + private final Drawable mLoadingErrorDrawable; + private final HashMap mSelectedColors = new HashMap(); + private int mDefaultFooterColor; + + public ImageCardViewPresenter(Context context, int imageWidthInDp, int imageHeightInDp) { + super(context); + int color = context.getResources().getColor(R.color.loading_error_card_background); + mLoadingErrorDrawable = new ColorDrawable(color); + + mDefaultFooterColor = context.getResources() + .getColor(R.color.default_card_footer_background_color); + mImageWidthInDp = imageWidthInDp; + mImageHeightDp = imageHeightInDp; + } + + @Override protected ImageCardViewReplacement onCreateView() { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreateView()"); + final ImageCardViewReplacement cardView = new ImageCardViewReplacement(getContext(), + mImageWidthInDp, + mImageHeightDp); + cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override public void onFocusChange(View v, boolean hasFocus) { + udateCardUi(cardView); + } + }); + return cardView; + } + + @Override public void onBindViewHolder(Card card, ImageCardViewReplacement cardView) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onBindViewHolder(Card,ImageCardViewReplacement)"); + cardView.setTag(card); + + // Display description iff there is one. + if (card.getDescription() == null || card.getDescription().length() == 0) { + cardView.getSecondaryTextView().setVisibility(View.GONE); + cardView.getPrimaryTextView().setLines(2); + cardView.getPrimaryTextView().setMaxLines(2); + } else { + cardView.getPrimaryTextView().setLines(1); + cardView.getPrimaryTextView().setMaxLines(1); + cardView.getSecondaryTextView().setText(card.getDescription()); + cardView.getSecondaryTextView().setVisibility(View.VISIBLE); + } + + // Display title iff there is one. + if (card.getTitle() == null || card.getTitle().length() == 0) { + cardView.getPrimaryTextView().setVisibility(View.GONE); + cardView.getSecondaryTextView().setLines(2); + cardView.getSecondaryTextView().setMaxLines(2); + } else { + cardView.getSecondaryTextView().setLines(1); + cardView.getSecondaryTextView().setMaxLines(1); + cardView.getPrimaryTextView().setText(card.getTitle()); + cardView.getPrimaryTextView().setVisibility(View.VISIBLE); + } + // Load main image from an URI or a local resource. + if (card.getImageURI() != null) { + Utils.loadImageFromUri(getContext(), card.getImageURI(), cardView.getImageView(), + mImageWidthInDp, mImageHeightDp, true, mLoadingErrorDrawable); + } else if (card.getLocalImageResourceName() != null) { + int resourceId = getContext().getResources() + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); + Picasso.with(getContext()).load(resourceId).resize(mImageWidthInDp, mImageHeightDp) + .centerCrop().into(cardView.getImageView()); + } + + // Load footer icon from a local resource or hide it. + cardView.getViewById(R.id.container).setVisibility(View.VISIBLE); + if (card.getFooterLocalImageResourceName() != null) { + int resourceId = getContext().getResources() + .getIdentifier(card.getFooterLocalImageResourceName(), + "drawable", getContext().getPackageName()); + Picasso.with(getContext()).load(resourceId).into(cardView.getIconView()); + cardView.getIconView().setVisibility(View.VISIBLE); + } else { + if (card.getDescription() == null || card.getDescription().isEmpty()) { + cardView.getViewById(R.id.container).setVisibility(View.GONE); + } + cardView.getIconView().setVisibility(View.GONE); + } + + // Update background color depending on the card's focused state. + udateCardUi(cardView); + } + + private void udateCardUi(ImageCardViewReplacement view) { + int color = mDefaultFooterColor; + + if (view.getTag() != null) { + Card card = (Card) view.getTag(); + if (card.getSelectedColor() != -1 && view.isSelected()) { + color = card.getSelectedColor(); + } + if (card.getFooterColor() != -1) { + color = card.getFooterColor(); + } + } + view.getInfoBoxView().setBackgroundColor(color); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java new file mode 100644 index 000000000..bd5712c69 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.Constants; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; +import android.support.v17.leanback.widget.ImageCardView; +import android.util.Log; + +/** + * A ImageCardViewPresenter is used to generate Views and bind Objects to them on demand. It + * contains an {@link ImageCardViewReplacement}. + */ +public class ImageCardViewPresenter1 extends AbstractCardPresenter { + + private static final String TAG = "ImageCardViewPresenter"; + private final int mImageWidthInDp; + private final int mImageHeightDp; + + public ImageCardViewPresenter1(Context context, int imageWidthInDp, int imageHeightInDp) { + super(context); + mImageWidthInDp = imageWidthInDp; + mImageHeightDp = imageHeightInDp; + } + + @Override protected ImageCardView onCreateView() { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreateView()"); + + final ImageCardView cardView = new ImageCardView(getContext(), R.style.ImageCardViewColoredTextStyle); + cardView.setMainImageDimensions(mImageWidthInDp, mImageHeightDp); + cardView.setFocusable(true); + return cardView; + } + + @Override public void onBindViewHolder(Card card, final ImageCardView cardView) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onBindViewHolder(Card,ImageCardViewReplacement)"); + cardView.setTag(card); + cardView.setTitleText(card.getTitle()); + //cardView.setContentText("Hello"); + if (card.getLocalImageResourceName() != null) { + int resourceId = getContext().getResources() + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); + cardView.getMainImageView().setImageResource(resourceId); + } + + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java new file mode 100644 index 000000000..894232125 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.widget.ImageView; + +import com.squareup.picasso.Picasso; + +/** + * THis Presenter displays an expandable card which is used e.g. in the AndroidTV launcher. Once + * such a card gets focused it expands and will show more details of the image. + */ +public class LauncherCardPresenter extends ImageCardViewPresenter { + + private static final String TAG = "LauncherCardPresenter"; + + public LauncherCardPresenter(Context context) { + super(context, 1 /* val > 0 required by Picasso */, + (int) context.getResources().getDimension(R.dimen.default_image_card_height)); + } + + @Override protected ImageCardViewReplacement onCreateView() { + ImageCardViewReplacement cardView = super.onCreateView(); + final ImageView imageView = cardView.getImageView(); + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override public void onFocusChange(View v, final boolean hasFocus) { + int expandedWidth = (int) getContext().getResources().getDimension( + R.dimen.default_image_card_width); + int collapsedWidth = (int) getContext().getResources().getDimension( + R.dimen.default_image_card_height); + + expandedWidth = collapsedWidth; + + ValueAnimator animator = new ValueAnimator(); + animator.setInterpolator(new AccelerateDecelerateInterpolator()); + animator.setIntValues(hasFocus ? collapsedWidth : expandedWidth, + hasFocus ? expandedWidth : collapsedWidth); + animator.setDuration(500); + animator.setStartDelay(0); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override public void onAnimationUpdate(ValueAnimator animation) { + ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams(); + layoutParams.width = (Integer) animation.getAnimatedValue(); + imageView.setLayoutParams(layoutParams); + } + }); + animator.start(); + } + }); + return cardView; + } + + @Override public void onBindViewHolder(Card card, ImageCardViewReplacement cardView) { + super.onBindViewHolder(card, cardView); + + ImageView imageView = cardView.getImageView(); + cardView.setTag(card); + int width = (int) getContext().getResources() + .getDimension(R.dimen.default_image_card_height); + ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams(); + layoutParams.width = Utils.convertDpToPixel(getContext(), width); + imageView.setLayoutParams(layoutParams); + + + if (card.getLocalImageResourceName() != null) { + int height = (int) getContext().getResources() + .getDimension(R.dimen.sidetext_image_card_height); + int resourceId = getContext().getResources() + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); + Picasso.with(getContext()).load(resourceId).into(imageView); + } + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java new file mode 100644 index 000000000..e3b2c7e3a --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; +import android.view.Gravity; + +/** + * This Presenter inherits from ImageCardViewPresenter and will set the secondary text alignment as + * well as a footer icon to display the movie's rating. + */ +public class MovieRatingCardPresenter extends ImageCardViewPresenter { + + private static final String TAG = "MovieRatingCardPresenter"; + + public MovieRatingCardPresenter(Context context) { + super(context, (int) context.getResources().getDimension(R.dimen.thin_image_card_width), + (int) context.getResources().getDimension(R.dimen.thin_image_card_height)); + } + + @Override public void onBindViewHolder(Card card, ImageCardViewReplacement cardView) { + super.onBindViewHolder(card, cardView); + cardView.getPrimaryTextView().setLines(2); + cardView.getPrimaryTextView().setMaxLines(2); + cardView.getSecondaryTextView().setGravity(Gravity.RIGHT); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java new file mode 100644 index 000000000..e1e4dc614 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.OnActivateStateChangeHandler; +import android.support.v17.leanback.widget.BaseCardView; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; + +/** + * This Presenter will display a card consisting of an image on the left side of the card followed + * by text on the right side. The image and text have equal width. The text will work like a info + * box, thus it will be hidden if the parent row is inactive. This behavior is unique to this card + * and requires a special focus handler. + */ +public class SideInfoCardPresenter extends AbstractCardPresenter implements + OnActivateStateChangeHandler { + + private static final String TAG = "SideInfoCardPresenter"; + + public SideInfoCardPresenter(Context context) { + super(context); + } + + @Override protected BaseCardViewEx onCreateView() { + BaseCardViewEx cardView = new BaseCardViewEx(getContext()); + cardView.setCardType(BaseCardView.CARD_TYPE_MAIN_ONLY); + cardView.addView(LayoutInflater.from(getContext()).inflate(R.layout.side_info_card, null)); + cardView.setOnActivateStateChangeHandler(this); + onActivateStateChanged(cardView, cardView.isActivated()); + return cardView; + } + + @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { + ImageView imageView = cardView.getViewById(R.id.main_image); + if (card.getLocalImageResourceName() != null) { + int width = (int) getContext().getResources() + .getDimension(R.dimen.sidetext_image_card_width); + int height = (int) getContext().getResources() + .getDimension(R.dimen.sidetext_image_card_height); + int resourceId = getContext().getResources() + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); + Picasso.with(getContext()).load(resourceId).resize(width, height).centerCrop() + .into(imageView); + } + + TextView primaryText = cardView.getViewById(R.id.primary_text); + primaryText.setText(card.getTitle()); + + TextView secondaryText = cardView.getViewById(R.id.secondary_text); + secondaryText.setText(card.getDescription()); + + TextView extraText = cardView.getViewById(R.id.extra_text); + extraText.setText(card.getExtraText()); + } + + @Override public void onActivateStateChanged(final BaseCardViewEx cardView, boolean activated) { + cardView.getViewById(R.id.info).setVisibility(activated ? View.VISIBLE : View.GONE); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java new file mode 100644 index 000000000..add3dfae7 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; +import android.support.v17.leanback.widget.BaseCardView; +import android.view.LayoutInflater; +import android.widget.ImageView; +import android.widget.TextView; + +/** + * This Presenter will display a card which consists of a big image followed by a colored footer. + * Not only the colored footer is unique to this card, but also it's footer (info) will be visible + * even when its parent row is inactive. + */ +public class SingleLineCardPresenter extends AbstractCardPresenter { + + private static final String TAG = "SingleLineCardPresenter"; + + public SingleLineCardPresenter(Context context) { + super(context); + } + + @Override protected BaseCardViewEx onCreateView() { + BaseCardViewEx cardView = new BaseCardViewEx(getContext()); + cardView.setCardType(BaseCardView.CARD_TYPE_MAIN_ONLY); + cardView.addView( + LayoutInflater.from(getContext()).inflate(R.layout.single_line_card_footer, null)); + return cardView; + } + + @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { + TextView primaryText = cardView.getViewById(R.id.primary_text); + primaryText.setText(card.getTitle()); + + int resourceId = getContext().getResources() + .getIdentifier(card.getLocalImageResourceName(), "drawable", + getContext().getPackageName()); + ImageView mainImage = cardView.getViewById(R.id.main_image); + mainImage.setImageResource(resourceId); + + cardView.getViewById(R.id.container).setBackgroundColor(card.getFooterColor()); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java new file mode 100644 index 000000000..93d42e0e1 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.Presenter; +import android.util.Log; +import android.view.ViewGroup; +import android.widget.TextView; + +public class StringPresenter extends Presenter { + + private static final String TAG = "StringPresenter"; + + public ViewHolder onCreateViewHolder(ViewGroup parent) { + Log.d(TAG, "onCreateViewHolder"); + TextView tv = new TextView(parent.getContext()); + tv.setFocusable(true); + tv.setFocusableInTouchMode(true); + tv.setBackground(parent.getContext().getResources().getDrawable(R.drawable.icon_focused)); + return new ViewHolder(tv); + } + + public void onBindViewHolder(ViewHolder viewHolder, Object item) { + Log.d(TAG, "onBindViewHolder for " + item.toString()); + ((TextView) viewHolder.view).setText(item.toString()); + } + + public void onUnbindViewHolder(ViewHolder viewHolder) { + Log.d(TAG, "onUnbindViewHolder"); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java new file mode 100644 index 000000000..ad13be5f8 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; +import android.support.v4.graphics.drawable.RoundedBitmapDrawable; +import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; +import android.view.LayoutInflater; +import android.widget.ImageView; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +/** + * The Presenter displays a card consisting of text as a replacement for a big image. The footer is + * also quite unique since it does contain two images rather than one or non. + */ +public class TextCardPresenter extends AbstractCardPresenter { + + private static final String TAG = "AbstractFooterCardPresenter"; + + public TextCardPresenter(Context context) { + super(context); + } + + @Override protected BaseCardViewEx onCreateView() { + BaseCardViewEx cardView = new BaseCardViewEx(getContext()); + LayoutInflater.from(getContext()).inflate(R.layout.text_icon_card, cardView); + LayoutInflater.from(getContext()).inflate(R.layout.text_icon_card_footer, cardView); + return cardView; + } + + @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { + TextView extraText = cardView.getViewById(R.id.extra_text); + TextView primaryText = cardView.getViewById(R.id.primary_text); + ImageView footerIcon = cardView.getViewById(R.id.footer_icon); + final ImageView imageView = cardView.getViewById(R.id.main_image); + + extraText.setText(card.getExtraText()); + primaryText.setText(card.getTitle()); + if (card.getLocalImageResourceName() != null) { + int width = (int) getContext().getResources() + .getDimension(R.dimen.sidetext_image_card_width); + int height = (int) getContext().getResources() + .getDimension(R.dimen.sidetext_image_card_height); + int resourceId = card.getLocalImageResourceId(getContext()); + // TODO: hahnr@ load the image without Picasso + Picasso.with(getContext()).load(resourceId).resize(width, height).centerCrop() + .into(new Target() { + + @Override + public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { + RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory + .create(getContext().getResources(), bitmap); + drawable.setCornerRadius( + Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); + imageView.setImageDrawable(drawable); + } + + @Override public void onBitmapFailed(Drawable errorDrawable) { + } + + @Override public void onPrepareLoad(Drawable placeHolderDrawable) { + } + }); + } + footerIcon.setImageResource(R.drawable.stars_white); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java new file mode 100644 index 000000000..d11f4e8cf --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.views; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.ResourceCache; +import android.support.v17.leanback.widget.BaseCardView; +import android.view.View; + +/** + * This class is an extension for the BaseCardView which is focusable by default. This behavior has + * to be merged into the original BaseCardView at some point in the development. After merging those + * two classes, this one, the BaseCardViewEx, can be removed. + */ +public class BaseCardViewEx extends BaseCardView { + + protected Context mContext; + private ResourceCache mResourceCache = new ResourceCache(); + private OnActivateStateChangeHandler mActivationCallback; + + + public BaseCardViewEx(Context context) { + super(context); + mContext = context; + setCardType(BaseCardView.CARD_TYPE_INFO_UNDER); + + // TODO: @hahnr BaseCardView should be focusable by default. Merge! + setFocusable(true); + setFocusableInTouchMode(true); + } + + @Override public void setActivated(boolean activated) { + super.setActivated(activated); + if (mActivationCallback != null) + mActivationCallback.onActivateStateChanged(this, activated); + } + + public void setOnActivateStateChangeHandler(OnActivateStateChangeHandler handler) { + mActivationCallback = handler; + } + + public ViewType getViewById(int resId) { + return mResourceCache.getViewById(this, resId); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java new file mode 100644 index 000000000..9e8af546d --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.views; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.view.LayoutInflater; +import android.widget.ImageView; + +/** + * The FooterLayoutCardView creates a card view consisting of a big image followed by a footer + * passed as a layout resource. + */ +public class FooterLayoutCardView extends BaseCardViewEx { + + private final ImageView mImageView; + + /** + * The footer passed as a layout resource id will be inflated and added automatically to this + * view. + *

+ * Note: If you want your footer to expand/collapse when its parent row is + * activated/deactivated, you have to add the layout_viewType="info" property to + * your footers root view. + *

+ * Example footer layout: + *

{@code 
+     * 
+     *     
+     * }
+ * + * @param context The current context. + * @param layoutId The footers layout resource id. + * @param imageWidthInDp The width of the ImageView used in this card. The card's width always + * equals the image's width. + * @param imageHeightInDp The height of the ImageView used in this card. + * @see android.support.v17.leanback.widget.BaseCardView.LayoutParams + */ + public FooterLayoutCardView(Context context, int layoutId, int imageWidthInDp, + int imageHeightInDp) { + super(context); + setCardType(CARD_TYPE_INFO_UNDER); + setBackgroundColor(context.getResources().getColor(R.color.default_card_background_color)); + + LayoutInflater.from(context).inflate(R.layout.image_card, this); + mImageView = getViewById(R.id.image_card_view_main_image); + LayoutInflater.from(context).inflate(layoutId, this); + } + + public ImageView getImageView() { + return mImageView; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java new file mode 100644 index 000000000..c2a55fdee --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.views; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.ImageCardView; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +/** + * Leanback's {@link ImageCardView} will need some layout changes to fit all design requirements + * from the specs. This class is a temporary implementation of the "new" {@link ImageCardView} and + * will replace the existing one at some point in the development process. The original + * implementation also requires some refactoring to be more flexible in order to be used for various + * card types. + *

+ * Besides from the refactoring of the ImageCardView I suggest to change not only the BaseCardView + * but also to add at least one additional CardView, the "FooterLayoutCardView". More about this + * topic can be discussed later in the development process. + */ +public class ImageCardViewReplacement extends FooterLayoutCardView { + + public static final int PRIMARY_TEXTVIEW_ID = R.id.primary_text; + public static final int SECONDARY_TEXTVIEW_ID = R.id.secondary_text; + public static final int FOOTER_ICON_ID = R.id.footer_icon; + public static final int INFO_BOX_ID = R.id.info_field; + + public ImageCardViewReplacement(Context context, int widthInDp, int heightInDp) { + super(context, R.layout.image_card_footer, widthInDp, heightInDp); + setBackgroundColor(context.getResources().getColor(R.color.default_card_background_color)); + } + + public TextView getPrimaryTextView() { + return getViewById(PRIMARY_TEXTVIEW_ID); + } + + public TextView getSecondaryTextView() { + return getViewById(SECONDARY_TEXTVIEW_ID); + } + + public ImageView getIconView() { + return getViewById(FOOTER_ICON_ID); + } + + public View getInfoBoxView() { + return getViewById(INFO_BOX_ID); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java new file mode 100644 index 000000000..e444ef266 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards.views; + +public interface OnActivateStateChangeHandler { + + void onActivateStateChanged(BaseCardViewEx cardView, boolean activated); + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-v21/song_row_background_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-v21/song_row_background_focused.xml new file mode 100644 index 000000000..34e2bd74b --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-v21/song_row_background_focused.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_canyon.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_canyon.jpg new file mode 100644 index 000000000..0f7726175 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_canyon.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_sax.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_sax.jpg new file mode 100644 index 000000000..20fec8cac Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_sax.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_dummy_16_9_l.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_dummy_16_9_l.png new file mode 100644 index 000000000..6088150b3 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_dummy_16_9_l.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_01.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_01.png new file mode 100755 index 000000000..862f8d6fb Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_01.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_02.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_02.png new file mode 100755 index 000000000..e10e38387 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_02.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_03.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_03.png new file mode 100755 index 000000000..9e4ffac9f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_03.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_04.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_04.png new file mode 100755 index 000000000..4d0d25d1c Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_04.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_05.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_05.png new file mode 100755 index 000000000..436af8ee3 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_05.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_06.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_06.png new file mode 100755 index 000000000..ff05fadc5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_06.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_07.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_07.png new file mode 100755 index 000000000..38261b76a Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_07.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_08.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_08.png new file mode 100755 index 000000000..517467a4f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_08.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_09.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_09.png new file mode 100755 index 000000000..7c052cb23 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_09.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_01.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_01.jpg new file mode 100755 index 000000000..435b2be5f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_01.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_02.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_02.jpg new file mode 100755 index 000000000..ca2b0abab Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_02.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_03.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_03.jpg new file mode 100755 index 000000000..26016ddd9 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_03.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_04.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_04.jpg new file mode 100755 index 000000000..7c9ea0116 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_04.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_05.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_05.jpg new file mode 100755 index 000000000..8dbd701a1 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_05.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_06.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_06.jpg new file mode 100755 index 000000000..9e90c202c Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_06.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_07.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_07.jpg new file mode 100755 index 000000000..3b7d3913e Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_07.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_08.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_08.jpg new file mode 100755 index 000000000..c9c00d7d5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_08.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_09.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_09.jpg new file mode 100755 index 000000000..4223bc64f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_09.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_10.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_10.jpg new file mode 100755 index 000000000..322854619 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_10.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_11.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_11.jpg new file mode 100755 index 000000000..473954880 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_11.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_12.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_12.jpg new file mode 100755 index 000000000..734ba57c4 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_12.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_13.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_13.jpg new file mode 100755 index 000000000..a94a3c34d Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_13.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_action.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_action.png new file mode 100755 index 000000000..f3cb7afeb Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_action.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_animation.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_animation.png new file mode 100755 index 000000000..a1d9f40da Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_animation.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_classics.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_classics.png new file mode 100755 index 000000000..17c1580b1 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_classics.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_comedy.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_comedy.png new file mode 100755 index 000000000..5a23e6e20 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_comedy.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_crime.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_crime.png new file mode 100755 index 000000000..52450a6b5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_crime.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_documentary.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_documentary.png new file mode 100755 index 000000000..afb2b61d4 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_documentary.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_drama.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_drama.png new file mode 100755 index 000000000..79e1b571b Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_drama.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_01.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_01.png new file mode 100755 index 000000000..9fb73f75e Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_01.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_02.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_02.png new file mode 100755 index 000000000..9e0abfe51 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_02.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_03.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_03.png new file mode 100755 index 000000000..cd78b71e2 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_03.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_04.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_04.png new file mode 100755 index 000000000..bf7561c3a Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_04.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_05.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_05.png new file mode 100755 index 000000000..eae533875 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_05.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_06.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_06.png new file mode 100755 index 000000000..b1feda0f2 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_06.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_07.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_07.png new file mode 100755 index 000000000..0f7dd2136 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_07.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_08.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_08.png new file mode 100755 index 000000000..b9041372a Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_08.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_01.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_01.png new file mode 100755 index 000000000..b4757a857 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_01.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_02.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_02.png new file mode 100755 index 000000000..0d746d323 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_02.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_03.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_03.png new file mode 100755 index 000000000..ddde1ef0d Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_03.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_04.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_04.png new file mode 100755 index 000000000..ca09156fe Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_04.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_05.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_05.png new file mode 100755 index 000000000..8c4d7e6bc Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_05.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_06.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_06.png new file mode 100755 index 000000000..d81ad8c54 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_06.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_07.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_07.png new file mode 100755 index 000000000..a0f381daf Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_07.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_08.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_08.png new file mode 100755 index 000000000..c377d2705 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_08.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_09.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_09.png new file mode 100755 index 000000000..de5a20774 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_09.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_10.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_10.png new file mode 100755 index 000000000..958f47e86 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_10.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_11.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_11.png new file mode 100755 index 000000000..36a8007b4 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_11.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_12.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_12.png new file mode 100755 index 000000000..4d60e8efd Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_12.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_13.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_13.png new file mode 100755 index 000000000..b4a883763 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_13.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_14.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_14.png new file mode 100755 index 000000000..ae3d40b4f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_14.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_angry_bird_w.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_angry_bird_w.png new file mode 100755 index 000000000..09bc30327 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_angry_bird_w.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_badland_w.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_badland_w.png new file mode 100755 index 000000000..703a33ee3 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_badland_w.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_leos_fortune_w.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_leos_fortune_w.png new file mode 100755 index 000000000..badd00a77 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_leos_fortune_w.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_minion_rush_w.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_minion_rush_w.png new file mode 100755 index 000000000..e76631cb6 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_minion_rush_w.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_monument_valley_w.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_monument_valley_w.png new file mode 100755 index 000000000..740421952 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_monument_valley_w.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_cc.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_cc.png new file mode 100644 index 000000000..461539485 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_cc.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_installed.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_installed.png new file mode 100644 index 000000000..190f6bac5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_installed.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_apps.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_apps.png new file mode 100755 index 000000000..ed92603d7 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_apps.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_more.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_more.png new file mode 100755 index 000000000..530757674 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_more.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_parental_control.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_parental_control.png new file mode 100755 index 000000000..d541c6ac3 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_parental_control.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_settings.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_settings.png new file mode 100755 index 000000000..f2eaa459d Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_settings.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_time.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_time.png new file mode 100755 index 000000000..72899aea2 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_time.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_3_bar.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_3_bar.png new file mode 100755 index 000000000..f9abb6c59 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_3_bar.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_4_bar.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_4_bar.png new file mode 100755 index 000000000..dcd208884 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_4_bar.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_off.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_off.png new file mode 100644 index 000000000..cbee75a4f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_off.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_on_yellow.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_on_yellow.png new file mode 100644 index 000000000..28cd07a19 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_on_yellow.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/movie_poster_01.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/movie_poster_01.png new file mode 100644 index 000000000..e09af320f Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/movie_poster_01.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_red.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_red.png new file mode 100644 index 000000000..e4c6056da Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_red.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_white.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_white.png new file mode 100644 index 000000000..83e7c8b03 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_white.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_browse.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_browse.png new file mode 100755 index 000000000..374f35710 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_browse.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_cards.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_cards.png new file mode 100755 index 000000000..1ddadfab5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_cards.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_custom_01.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_custom_01.png new file mode 100755 index 000000000..f73b9b793 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_custom_01.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_detail.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_detail.png new file mode 100755 index 000000000..aa881b8eb Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_detail.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_dialog.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_dialog.png new file mode 100755 index 000000000..6508d080c Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_dialog.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_grid.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_grid.png new file mode 100755 index 000000000..686566f99 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_grid.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_music_consumption.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_music_consumption.png new file mode 100755 index 000000000..ffc653db5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_music_consumption.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_settings.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_settings.png new file mode 100755 index 000000000..8337b928e Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_settings.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_video_consumption.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_video_consumption.png new file mode 100755 index 000000000..a0a9d95c8 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_video_consumption.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_wizard.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_wizard.png new file mode 100755 index 000000000..4338d30e0 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_wizard.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/title_android_tv.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/title_android_tv.png new file mode 100644 index 000000000..8d1e24105 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/title_android_tv.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/app_icon_your_company.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/app_icon_your_company.png new file mode 100644 index 000000000..0a47b018c Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/app_icon_your_company.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room.jpg new file mode 100644 index 000000000..47e885179 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room_wide.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room_wide.jpg new file mode 100644 index 000000000..156d55cf6 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room_wide.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml new file mode 100644 index 000000000..eb126831c --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml new file mode 100644 index 000000000..c2f724c53 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml new file mode 100644 index 000000000..1140e80be --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml new file mode 100644 index 000000000..07b058990 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_01.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_01.png new file mode 100755 index 000000000..d5b2900f6 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_01.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_02.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_02.png new file mode 100755 index 000000000..ced0a7cd5 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_02.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_03.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_03.png new file mode 100755 index 000000000..276cacf05 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_03.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_04.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_04.png new file mode 100755 index 000000000..e90487d11 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_04.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_05.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_05.png new file mode 100755 index 000000000..f048ecb20 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_05.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_06.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_06.png new file mode 100755 index 000000000..f4d15ebfb Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_06.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_07.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_07.png new file mode 100755 index 000000000..7ac0af3b6 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_07.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_08.png b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_08.png new file mode 100755 index 000000000..e6fc51e61 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_08.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml new file mode 100644 index 000000000..4eb4fa823 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused_selector.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused_selector.xml new file mode 100644 index 000000000..386aa7d05 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml new file mode 100644 index 000000000..940efe702 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml new file mode 100644 index 000000000..880f9f0b1 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml new file mode 100644 index 000000000..7be6ec48b --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml new file mode 100644 index 000000000..2dd9d9fc3 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml new file mode 100644 index 000000000..dca2934de --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml new file mode 100644 index 000000000..4893247fa --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml new file mode 100644 index 000000000..4652b0b3e --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml new file mode 100644 index 000000000..43cbeacb2 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..b6cf93f7a --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,10 @@ + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml new file mode 100644 index 000000000..080adb14e --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml new file mode 100644 index 000000000..0343cb8bd --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view.xml new file mode 100644 index 000000000..3caaa2f97 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml new file mode 100644 index 000000000..c24c187b4 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml new file mode 100644 index 000000000..b1cc798e1 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml new file mode 100644 index 000000000..31c56360f --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml new file mode 100644 index 000000000..d8f86e783 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml new file mode 100644 index 000000000..aadc10525 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_track_list_header.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_track_list_header.xml new file mode 100644 index 000000000..41562674b --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_track_list_header.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml new file mode 100644 index 000000000..467672740 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml new file mode 100644 index 000000000..84ca560b3 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml new file mode 100644 index 000000000..a11ac68ab --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml new file mode 100644 index 000000000..717c63aaa --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml new file mode 100644 index 000000000..8a1286997 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_container.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_container.xml new file mode 100644 index 000000000..52b8a5ef5 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_container.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_item.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_item.xml new file mode 100644 index 000000000..32a967939 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_item.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-hdpi/ic_launcher.png b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..cde69bccc Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-mdpi/ic_launcher.png b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..c133a0cbd Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/app_banner_sample_app.png b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/app_banner_sample_app.png new file mode 100644 index 000000000..222c1e580 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/app_banner_sample_app.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..bfa42f0e7 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..324e72cdd Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json new file mode 100644 index 000000000..addc33ca4 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json @@ -0,0 +1,356 @@ +[ + { + "title": "Movie Collection", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Recommendations", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Featured Movies", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Categories", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Favorites", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Settings", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + } +] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json new file mode 100644 index 000000000..84184a2da --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json @@ -0,0 +1,559 @@ +[ + { + "title": "Standard", + "cards": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Two Line Title", + "cards": [ + { + "type": "THIN_RATING", + "title": "The Amazing Spuder-Man", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN_RATING", + "title": "American Psycho", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN_RATING", + "title": "Big Hero 6", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN_RATING", + "title": "Edge of Tomorrow", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN_RATING", + "title": "The Hobbit: The Desolation of Smaug", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN_RATING", + "title": "Interstellar", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN_RATING", + "title": "Jurassic Park", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN_RATING", + "title": "The Hunger Games: Mockingjay Part I", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN_RATING", + "title": "Planes", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Two Line Title + Icon", + "cards": [ + { + "type": "THIN_RATING", + "description": "$3.99", + "title": "The Amazing Spider-Man", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN_RATING", + "title": "American Psycho", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN_RATING", + "title": "Big Hero 6", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN_RATING", + "title": "Edge of Tomorrow", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN_RATING", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN_RATING", + "title": "Interstellar", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN_RATING", + "title": "Jurassic Park", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN_RATING", + "description": "$3.99", + "title": "The Hunger Games: Mockingjay Part I", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN_RATING", + "title": "Planes", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Standard Square", + "cards": [ + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#bf360C", + "localImageResource": "card_image_music_02" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#b93221", + "localImageResource": "card_image_music_13" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#311b92", + "localImageResource": "card_image_music_08" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#33691e", + "localImageResource": "card_image_music_05" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#37474f", + "localImageResource": "card_image_music_06" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#3e2723", + "localImageResource": "card_image_music_09" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#01579B", + "localImageResource": "card_image_music_11" + } + ] + }, + { + "title": "Side Info", + "cards": [ + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_02" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_13" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_08" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_05" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_06" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_09" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_11" + } + ] + }, + { + "title": "Wide (Games)", + "cards": [ + { + "type": "WIDE_SHORT", + "title": "Angry Birds", + "description": "Purchased", + "localImageResource": "game_angry_bird_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "WIDE_SHORT", + "title": "Badland", + "description": "Purchased", + "localImageResource": "game_badland_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "WIDE_SHORT", + "title": "Leo's Fortune", + "description": "Purchased", + "localImageResource": "game_leos_fortune_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "WIDE_SHORT", + "title": "Minion Rush", + "description": "Purchased", + "localImageResource": "game_minion_rush_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "WIDE_SHORT", + "title": "Monument Valley", + "description": "Purchased", + "localImageResource": "game_monument_valley_w", + "footerIconLocalImageResource": "ic_installed" + } + ] + }, + { + "title": "Wide (Videos)", + "cards": [ + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_01" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_02" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_03" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_04" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_05" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_06" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_07" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_08" + } + ] + }, + { + "title": "Text", + "cards": [ + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_01" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_02" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_03" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_04" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_05" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_06" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_07" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_08" + } + ] + }, + { + "title": "Launcher", + "cards": [ + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_01" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_02" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_03" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_04" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_05" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_06" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_07" + }, + { + "type": "SIDE_INFO_TEST_1", + "title": "Harry Potter", + "description": "$3.99", + "localImageResource": "coffee_and_tea_08" + } + ] + }, + { + "title": "Single Line", + "cards": [ + { + "type": "SQUARE", + "title": "Action & Adventure", + "footerColor": "#dd004e", + "localImageResource": "category_action" + }, + { + "type": "SQUARE", + "title": "Animation", + "footerColor": "#c51162", + "localImageResource": "category_animation" + }, + { + "type": "SQUARE", + "title": "Classics", + "footerColor": "#9c27b0", + "localImageResource": "category_classics" + }, + { + "type": "SQUARE", + "title": "Comedy", + "footerColor": "#cf4900", + "localImageResource": "category_comedy" + }, + { + "type": "SQUARE", + "title": "Crime", + "footerColor": "#3f51b5", + "localImageResource": "category_crime" + }, + { + "type": "SQUARE", + "title": "Documentary", + "footerColor": "#02639b", + "localImageResource": "category_documentary" + }, + { + "type": "SQUARE", + "title": "Drama", + "footerColor": "#2a56c6", + "localImageResource": "category_drama" + } + ] + }, + { + "title": "Icon", + "shadow": false, + "cards": [ + { + "type": "ICON", + "title": "Settings", + "localImageResource": "ic_settings_settings" + }, + { + "type": "ICON", + "title": "WiFi", + "localImageResource": "ic_settings_wifi_3_bar" + }, + { + "type": "ICON", + "title": "Parental Control", + "localImageResource": "ic_settings_parental_control" + }, + { + "type": "ICON", + "title": "Time", + "localImageResource": "ic_settings_time" + } + ] + } +] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json new file mode 100644 index 000000000..0f35a1536 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json @@ -0,0 +1,70 @@ +[ + { + "title": "", + "cards": [ + { + "id": 0, + "type": "DEFAULT", + "title": "Card Examples", + "localImageResource": "thumbnail_example_cards", + "description": "Showcase of various card design and layouts" + }, + { + "id": 1, + "type": "DEFAULT", + "title": "Browsing Examples", + "localImageResource": "thumbnail_example_browse", + "description": "Showcase of various card design and layouts" + }, + { + "id": 2, + "type": "DEFAULT", + "title": "Grid Examples", + "localImageResource": "thumbnail_example_grid", + "description": "Showcase of various card design and layouts" + }, + { + "id": 3, + "type": "DEFAULT", + "title": "Detail Examples", + "localImageResource": "thumbnail_example_detail", + "description": "Showcase of various card design and layouts" + }, + { + "id": 4, + "type": "DEFAULT", + "title": "Video consumption Examples", + "localImageResource": "thumbnail_example_video_consumption", + "description": "Showcase of various card design and layouts" + }, + { + "id": 5, + "type": "DEFAULT", + "title": "Music consumption Examples", + "localImageResource": "thumbnail_example_music_consumption", + "description": "Showcase of various card design and layouts" + }, + { + "id": 6, + "type": "DEFAULT", + "title": "Wizard Examples", + "localImageResource": "thumbnail_example_wizard", + "description": "Showcase of various card design and layouts" + }, + { + "id": 7, + "type": "DEFAULT", + "title": "Settings Examples", + "localImageResource": "thumbnail_example_settings", + "description": "Showcase of various card design and layouts" + }, + { + "id": 8, + "type": "DEFAULT", + "title": "Dialog Examples", + "localImageResource": "thumbnail_example_dialog", + "description": "Showcase of various card design and layouts" + } + ] + } +] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json new file mode 100644 index 000000000..b01a2d45e --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json @@ -0,0 +1,106 @@ +{ + "title": "A Summer in a Canyon", + "description": "Kate Douglas Smith Wiggin", + "year": 1914, + "text": "It was nine o’clock one sunny California morning, and Geoffrey Strong stood under the live-oak trees in Las Flores Cañon, with a pot of black paint in one hand and a huge brush in the other. He could have handled these implements to better purpose and with better grace had not his arms been firmly held by three laughing girls, who pulled not wisely, but too well. He was further incommoded by the presence of a small urchin who lay on the dusty ground beneath his feet, fastening an upward clutch on the legs of his trousers.\n\nThere were three large canvas tents directly in front of them, yet no one of these seemed to be the object of dissension, but rather a redwood board, some three feet in length, which was nailed on a tree near by. twitch of her cousin’s sleeve.", + "localImageResource": "movie_poster_01", + "price": "$9.99", + "characters": [ + { + "type": "CHARACTER", + "title": "Leonardo Di Caprio", + "localImageResource": "face_01" + }, + { + "type": "CHARACTER", + "title": "Gerald Butler", + "localImageResource": "face_08" + }, + { + "type": "CHARACTER", + "title": "Russle Crow", + "localImageResource": "face_02" + }, + { + "type": "CHARACTER", + "title": "Emma Stone", + "localImageResource": "face_03" + }, + { + "type": "CHARACTER", + "title": "Natalie Portman", + "localImageResource": "face_04" + }, + { + "type": "CHARACTER", + "title": "Jack Gyllanhall", + "localImageResource": "face_05" + }, + { + "type": "CHARACTER", + "title": "Ryan Gossling", + "localImageResource": "face_06" + }, + { + "type": "CHARACTER", + "title": "Olivia Wilde", + "localImageResource": "face_07" + } + ], + "recommended": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] +} \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/grid_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/grid_example.json new file mode 100644 index 000000000..56da5db02 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/grid_example.json @@ -0,0 +1,88 @@ +{ + "cards": [ + { + "type": "GRID_SQUARE", + "title": "Nüsse", + "description": "$3.99/lb", + "localImageResource": "food_01" + }, + { + "type": "GRID_SQUARE", + "title": "Undefinierbar", + "description": "$3.99/lb", + "localImageResource": "food_02" + }, + { + "type": "GRID_SQUARE", + "title": "Brocoli", + "description": "$3.99/lb", + "localImageResource": "food_03" + }, + { + "type": "GRID_SQUARE", + "title": "Salat", + "description": "$3.99/lb", + "localImageResource": "food_04" + }, + { + "type": "GRID_SQUARE", + "title": "Große Radischen", + "description": "$3.99/lb", + "localImageResource": "food_05" + }, + { + "type": "GRID_SQUARE", + "title": "Rote Zwiebeln", + "description": "$3.99/lb", + "localImageResource": "food_06" + }, + { + "type": "GRID_SQUARE", + "title": "Lauch", + "description": "$3.99/lb", + "localImageResource": "food_07" + }, + { + "type": "GRID_SQUARE", + "title": "Exotisches Zeugs", + "description": "$3.99/lb", + "localImageResource": "food_08" + }, + { + "type": "GRID_SQUARE", + "title": "Zitronen", + "description": "$3.99/lb", + "localImageResource": "food_09" + }, + { + "type": "GRID_SQUARE", + "title": "Meerirgendwas", + "description": "$3.99/lb", + "localImageResource": "food_10" + }, + { + "type": "GRID_SQUARE", + "title": "Irgendein Kohl", + "description": "$3.99/lb", + "localImageResource": "food_11" + }, + { + "type": "GRID_SQUARE", + "title": "Apfel", + "description": "$3.99/lb", + "localImageResource": "food_12" + }, + { + "type": "GRID_SQUARE", + "title": "Mehr Äpfel", + "description": "$3.99/lb", + "localImageResource": "food_13" + }, + { + "type": "GRID_SQUARE", + "title": "Tomaten", + "description": "$3.99/lb", + "localImageResource": "food_14" + } + ] +} \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 new file mode 100644 index 000000000..5fdde6280 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/music_consumption_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/music_consumption_example.json new file mode 100644 index 000000000..0da65c32d --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/music_consumption_example.json @@ -0,0 +1,76 @@ +{ + "songs": [ + { + "number": 1, + "duration": "2:54", + "title": "Blue Mood", + "description": "Duke Ellington & His Famous Orchestra", + "image": "card_image_music_01", + "file": "track_01" + }, + { + "number": 2, + "duration": "3:20", + "title": "I Saw Stars", + "description": "Patrick Et Son Orchestre De Danse", + "image": "card_image_music_02", + "file": "track_02" + }, + { + "number": 3, + "duration": "2:46", + "title": "Laura", + "description": "Dave Brubeck Trio", + "image": "card_image_music_03", + "file": "track_03" + }, + { + "number": 4, + "duration": "3:27", + "title": "September Song", + "description": "Dave Brubeck Trio", + "image": "card_image_music_07", + "file": "track_04" + }, + { + "number": 5, + "duration": "3:46", + "title": "Squeeze Me", + "description": "Dave Brubeck Trio", + "image": "card_image_music_08", + "file": "track_05" + }, + { + "number": 6, + "duration": "0:22", + "title": "Constellation", + "description": "Charlie Parker", + "image": "card_image_music_09", + "file": "track_06" + }, + { + "number": 7, + "duration": "2:54", + "title": "Satin Doll (1952)", + "description": "Duke Ellington & His Famous Orchestra", + "image": "card_image_music_10", + "file": "track_07" + }, + { + "number": 8, + "duration": "3:26", + "title": "Solitude", + "description": "Duke Ellington & His Famous Orchestra", + "image": "card_image_music_11", + "file": "track_08" + }, + { + "number": 9, + "duration": "3:10", + "title": "The Mooche", + "description": "Duke Ellington & His Famous Orchestra", + "image": "card_image_music_12", + "file": "track_09" + } + ] +} \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/music_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/music_example.json new file mode 100644 index 000000000..b01a2d45e --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/music_example.json @@ -0,0 +1,106 @@ +{ + "title": "A Summer in a Canyon", + "description": "Kate Douglas Smith Wiggin", + "year": 1914, + "text": "It was nine o’clock one sunny California morning, and Geoffrey Strong stood under the live-oak trees in Las Flores Cañon, with a pot of black paint in one hand and a huge brush in the other. He could have handled these implements to better purpose and with better grace had not his arms been firmly held by three laughing girls, who pulled not wisely, but too well. He was further incommoded by the presence of a small urchin who lay on the dusty ground beneath his feet, fastening an upward clutch on the legs of his trousers.\n\nThere were three large canvas tents directly in front of them, yet no one of these seemed to be the object of dissension, but rather a redwood board, some three feet in length, which was nailed on a tree near by. twitch of her cousin’s sleeve.", + "localImageResource": "movie_poster_01", + "price": "$9.99", + "characters": [ + { + "type": "CHARACTER", + "title": "Leonardo Di Caprio", + "localImageResource": "face_01" + }, + { + "type": "CHARACTER", + "title": "Gerald Butler", + "localImageResource": "face_08" + }, + { + "type": "CHARACTER", + "title": "Russle Crow", + "localImageResource": "face_02" + }, + { + "type": "CHARACTER", + "title": "Emma Stone", + "localImageResource": "face_03" + }, + { + "type": "CHARACTER", + "title": "Natalie Portman", + "localImageResource": "face_04" + }, + { + "type": "CHARACTER", + "title": "Jack Gyllanhall", + "localImageResource": "face_05" + }, + { + "type": "CHARACTER", + "title": "Ryan Gossling", + "localImageResource": "face_06" + }, + { + "type": "CHARACTER", + "title": "Olivia Wilde", + "localImageResource": "face_07" + } + ], + "recommended": [ + { + "type": "THIN", + "title": "The Amazing Spuder-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "THIN", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "THIN", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "THIN", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "THIN", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "THIN", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "THIN", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "THIN", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "THIN", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] +} \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_01.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_01.mp3 new file mode 100755 index 000000000..3b02d928c Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_01.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_02.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_02.mp3 new file mode 100755 index 000000000..11d01fdf0 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_02.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_03.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_03.mp3 new file mode 100755 index 000000000..3d05a0c85 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_03.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_04.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_04.mp3 new file mode 100755 index 000000000..c4d6dfb63 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_04.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_05.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_05.mp3 new file mode 100755 index 000000000..259831c0d Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_05.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_06.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_06.mp3 new file mode 100755 index 000000000..c984d4413 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_06.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_07.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_07.mp3 new file mode 100755 index 000000000..7ddf065ed Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_07.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_08.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_08.mp3 new file mode 100755 index 000000000..a035bc5f0 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_08.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_09.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_09.mp3 new file mode 100755 index 000000000..dd58c2096 Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_09.mp3 differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/wizard_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/wizard_example.json new file mode 100644 index 000000000..f46b85665 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/wizard_example.json @@ -0,0 +1,6 @@ +{ + "title": "Androidify! The Movie", + "breadcrump": "Android TV", + "price_hd": "$4.99", + "price_sd": "$2.99" +} \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml new file mode 100644 index 000000000..f4877e823 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml @@ -0,0 +1,36 @@ + + + + + + Everyone + Low maturity + Medium maturity + High maturity + + + everyone + low + medium + high + + + This description becomes visible only on focus. + This description becomes visible only on focus. + This description becomes visible only on focus. + This description becomes visible only on focus. + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..7984d7e6c --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml @@ -0,0 +1,29 @@ + + #FFFFFF + #DDDDDD + #06838f + #00796B + #ffaa3f + #FFEB3B + #FFEB3B + #222222 + #80D3FB + #00695C + + #3d3d3d + + #263238 + #37474F + #F0F + + #EEEEEE + #99EEEEEE + + #86c739 + + #222222 + + #04549D + #0374BF + #022A4E + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml new file mode 100644 index 000000000..d12d7900b --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml @@ -0,0 +1,32 @@ + + + 224dp + 126dp + + 120dp + 172dp + + 224dp + 109dp + + 144dp + 144dp + + 128dp + 128dp + + 96dp + 96dp + + 144dp + 144dp + + 224dp + 109dp + + 120dp + 120dp + + 200dp + 200dp + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..fab46b074 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml @@ -0,0 +1,73 @@ + + ShowcaseApp + + Related Videos + + Error + OK + Pause + Play + Stop + 00:00 + Play Pause Button + Loading… + No video was found + About DemoCast Player + Version: %1$s + Popular Videos + PREFERENCES + Grid View + Error Fragment + Personal Settings + Watch trailer + FREE + Rent By Day + From $1.99 + Buy and Own + AT $9.99 + Movie + shouldStart + startPosition + Search Results + + + Media loading timed out + Media server was not reachable + Failed to load video + An error occurred + Dismiss + Oops + Implement your own in-app search. + Card Examples + DetailView Example + Action clicked. Implement your own handler. + Grid Example + Buy + Add to wishlist + Related + Related Items + Recommended + + + Use Google\'s location service? + Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running. + Agree + Disagree + \'Agree\' clicked. + \'Disagree\' clicked. + + + Choose rent options + Watch in HD on supported devices + Watch in standard definition on the web and supported devices + Rental period: start within 30 days,\nfinish within 24 hours + Payment Method + \'Payment Method\' clicked. + Rent + Rent HD + Rent SD + Processinig... + Watch now + Later + \'Watch now\' clicked. + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..1ac8724f5 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml new file mode 100644 index 000000000..38244aac3 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml b/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml new file mode 100644 index 000000000..71cd5320d --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 8dd090f5147d73261011620a8c1e0eeb43accf3e Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Mon, 3 Aug 2015 12:36:31 -0700 Subject: Cleanup and usage of new ImageCardView The Showcase app now makes use of the new ImageCardView which is stylable through XML and uses less Views. Cleaned up DetailView. Cleaned up styles and layouts. Added Copyright notices. Change-Id: Ib37485d5b57be6a0f4b5321ac61b41a0808eaf35 --- .../app/src/main/AndroidManifest.xml | 3 + .../CardExampleFragment.java | 2 +- .../DetailViewExampleActivity.java | 54 ++ .../DetailViewExampleFragment.java | 45 +- .../DetailsDescriptionPresenter.java | 2 +- .../supportleanbackshowcase/MainFragment.java | 9 +- .../leanback/supportleanbackshowcase/Movie.java | 14 + .../supportleanbackshowcase/ResourceCache.java | 14 + .../SettingsExampleFragment.java | 14 + .../VideoConsumptionExampleFragment.java | 4 - .../WizardExample2ndStepFragment.java | 14 + .../WizardExample3rdStepFragment.java | 19 +- .../WizardExample4thStepFragment.java | 14 + .../cards/CharacterCardView.java | 70 +++ .../cards/TextCardView.java | 57 +++ .../supportleanbackshowcase/cards/models/Card.java | 9 +- .../cards/presenters/AbstractCardPresenter.java | 1 - .../presenters/AbstractFooterCardPresenter.java | 95 ---- .../cards/presenters/CardPresenterSelector.java | 104 ++-- .../cards/presenters/CharacterCardPresenter.java | 63 +-- .../cards/presenters/GameBannerCardPresenter.java | 44 -- .../cards/presenters/IconCardPresenter.java | 47 +- .../cards/presenters/ImageCardViewPresenter.java | 128 +---- .../cards/presenters/ImageCardViewPresenter1.java | 64 --- .../cards/presenters/LauncherCardPresenter.java | 97 ---- .../cards/presenters/MovieRatingCardPresenter.java | 42 -- .../cards/presenters/SideInfoCardPresenter.java | 46 +- .../cards/presenters/SingleLineCardPresenter.java | 34 +- .../cards/presenters/StringPresenter.java | 44 -- .../cards/presenters/TextCardPresenter.java | 63 +-- .../cards/views/BaseCardViewEx.java | 54 -- .../cards/views/FooterLayoutCardView.java | 70 --- .../cards/views/ImageCardViewReplacement.java | 63 --- .../cards/views/OnActivateStateChangeHandler.java | 17 - .../src/main/res/drawable/character_focused.xml | 21 +- .../main/res/drawable/character_not_focused.xml | 15 + .../res/drawable/character_not_focused_padding.xml | 15 + .../src/main/res/drawable/default_background.xml | 20 +- .../app/src/main/res/drawable/icon_focused.xml | 20 +- .../main/res/drawable/icon_focused_selector.xml | 5 - .../app/src/main/res/drawable/icon_not_focused.xml | 21 - .../app/src/main/res/drawable/overlay_black.xml | 15 + .../src/main/res/drawable/song_row_background.xml | 17 +- .../res/drawable/song_row_background_focused.xml | 15 + .../res/drawable/wizard_background_blackned.xml | 19 +- .../wizard_important_action_item_background.xml | 15 + ...rd_important_action_item_background_focused.xml | 15 + ...mportant_action_item_background_not_focused.xml | 15 + .../main/res/layout/activity_detail_example.xml | 25 + .../app/src/main/res/layout/activity_main.xml | 15 + .../main/res/layout/activity_settings_example.xml | 16 +- .../app/src/main/res/layout/character_card.xml | 17 +- .../app/src/main/res/layout/detail_view.xml | 82 --- .../src/main/res/layout/detail_view_content.xml | 96 ++++ .../app/src/main/res/layout/icon_card.xml | 22 - .../app/src/main/res/layout/icon_card_footer.xml | 20 - .../app/src/main/res/layout/image_card.xml | 9 - .../app/src/main/res/layout/image_card_footer.xml | 53 -- .../app/src/main/res/layout/row_song.xml | 15 + .../src/main/res/layout/row_track_list_header.xml | 15 + .../app/src/main/res/layout/side_info_card.xml | 21 +- .../main/res/layout/single_line_card_footer.xml | 33 -- .../app/src/main/res/layout/text_icon_card.xml | 92 +++- .../src/main/res/layout/text_icon_card_footer.xml | 56 --- .../src/main/res/layout/video_surface_fragment.xml | 16 +- .../app/src/main/res/raw/cards_card_example.json | 559 --------------------- .../app/src/main/res/raw/cards_example.json | 506 +++++++++++++++++++ .../app/src/main/res/raw/detail_example.json | 18 +- .../app/src/main/res/values/colors.xml | 15 + .../app/src/main/res/values/dims.xml | 18 +- .../app/src/main/res/values/strings.xml | 15 + .../app/src/main/res/values/styles.xml | 165 +++++- .../app/src/main/res/values/themes.xml | 20 +- 73 files changed, 1652 insertions(+), 1915 deletions(-) create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused_selector.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view_content.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_example.json (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index 71f1b7d28..c15f13513 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -39,6 +39,9 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java index b47caf172..4ece60db1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java @@ -70,7 +70,7 @@ public class CardExampleFragment extends BrowseFragment { private void createRows() { String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.cards_card_example)); + .inputStreamToString(getResources().openRawResource(R.raw.cards_example)); CardRow[] rows = new Gson().fromJson(json, CardRow[].class); for (CardRow row : rows) { mRowsAdapter.add(createCardRow(row)); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java new file mode 100644 index 000000000..e301f58f5 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase; + +import android.app.Activity; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.support.v17.leanback.app.DetailsFragment; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.DetailsOverviewRow; +import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.google.gson.Gson; + +/** + * Contains a {@link DetailsFragment} in order to display more details for a given card. + */ +public class DetailViewExampleActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java index 10ceceb38..543358707 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java @@ -38,39 +38,46 @@ import android.widget.Toast; import com.google.gson.Gson; /** - * Displays a card with more details. + * Displays a card with more details using a {@link DetailsFragment}. */ public class DetailViewExampleFragment extends DetailsFragment implements OnItemViewClickedListener, OnItemViewSelectedListener { - private static final String TAG = "DetailViewExampleFragment"; private ArrayObjectAdapter mRowsAdapter; - @Override public void onActivityCreated(Bundle savedInstanceState) { + @Override + public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setupUi(); setupEventListeners(); } private void setupUi() { + // Load the card we want to display from a JSON resource. This JSON data could come from + // anywhere in a real world app, e.g. a server. String json = Utils .inputStreamToString(getResources().openRawResource(R.raw.detail_example)); DetailedCard data = new Gson().fromJson(json, DetailedCard.class); + + // Setup fragment setTitle(getString(R.string.detail_view_title)); FullWidthDetailsOverviewRowPresenter rowPresenter = new FullWidthDetailsOverviewRowPresenter( new DetailsDescriptionPresenter(getActivity())) { - @Override protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { + + @Override + protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { + // Customize Actionbar and Content by using custom colors. RowPresenter.ViewHolder viewHolder = super.createRowViewHolder(parent); - // TODO: hahnr@ replace with API calls (they don't exist yet) - View actionsView = viewHolder.view.findViewById(R.id.details_overview_actions); - actionsView.setBackgroundColor(getActivity().getResources().getColor( - R.color.detail_view_actionbar_background)); + View actionsView = viewHolder.view. + findViewById(R.id.details_overview_actions_background); + actionsView.setBackgroundColor(getActivity().getResources(). + getColor(R.color.detail_view_actionbar_background, null)); View detailsView = viewHolder.view.findViewById(R.id.details_frame); detailsView.setBackgroundColor( - getActivity().getResources().getColor(R.color.detail_view_background)); + getResources().getColor(R.color.detail_view_background, null)); return viewHolder; } }; @@ -112,26 +119,30 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem } private void setupEventListeners() { - // FIXME: leanbackteam@ The item & itemViewHolder parameters in onItemSelected are null in the DetailsOverviewRow as long as the user navigates top or down. After navigating left or right it will be the actual item rather than null. setOnItemViewSelectedListener(this); setOnItemViewClickedListener(this); } - @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { + @Override + public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { if (!(item instanceof Action)) return; Action action = (Action) item; if (action.getId() == 3) { setSelectedPosition(1); - } else Toast.makeText(getActivity(), getString(R.string.action_cicked), Toast.LENGTH_LONG) + } else { + Toast.makeText(getActivity(), getString(R.string.action_cicked), Toast.LENGTH_LONG) .show(); + } } - @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { + @Override + public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { if (mRowsAdapter.indexOf(row) > 0) { - getView().setBackgroundColor( - getResources().getColor(R.color.detail_view_related_background)); + int backgroundColor = getResources().getColor(R.color.detail_view_related_background, + null); + getView().setBackgroundColor(backgroundColor); } else { getView().setBackgroundResource(R.drawable.background_canyon); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java index 678b3d578..ebb5c53e6 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java @@ -36,7 +36,7 @@ public class DetailsDescriptionPresenter extends Presenter { } @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { - View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view, null); + View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view_content, null); return new ViewHolder(view); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java index 3522d0b45..6486a10b6 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java @@ -178,12 +178,9 @@ public class MainFragment extends BrowseFragment { break; } case 3: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_canyon, null)); - Fragment fragment = new DetailViewExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); + Intent intent = new Intent(getActivity().getBaseContext(), + DetailViewExampleActivity.class); + startActivity(intent); break; } case 4: { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java index 3fc9d6955..4d590aebd 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java @@ -1,3 +1,17 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package android.support.v17.leanback.supportleanbackshowcase; import com.google.gson.annotations.SerializedName; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java index bee5cbbec..c7c858939 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java @@ -1,3 +1,17 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package android.support.v17.leanback.supportleanbackshowcase; import android.util.SparseArray; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java index fef91b108..44930f2b4 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java @@ -1,3 +1,17 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package android.support.v17.leanback.supportleanbackshowcase; import android.app.Fragment; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java index 058f759fa..29e82a875 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java @@ -34,13 +34,11 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp OnItemViewClickedListener, MediaPlayerGlue.OnMediaFileFinishedPlayingListener { private static final String URL = "http://techslides.com/demos/sample-videos/small.mp4"; - private static final String TAG = "VideoConsumptionExampleFragment"; private ArrayObjectAdapter mRowsAdapter; private MediaPlayerGlue mGlue; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreate"); mGlue = new VideoMediaPlayerGlue(getActivity(), this) { @@ -61,7 +59,6 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp SurfaceView surface = (SurfaceView) videoSurfaceFragment.getView(); surface.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { - Log.d(TAG, "surfaceCreated(SurfaceHolder)"); mGlue.setDisplay(holder); } @@ -71,7 +68,6 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp } @Override public void surfaceDestroyed(SurfaceHolder holder) { - Log.d(TAG, "surfaceDestroyed(SurfaceHolder)"); } }); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java index 4d54a6a7e..ea532880b 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java @@ -1,3 +1,17 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package android.support.v17.leanback.supportleanbackshowcase; import android.graphics.Color; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java index 4838301fb..fccf7c9ee 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java @@ -1,7 +1,19 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package android.support.v17.leanback.supportleanbackshowcase; -import android.graphics.Color; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; @@ -9,11 +21,8 @@ import android.support.v17.leanback.app.GuidedStepFragment; import android.support.v17.leanback.widget.GuidanceStylist; import android.support.v17.leanback.widget.GuidedAction; import android.support.v17.leanback.widget.GuidedActionsStylist; -import android.util.Log; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; /** * TODO: JavaDoc diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java index 623de26ca..82a8a3d65 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java @@ -1,3 +1,17 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package android.support.v17.leanback.supportleanbackshowcase; import android.os.Bundle; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java new file mode 100644 index 000000000..311f88518 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.widget.BaseCardView; +import android.support.v4.graphics.drawable.RoundedBitmapDrawable; +import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +public class CharacterCardView extends BaseCardView { + + public CharacterCardView(Context context) { + super(context); + LayoutInflater.from(getContext()).inflate(R.layout.character_card, this); + setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + ImageView mainImage = (ImageView) findViewById(R.id.main_image); + View container = findViewById(R.id.container); + if (hasFocus) { + container.setBackgroundResource(R.drawable.character_focused); + mainImage.setBackgroundResource(R.drawable.character_focused); + } else { + container.setBackgroundResource(R.drawable.character_not_focused_padding); + mainImage.setBackgroundResource(R.drawable.character_not_focused); + } + } + }); + setFocusable(true); + } + + public void updateUi(Card card) { + TextView primaryText = (TextView) findViewById(R.id.primary_text); + final ImageView imageView = (ImageView) findViewById(R.id.main_image); + + primaryText.setText(card.getTitle()); + if (card.getLocalImageResourceName() != null) { + int resourceId = card.getLocalImageResourceId(getContext()); + Bitmap bitmap = BitmapFactory + .decodeResource(getContext().getResources(), resourceId); + RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getContext().getResources(), bitmap); + drawable.setAntiAlias(true); + drawable.setCornerRadius(Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); + imageView.setImageDrawable(drawable); + } + } + + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java new file mode 100644 index 000000000..4f661e098 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.cards; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.widget.BaseCardView; +import android.support.v4.graphics.drawable.RoundedBitmapDrawable; +import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; +import android.view.LayoutInflater; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +public class TextCardView extends BaseCardView { + + public TextCardView(Context context) { + super(context); + LayoutInflater.from(getContext()).inflate(R.layout.text_icon_card, this); + setFocusable(true); + } + + public void updateUi(Card card) { + TextView extraText = (TextView) findViewById(R.id.extra_text); + TextView primaryText = (TextView) findViewById(R.id.primary_text); + final ImageView imageView = (ImageView) findViewById(R.id.main_image); + + extraText.setText(card.getExtraText()); + primaryText.setText(card.getTitle()); + + // Create a rounded drawable. + int resourceId = card.getLocalImageResourceId(getContext()); + Bitmap bitmap = BitmapFactory + .decodeResource(getContext().getResources(), resourceId); + RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getContext().getResources(), bitmap); + drawable.setAntiAlias(true); + drawable.setCornerRadius( + Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); + imageView.setImageDrawable(drawable); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java index c0b79c7e0..79f951938 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java @@ -109,12 +109,13 @@ public class Card { public enum Type { - THIN, - THIN_RATING, + MOVIE_COMPLETE, + MOVIE, + MOVIE_BASE, ICON, SQUARE_BIG, - SQUARE, - WIDE_SHORT, + SINGLE_LINE, + GAME, SQUARE_SMALL, DEFAULT, SIDE_INFO, diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java index 574968c07..b81f119ed 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java @@ -15,7 +15,6 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; import android.support.v17.leanback.widget.BaseCardView; import android.support.v17.leanback.widget.Presenter; import android.view.ViewGroup; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java deleted file mode 100644 index adfda2407..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractFooterCardPresenter.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; - -import android.content.Context; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.Utils; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.FooterLayoutCardView; -import android.support.v17.leanback.widget.Presenter; -import android.view.ViewGroup; -import android.widget.ImageView; - -import com.squareup.picasso.Picasso; - -/** - * A custom and abstract card {@link Presenter} which allows to create a card consisting of an image - * and a custom footer. The footer is passed as a layout and will be inflated automatically. - */ -public abstract class AbstractFooterCardPresenter extends - AbstractCardPresenter { - - private static final String TAG = "AbstractFooterCardPresenter"; - private final Drawable mLoadingErrorDrawable; - private final int mFooterLayoutd; - private final int mImageWidth; - private final int mImageHeight; - - /** - * @param context Used to retrieve default values such as error drawables. - * @param footerLayoutId The layout which represents the footer. - * @param imageWidth The width of the card's main image. This width defines the card's width - * too. - * @param imageHeight The height of the card's main image. The card's height will be - * imageHeight + footerHeight - */ - public AbstractFooterCardPresenter(Context context, int footerLayoutId, int imageWidth, - int imageHeight) { - super(context); - mFooterLayoutd = footerLayoutId; - mImageWidth = imageWidth; - mImageHeight = imageHeight; - - // In case the image could not be fetched from the server we want to make sure something is show. In this case, a solid color. - int color = context.getResources().getColor(R.color.loading_error_card_background); - mLoadingErrorDrawable = new ColorDrawable(color); - } - - @Override public final FooterLayoutCardView onCreateView() { - FooterLayoutCardView cardView = new FooterLayoutCardView(getContext(), mFooterLayoutd, - mImageWidth, mImageHeight); - onViewCreated(cardView); - return cardView; - } - - @Override public void onBindViewHolder(Card card, FooterLayoutCardView cardView) { - // Load the card's image. This can be either an image on a remote server or a local one stored in the resources. - ImageView imageView = cardView.getImageView(); - if (card.getImageURI() != null) { - Utils.loadImageFromUri(getContext(), card.getImageURI(), imageView, mImageWidth, - mImageHeight, true, mLoadingErrorDrawable); - } else if (card.getLocalImageResourceName() != null) { - int resourceId = getContext().getResources() - .getIdentifier(card.getLocalImageResourceName(), - "drawable", getContext().getPackageName()); - Picasso.with(getContext()).load(resourceId).resize(mImageWidth, mImageHeight) - .centerCrop().into(imageView); - } - } - - /** - * Override this method to react to creations of new card views. - * - * @param cardView The view which has been created. - * @see Presenter#onCreateViewHolder(ViewGroup) - */ - public void onViewCreated(FooterLayoutCardView cardView) { - // Nothing to clean up. Override if necessary. - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java index 491fb2f72..53d462069 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java @@ -25,9 +25,6 @@ import java.util.HashMap; /** * This PresenterSelector will decide what Presenter to use depending on a given card's type. - *

- * TODO: leanbackteam@ Discuss whether leanback's PresenterSelector should be renamed to - * AbstractPresenterSelector. */ public class CardPresenterSelector extends PresenterSelector { @@ -38,68 +35,55 @@ public class CardPresenterSelector extends PresenterSelector { mContext = context; } - @Override public Presenter getPresenter(Object item) { + @Override + public Presenter getPresenter(Object item) { if (!(item instanceof Card)) throw new RuntimeException( String.format("The PresenterSelector only supports data items of type '%s'", - Card.class.getName())); + Card.class.getName())); Card card = (Card) item; Presenter presenter = presenters.get(card.getType()); - if (presenter == null) switch (card.getType()) { - case SQUARE: - presenter = new SingleLineCardPresenter(mContext); - break; - case THIN_RATING: - presenter = new MovieRatingCardPresenter(mContext); - break; - case SIDE_INFO: - presenter = new SideInfoCardPresenter(mContext); - break; - case SIDE_INFO_TEST_1: - presenter = new LauncherCardPresenter(mContext); - break; - case TEXT: - presenter = new TextCardPresenter(mContext); - break; - case ICON: - presenter = new IconCardPresenter(mContext); - break; - case CHARACTER: - presenter = new CharacterCardPresenter(mContext); - break; - case THIN: { - int width = (int) mContext.getResources() - .getDimension(R.dimen.thin_image_card_width); - int height = (int) mContext.getResources() - .getDimension(R.dimen.thin_image_card_height); - presenter = new ImageCardViewPresenter1(mContext, width, height); + if (presenter == null) { + switch (card.getType()) { + case SINGLE_LINE: + presenter = new SingleLineCardPresenter(mContext); + break; + case MOVIE: + case MOVIE_BASE: + case MOVIE_COMPLETE: + case SQUARE_BIG: + case GRID_SQUARE: + case GAME: { + int style = R.style.MovieCardSimpleStyle; + if (card.getType() == Card.Type.MOVIE_BASE) { + style = R.style.MovieCardBasicStyle; + } else if (card.getType() == Card.Type.MOVIE_COMPLETE) { + style = R.style.MovieCardCompleteStyle; + } else if (card.getType() == Card.Type.SQUARE_BIG) { + style = R.style.SquareBigCard; + } else if (card.getType() == Card.Type.GRID_SQUARE) { + style = R.style.GridCardStyle; + } else if (card.getType() == Card.Type.GAME) { + style = R.style.GameCardStyle; + } + presenter = new ImageCardViewPresenter(mContext, style); + break; + } + case SIDE_INFO: + presenter = new SideInfoCardPresenter(mContext); + break; + case TEXT: + presenter = new TextCardPresenter(mContext); + break; + case ICON: + presenter = new IconCardPresenter(mContext); + break; + case CHARACTER: + presenter = new CharacterCardPresenter(mContext); + break; + default: + presenter = new ImageCardViewPresenter(mContext); + break; } - break; - case SQUARE_BIG: { - int width = (int) mContext.getResources() - .getDimension(R.dimen.big_square_image_card_width); - int height = (int) mContext.getResources() - .getDimension(R.dimen.big_square_image_card_height); - presenter = new ImageCardViewPresenter(mContext, width, height); - } - break; - case GRID_SQUARE: { - int width = (int) mContext.getResources().getDimension(R.dimen.grid_card_width); - int height = (int) mContext.getResources().getDimension(R.dimen.grid_card_height); - presenter = new ImageCardViewPresenter(mContext, width, height); - } - break; - case WIDE_SHORT: { - presenter = new GameBannerCardPresenter(mContext); - } - break; - default: { - int width = (int) mContext.getResources() - .getDimension(R.dimen.default_image_card_width); - int height = (int) mContext.getResources() - .getDimension(R.dimen.default_image_card_height); - presenter = new ImageCardViewPresenter(mContext, width, height); - } - break; } presenters.put(card.getType(), presenter); return presenter; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java index 5514674cb..60fa5b2aa 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java @@ -15,73 +15,26 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.support.v17.leanback.supportleanbackshowcase.Constants; -import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.CharacterCardView; import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; -import android.support.v4.graphics.drawable.RoundedBitmapDrawable; -import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; -import android.util.Log; -import android.util.SparseArray; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; /** * This Presenter is used to display the characters card row in the DetailView examples. */ -public class CharacterCardPresenter extends AbstractCardPresenter { - - private static final String TAG = "CharacterCardPresenter"; - private final SparseArray mImageCache = new SparseArray(); +public class CharacterCardPresenter extends AbstractCardPresenter { public CharacterCardPresenter(Context context) { super(context); } - @Override protected BaseCardViewEx onCreateView() { - final BaseCardViewEx cardView = new BaseCardViewEx(getContext()); - LayoutInflater.from(getContext()).inflate(R.layout.character_card, cardView); - cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override public void onFocusChange(View v, boolean hasFocus) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onFocusChanged(" + hasFocus + ")"); - ImageView mainImage = cardView.getViewById(R.id.main_image); - View container = cardView.getViewById(R.id.container); - if (hasFocus) { - container.setBackgroundResource(R.drawable.character_focused); - mainImage.setBackgroundResource(R.drawable.character_focused); - } else { - container.setBackgroundResource(R.drawable.character_not_focused_padding); - mainImage.setBackgroundResource(R.drawable.character_not_focused); - } - } - }); - return cardView; + @Override + protected CharacterCardView onCreateView() { + return new CharacterCardView(getContext()); } - @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onBindViewHolder"); - TextView primaryText = cardView.getViewById(R.id.primary_text); - final ImageView imageView = cardView.getViewById(R.id.main_image); - - primaryText.setText(card.getTitle()); - if (card.getLocalImageResourceName() != null) { - int resourceId = card.getLocalImageResourceId(getContext()); - RoundedBitmapDrawable drawable = mImageCache.get(resourceId, null); - if (drawable == null) { - Bitmap bitmap = BitmapFactory - .decodeResource(getContext().getResources(), resourceId); - drawable = RoundedBitmapDrawableFactory.create(getContext().getResources(), bitmap); - drawable.setAntiAlias(true); - drawable.setCornerRadius(Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); - mImageCache.put(resourceId, drawable); - } - imageView.setImageDrawable(drawable); - if (Constants.LOCAL_LOGD) Log.d(TAG, "Round image created and set."); - } + @Override + public void onBindViewHolder(Card card, CharacterCardView cardView) { + cardView.updateUi(card); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java deleted file mode 100644 index d6e3d0e26..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/GameBannerCardPresenter.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; - -import android.content.Context; -import android.graphics.Color; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; -import android.widget.TextView; - -/** - * This presenter will display the cards representing a gamer banners. It inherits from {@link - * ImageCardViewPresenter} and will set a footer icon as well as a secondary text color. - */ -public class GameBannerCardPresenter extends ImageCardViewPresenter { - - private static final String TAG = "GameBannerCardPresenter"; - - public GameBannerCardPresenter(Context context) { - super(context, - (int) context.getResources().getDimension(R.dimen.wide_short_image_card_width), - (int) context.getResources().getDimension(R.dimen.wide_short_image_card_height)); - } - - @Override protected ImageCardViewReplacement onCreateView() { - ImageCardViewReplacement cardView = super.onCreateView(); - TextView secondaryText = cardView.getSecondaryTextView(); - secondaryText.setTextColor(Color.parseColor("#80c349")); - return cardView; - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java index 0154743db..bf5be70f4 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java @@ -16,51 +16,36 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; -import android.view.LayoutInflater; +import android.support.v17.leanback.widget.ImageCardView; import android.view.View; import android.widget.ImageView; -import android.widget.TextView; - -import com.squareup.picasso.Picasso; /** * This Presenter will display cards which consists of a single icon which will be highlighted by a * surrounding circle when the card is focused. AndroidTV uses these cards for entering settings * menu. */ -public class IconCardPresenter extends AbstractCardPresenter { - - private static final String TAG = "IconCardPresenter"; +public class IconCardPresenter extends ImageCardViewPresenter { public IconCardPresenter(Context context) { - super(context); + super(context, R.style.IconCardStyle); } - @Override protected BaseCardViewEx onCreateView() { - final BaseCardViewEx cardView = new BaseCardViewEx(getContext()); - LayoutInflater.from(getContext()).inflate(R.layout.icon_card, cardView); - LayoutInflater.from(getContext()).inflate(R.layout.icon_card_footer, cardView); - cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) cardView.getViewById(R.id.container) - .setBackgroundResource(R.drawable.icon_focused); - else cardView.getViewById(R.id.container).setBackground(null); + @Override + protected ImageCardView onCreateView() { + final ImageCardView imageCardView = super.onCreateView(); + final ImageView image = imageCardView.getMainImageView(); + imageCardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + image.setBackgroundResource(R.drawable.icon_focused); + } else { + image.setBackground(null); + } } }); - return cardView; - } - - @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { - TextView primaryText = cardView.getViewById(R.id.primary_text); - ImageView imageView = cardView.getViewById(R.id.main_image); - - primaryText.setText(card.getTitle()); - if (card.getLocalImageResourceName() != null) { - int resourceId = card.getLocalImageResourceId(getContext()); - Picasso.with(getContext()).load(resourceId).into(imageView); - } + return imageCardView; } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java index f467dad70..bf03753e8 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java @@ -15,127 +15,45 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.support.v17.leanback.supportleanbackshowcase.Constants; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.Utils; import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; -import android.util.Log; -import android.view.View; - -import com.squareup.picasso.Picasso; - -import java.util.HashMap; +import android.support.v17.leanback.widget.ImageCardView; /** - * A ImageCardViewPresenter is used to generate Views and bind Objects to them on demand. It - * contains an {@link ImageCardViewReplacement}. + * A very basic {@link ImageCardView} {@link android.support.v17.leanback.widget.Presenter}.You can + * pass a custom style for the ImageCardView in the constructor. Use the default constructor to + * create a Presenter with a default ImageCardView style. */ -public class ImageCardViewPresenter extends AbstractCardPresenter { +public class ImageCardViewPresenter extends AbstractCardPresenter { - private static final String TAG = "ImageCardViewPresenter"; - private final int mImageWidthInDp; - private final int mImageHeightDp; - private final Drawable mLoadingErrorDrawable; - private final HashMap mSelectedColors = new HashMap(); - private int mDefaultFooterColor; + private final int mCardStyleResId; - public ImageCardViewPresenter(Context context, int imageWidthInDp, int imageHeightInDp) { + public ImageCardViewPresenter(Context context, int cardStyleResId) { super(context); - int color = context.getResources().getColor(R.color.loading_error_card_background); - mLoadingErrorDrawable = new ColorDrawable(color); + mCardStyleResId = cardStyleResId; + } - mDefaultFooterColor = context.getResources() - .getColor(R.color.default_card_footer_background_color); - mImageWidthInDp = imageWidthInDp; - mImageHeightDp = imageHeightInDp; + public ImageCardViewPresenter(Context context) { + super(context); + mCardStyleResId = R.style.DefaultCardStyle; } - @Override protected ImageCardViewReplacement onCreateView() { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreateView()"); - final ImageCardViewReplacement cardView = new ImageCardViewReplacement(getContext(), - mImageWidthInDp, - mImageHeightDp); - cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override public void onFocusChange(View v, boolean hasFocus) { - udateCardUi(cardView); - } - }); - return cardView; + @Override + protected ImageCardView onCreateView() { + return new ImageCardView(getContext(), mCardStyleResId); } - @Override public void onBindViewHolder(Card card, ImageCardViewReplacement cardView) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onBindViewHolder(Card,ImageCardViewReplacement)"); + @Override + public void onBindViewHolder(Card card, final ImageCardView cardView) { cardView.setTag(card); - - // Display description iff there is one. - if (card.getDescription() == null || card.getDescription().length() == 0) { - cardView.getSecondaryTextView().setVisibility(View.GONE); - cardView.getPrimaryTextView().setLines(2); - cardView.getPrimaryTextView().setMaxLines(2); - } else { - cardView.getPrimaryTextView().setLines(1); - cardView.getPrimaryTextView().setMaxLines(1); - cardView.getSecondaryTextView().setText(card.getDescription()); - cardView.getSecondaryTextView().setVisibility(View.VISIBLE); - } - - // Display title iff there is one. - if (card.getTitle() == null || card.getTitle().length() == 0) { - cardView.getPrimaryTextView().setVisibility(View.GONE); - cardView.getSecondaryTextView().setLines(2); - cardView.getSecondaryTextView().setMaxLines(2); - } else { - cardView.getSecondaryTextView().setLines(1); - cardView.getSecondaryTextView().setMaxLines(1); - cardView.getPrimaryTextView().setText(card.getTitle()); - cardView.getPrimaryTextView().setVisibility(View.VISIBLE); - } - // Load main image from an URI or a local resource. - if (card.getImageURI() != null) { - Utils.loadImageFromUri(getContext(), card.getImageURI(), cardView.getImageView(), - mImageWidthInDp, mImageHeightDp, true, mLoadingErrorDrawable); - } else if (card.getLocalImageResourceName() != null) { + cardView.setTitleText(card.getTitle()); + cardView.setContentText(card.getDescription()); + if (card.getLocalImageResourceName() != null) { int resourceId = getContext().getResources() - .getIdentifier(card.getLocalImageResourceName(), - "drawable", getContext().getPackageName()); - Picasso.with(getContext()).load(resourceId).resize(mImageWidthInDp, mImageHeightDp) - .centerCrop().into(cardView.getImageView()); + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); + cardView.getMainImageView().setImageResource(resourceId); } - - // Load footer icon from a local resource or hide it. - cardView.getViewById(R.id.container).setVisibility(View.VISIBLE); - if (card.getFooterLocalImageResourceName() != null) { - int resourceId = getContext().getResources() - .getIdentifier(card.getFooterLocalImageResourceName(), - "drawable", getContext().getPackageName()); - Picasso.with(getContext()).load(resourceId).into(cardView.getIconView()); - cardView.getIconView().setVisibility(View.VISIBLE); - } else { - if (card.getDescription() == null || card.getDescription().isEmpty()) { - cardView.getViewById(R.id.container).setVisibility(View.GONE); - } - cardView.getIconView().setVisibility(View.GONE); - } - - // Update background color depending on the card's focused state. - udateCardUi(cardView); } - private void udateCardUi(ImageCardViewReplacement view) { - int color = mDefaultFooterColor; - - if (view.getTag() != null) { - Card card = (Card) view.getTag(); - if (card.getSelectedColor() != -1 && view.isSelected()) { - color = card.getSelectedColor(); - } - if (card.getFooterColor() != -1) { - color = card.getFooterColor(); - } - } - view.getInfoBoxView().setBackgroundColor(color); - } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java deleted file mode 100644 index bd5712c69..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter1.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.Constants; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; -import android.support.v17.leanback.widget.ImageCardView; -import android.util.Log; - -/** - * A ImageCardViewPresenter is used to generate Views and bind Objects to them on demand. It - * contains an {@link ImageCardViewReplacement}. - */ -public class ImageCardViewPresenter1 extends AbstractCardPresenter { - - private static final String TAG = "ImageCardViewPresenter"; - private final int mImageWidthInDp; - private final int mImageHeightDp; - - public ImageCardViewPresenter1(Context context, int imageWidthInDp, int imageHeightInDp) { - super(context); - mImageWidthInDp = imageWidthInDp; - mImageHeightDp = imageHeightInDp; - } - - @Override protected ImageCardView onCreateView() { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreateView()"); - - final ImageCardView cardView = new ImageCardView(getContext(), R.style.ImageCardViewColoredTextStyle); - cardView.setMainImageDimensions(mImageWidthInDp, mImageHeightDp); - cardView.setFocusable(true); - return cardView; - } - - @Override public void onBindViewHolder(Card card, final ImageCardView cardView) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onBindViewHolder(Card,ImageCardViewReplacement)"); - cardView.setTag(card); - cardView.setTitleText(card.getTitle()); - //cardView.setContentText("Hello"); - if (card.getLocalImageResourceName() != null) { - int resourceId = getContext().getResources() - .getIdentifier(card.getLocalImageResourceName(), - "drawable", getContext().getPackageName()); - cardView.getMainImageView().setImageResource(resourceId); - } - - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java deleted file mode 100644 index 894232125..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/LauncherCardPresenter.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; - -import android.animation.ValueAnimator; -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.Utils; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.widget.ImageView; - -import com.squareup.picasso.Picasso; - -/** - * THis Presenter displays an expandable card which is used e.g. in the AndroidTV launcher. Once - * such a card gets focused it expands and will show more details of the image. - */ -public class LauncherCardPresenter extends ImageCardViewPresenter { - - private static final String TAG = "LauncherCardPresenter"; - - public LauncherCardPresenter(Context context) { - super(context, 1 /* val > 0 required by Picasso */, - (int) context.getResources().getDimension(R.dimen.default_image_card_height)); - } - - @Override protected ImageCardViewReplacement onCreateView() { - ImageCardViewReplacement cardView = super.onCreateView(); - final ImageView imageView = cardView.getImageView(); - imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); - cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override public void onFocusChange(View v, final boolean hasFocus) { - int expandedWidth = (int) getContext().getResources().getDimension( - R.dimen.default_image_card_width); - int collapsedWidth = (int) getContext().getResources().getDimension( - R.dimen.default_image_card_height); - - expandedWidth = collapsedWidth; - - ValueAnimator animator = new ValueAnimator(); - animator.setInterpolator(new AccelerateDecelerateInterpolator()); - animator.setIntValues(hasFocus ? collapsedWidth : expandedWidth, - hasFocus ? expandedWidth : collapsedWidth); - animator.setDuration(500); - animator.setStartDelay(0); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override public void onAnimationUpdate(ValueAnimator animation) { - ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams(); - layoutParams.width = (Integer) animation.getAnimatedValue(); - imageView.setLayoutParams(layoutParams); - } - }); - animator.start(); - } - }); - return cardView; - } - - @Override public void onBindViewHolder(Card card, ImageCardViewReplacement cardView) { - super.onBindViewHolder(card, cardView); - - ImageView imageView = cardView.getImageView(); - cardView.setTag(card); - int width = (int) getContext().getResources() - .getDimension(R.dimen.default_image_card_height); - ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams(); - layoutParams.width = Utils.convertDpToPixel(getContext(), width); - imageView.setLayoutParams(layoutParams); - - - if (card.getLocalImageResourceName() != null) { - int height = (int) getContext().getResources() - .getDimension(R.dimen.sidetext_image_card_height); - int resourceId = getContext().getResources() - .getIdentifier(card.getLocalImageResourceName(), - "drawable", getContext().getPackageName()); - Picasso.with(getContext()).load(resourceId).into(imageView); - } - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java deleted file mode 100644 index e3b2c7e3a..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/MovieRatingCardPresenter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.ImageCardViewReplacement; -import android.view.Gravity; - -/** - * This Presenter inherits from ImageCardViewPresenter and will set the secondary text alignment as - * well as a footer icon to display the movie's rating. - */ -public class MovieRatingCardPresenter extends ImageCardViewPresenter { - - private static final String TAG = "MovieRatingCardPresenter"; - - public MovieRatingCardPresenter(Context context) { - super(context, (int) context.getResources().getDimension(R.dimen.thin_image_card_width), - (int) context.getResources().getDimension(R.dimen.thin_image_card_height)); - } - - @Override public void onBindViewHolder(Card card, ImageCardViewReplacement cardView) { - super.onBindViewHolder(card, cardView); - cardView.getPrimaryTextView().setLines(2); - cardView.getPrimaryTextView().setMaxLines(2); - cardView.getSecondaryTextView().setGravity(Gravity.RIGHT); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java index e1e4dc614..dfe34e22a 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java @@ -17,8 +17,6 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.OnActivateStateChangeHandler; import android.support.v17.leanback.widget.BaseCardView; import android.view.LayoutInflater; import android.view.View; @@ -33,49 +31,55 @@ import com.squareup.picasso.Picasso; * box, thus it will be hidden if the parent row is inactive. This behavior is unique to this card * and requires a special focus handler. */ -public class SideInfoCardPresenter extends AbstractCardPresenter implements - OnActivateStateChangeHandler { - - private static final String TAG = "SideInfoCardPresenter"; +public class SideInfoCardPresenter extends AbstractCardPresenter { public SideInfoCardPresenter(Context context) { super(context); } - @Override protected BaseCardViewEx onCreateView() { - BaseCardViewEx cardView = new BaseCardViewEx(getContext()); + @Override + protected BaseCardView onCreateView() { + final BaseCardView cardView = new BaseCardView(getContext()) { + + @Override + public void setActivated(boolean activated) { + super.setActivated(activated); + onActivateStateChanged(this, activated); + } + }; + cardView.setFocusable(true); cardView.setCardType(BaseCardView.CARD_TYPE_MAIN_ONLY); cardView.addView(LayoutInflater.from(getContext()).inflate(R.layout.side_info_card, null)); - cardView.setOnActivateStateChangeHandler(this); onActivateStateChanged(cardView, cardView.isActivated()); return cardView; } - @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { - ImageView imageView = cardView.getViewById(R.id.main_image); + @Override + public void onBindViewHolder(Card card, BaseCardView cardView) { + ImageView imageView = (ImageView) cardView.findViewById(R.id.main_image); if (card.getLocalImageResourceName() != null) { int width = (int) getContext().getResources() - .getDimension(R.dimen.sidetext_image_card_width); + .getDimension(R.dimen.sidetext_image_card_width); int height = (int) getContext().getResources() - .getDimension(R.dimen.sidetext_image_card_height); + .getDimension(R.dimen.sidetext_image_card_height); int resourceId = getContext().getResources() - .getIdentifier(card.getLocalImageResourceName(), - "drawable", getContext().getPackageName()); + .getIdentifier(card.getLocalImageResourceName(), + "drawable", getContext().getPackageName()); Picasso.with(getContext()).load(resourceId).resize(width, height).centerCrop() - .into(imageView); + .into(imageView); } - TextView primaryText = cardView.getViewById(R.id.primary_text); + TextView primaryText = (TextView) cardView.findViewById(R.id.primary_text); primaryText.setText(card.getTitle()); - TextView secondaryText = cardView.getViewById(R.id.secondary_text); + TextView secondaryText = (TextView) cardView.findViewById(R.id.secondary_text); secondaryText.setText(card.getDescription()); - TextView extraText = cardView.getViewById(R.id.extra_text); + TextView extraText = (TextView) cardView.findViewById(R.id.extra_text); extraText.setText(card.getExtraText()); } - @Override public void onActivateStateChanged(final BaseCardViewEx cardView, boolean activated) { - cardView.getViewById(R.id.info).setVisibility(activated ? View.VISIBLE : View.GONE); + public void onActivateStateChanged(final BaseCardView cardView, boolean activated) { + cardView.findViewById(R.id.info).setVisibility(activated ? View.VISIBLE : View.GONE); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java index add3dfae7..f48a3cab1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java @@ -17,44 +17,22 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; -import android.support.v17.leanback.widget.BaseCardView; -import android.view.LayoutInflater; -import android.widget.ImageView; -import android.widget.TextView; +import android.support.v17.leanback.widget.ImageCardView; /** * This Presenter will display a card which consists of a big image followed by a colored footer. * Not only the colored footer is unique to this card, but also it's footer (info) will be visible * even when its parent row is inactive. */ -public class SingleLineCardPresenter extends AbstractCardPresenter { - - private static final String TAG = "SingleLineCardPresenter"; +public class SingleLineCardPresenter extends ImageCardViewPresenter { public SingleLineCardPresenter(Context context) { - super(context); - } - - @Override protected BaseCardViewEx onCreateView() { - BaseCardViewEx cardView = new BaseCardViewEx(getContext()); - cardView.setCardType(BaseCardView.CARD_TYPE_MAIN_ONLY); - cardView.addView( - LayoutInflater.from(getContext()).inflate(R.layout.single_line_card_footer, null)); - return cardView; + super(context, R.style.SingleLineCardStyle); } - @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { - TextView primaryText = cardView.getViewById(R.id.primary_text); - primaryText.setText(card.getTitle()); - - int resourceId = getContext().getResources() - .getIdentifier(card.getLocalImageResourceName(), "drawable", - getContext().getPackageName()); - ImageView mainImage = cardView.getViewById(R.id.main_image); - mainImage.setImageResource(resourceId); - - cardView.getViewById(R.id.container).setBackgroundColor(card.getFooterColor()); + @Override public void onBindViewHolder(Card card, ImageCardView cardView) { + super.onBindViewHolder(card, cardView); + cardView.setInfoAreaBackgroundColor(card.getFooterColor()); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java deleted file mode 100644 index 93d42e0e1..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/StringPresenter.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ -package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; - -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.widget.Presenter; -import android.util.Log; -import android.view.ViewGroup; -import android.widget.TextView; - -public class StringPresenter extends Presenter { - - private static final String TAG = "StringPresenter"; - - public ViewHolder onCreateViewHolder(ViewGroup parent) { - Log.d(TAG, "onCreateViewHolder"); - TextView tv = new TextView(parent.getContext()); - tv.setFocusable(true); - tv.setFocusableInTouchMode(true); - tv.setBackground(parent.getContext().getResources().getDrawable(R.drawable.icon_focused)); - return new ViewHolder(tv); - } - - public void onBindViewHolder(ViewHolder viewHolder, Object item) { - Log.d(TAG, "onBindViewHolder for " + item.toString()); - ((TextView) viewHolder.view).setText(item.toString()); - } - - public void onUnbindViewHolder(ViewHolder viewHolder) { - Log.d(TAG, "onUnbindViewHolder"); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java index ad13be5f8..a688f444c 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java @@ -15,74 +15,27 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.cards.TextCardView; import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.views.BaseCardViewEx; -import android.support.v4.graphics.drawable.RoundedBitmapDrawable; -import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; -import android.view.LayoutInflater; -import android.widget.ImageView; -import android.widget.TextView; - -import com.squareup.picasso.Picasso; -import com.squareup.picasso.Target; /** * The Presenter displays a card consisting of text as a replacement for a big image. The footer is * also quite unique since it does contain two images rather than one or non. */ -public class TextCardPresenter extends AbstractCardPresenter { - - private static final String TAG = "AbstractFooterCardPresenter"; +public class TextCardPresenter extends AbstractCardPresenter { public TextCardPresenter(Context context) { super(context); } - @Override protected BaseCardViewEx onCreateView() { - BaseCardViewEx cardView = new BaseCardViewEx(getContext()); - LayoutInflater.from(getContext()).inflate(R.layout.text_icon_card, cardView); - LayoutInflater.from(getContext()).inflate(R.layout.text_icon_card_footer, cardView); - return cardView; + @Override + protected TextCardView onCreateView() { + return new TextCardView(getContext()); } - @Override public void onBindViewHolder(Card card, BaseCardViewEx cardView) { - TextView extraText = cardView.getViewById(R.id.extra_text); - TextView primaryText = cardView.getViewById(R.id.primary_text); - ImageView footerIcon = cardView.getViewById(R.id.footer_icon); - final ImageView imageView = cardView.getViewById(R.id.main_image); - - extraText.setText(card.getExtraText()); - primaryText.setText(card.getTitle()); - if (card.getLocalImageResourceName() != null) { - int width = (int) getContext().getResources() - .getDimension(R.dimen.sidetext_image_card_width); - int height = (int) getContext().getResources() - .getDimension(R.dimen.sidetext_image_card_height); - int resourceId = card.getLocalImageResourceId(getContext()); - // TODO: hahnr@ load the image without Picasso - Picasso.with(getContext()).load(resourceId).resize(width, height).centerCrop() - .into(new Target() { - - @Override - public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { - RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory - .create(getContext().getResources(), bitmap); - drawable.setCornerRadius( - Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); - imageView.setImageDrawable(drawable); - } - - @Override public void onBitmapFailed(Drawable errorDrawable) { - } - - @Override public void onPrepareLoad(Drawable placeHolderDrawable) { - } - }); - } - footerIcon.setImageResource(R.drawable.stars_white); + @Override + public void onBindViewHolder(Card card, TextCardView cardView) { + cardView.updateUi(card); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java deleted file mode 100644 index d11f4e8cf..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/BaseCardViewEx.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.views; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.ResourceCache; -import android.support.v17.leanback.widget.BaseCardView; -import android.view.View; - -/** - * This class is an extension for the BaseCardView which is focusable by default. This behavior has - * to be merged into the original BaseCardView at some point in the development. After merging those - * two classes, this one, the BaseCardViewEx, can be removed. - */ -public class BaseCardViewEx extends BaseCardView { - - protected Context mContext; - private ResourceCache mResourceCache = new ResourceCache(); - private OnActivateStateChangeHandler mActivationCallback; - - - public BaseCardViewEx(Context context) { - super(context); - mContext = context; - setCardType(BaseCardView.CARD_TYPE_INFO_UNDER); - - // TODO: @hahnr BaseCardView should be focusable by default. Merge! - setFocusable(true); - setFocusableInTouchMode(true); - } - - @Override public void setActivated(boolean activated) { - super.setActivated(activated); - if (mActivationCallback != null) - mActivationCallback.onActivateStateChanged(this, activated); - } - - public void setOnActivateStateChangeHandler(OnActivateStateChangeHandler handler) { - mActivationCallback = handler; - } - - public ViewType getViewById(int resId) { - return mResourceCache.getViewById(this, resId); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java deleted file mode 100644 index 9e8af546d..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/FooterLayoutCardView.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.views; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.view.LayoutInflater; -import android.widget.ImageView; - -/** - * The FooterLayoutCardView creates a card view consisting of a big image followed by a footer - * passed as a layout resource. - */ -public class FooterLayoutCardView extends BaseCardViewEx { - - private final ImageView mImageView; - - /** - * The footer passed as a layout resource id will be inflated and added automatically to this - * view. - *

- * Note: If you want your footer to expand/collapse when its parent row is - * activated/deactivated, you have to add the layout_viewType="info" property to - * your footers root view. - *

- * Example footer layout: - *

{@code 
-     * 
-     *     
-     * }
- * - * @param context The current context. - * @param layoutId The footers layout resource id. - * @param imageWidthInDp The width of the ImageView used in this card. The card's width always - * equals the image's width. - * @param imageHeightInDp The height of the ImageView used in this card. - * @see android.support.v17.leanback.widget.BaseCardView.LayoutParams - */ - public FooterLayoutCardView(Context context, int layoutId, int imageWidthInDp, - int imageHeightInDp) { - super(context); - setCardType(CARD_TYPE_INFO_UNDER); - setBackgroundColor(context.getResources().getColor(R.color.default_card_background_color)); - - LayoutInflater.from(context).inflate(R.layout.image_card, this); - mImageView = getViewById(R.id.image_card_view_main_image); - LayoutInflater.from(context).inflate(layoutId, this); - } - - public ImageView getImageView() { - return mImageView; - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java deleted file mode 100644 index c2a55fdee..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/ImageCardViewReplacement.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.views; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.widget.ImageCardView; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -/** - * Leanback's {@link ImageCardView} will need some layout changes to fit all design requirements - * from the specs. This class is a temporary implementation of the "new" {@link ImageCardView} and - * will replace the existing one at some point in the development process. The original - * implementation also requires some refactoring to be more flexible in order to be used for various - * card types. - *

- * Besides from the refactoring of the ImageCardView I suggest to change not only the BaseCardView - * but also to add at least one additional CardView, the "FooterLayoutCardView". More about this - * topic can be discussed later in the development process. - */ -public class ImageCardViewReplacement extends FooterLayoutCardView { - - public static final int PRIMARY_TEXTVIEW_ID = R.id.primary_text; - public static final int SECONDARY_TEXTVIEW_ID = R.id.secondary_text; - public static final int FOOTER_ICON_ID = R.id.footer_icon; - public static final int INFO_BOX_ID = R.id.info_field; - - public ImageCardViewReplacement(Context context, int widthInDp, int heightInDp) { - super(context, R.layout.image_card_footer, widthInDp, heightInDp); - setBackgroundColor(context.getResources().getColor(R.color.default_card_background_color)); - } - - public TextView getPrimaryTextView() { - return getViewById(PRIMARY_TEXTVIEW_ID); - } - - public TextView getSecondaryTextView() { - return getViewById(SECONDARY_TEXTVIEW_ID); - } - - public ImageView getIconView() { - return getViewById(FOOTER_ICON_ID); - } - - public View getInfoBoxView() { - return getViewById(INFO_BOX_ID); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java deleted file mode 100644 index e444ef266..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/views/OnActivateStateChangeHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.views; - -public interface OnActivateStateChangeHandler { - - void onActivateStateChanged(BaseCardViewEx cardView, boolean activated); - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml index eb126831c..5c2570d53 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml @@ -1,7 +1,26 @@ + - + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml index c2f724c53..db4cf9c7d 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml @@ -1,4 +1,19 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml index 1140e80be..8da381217 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml @@ -1,4 +1,19 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml index 07b058990..d9fa80b2c 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml @@ -1,9 +1,23 @@ + + android:angle="-270" + android:endColor="@color/background_gradient_end" + android:startColor="@color/background_gradient_start"/> \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml index 4eb4fa823..bab1cc6f9 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml @@ -1,7 +1,21 @@ - + + - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml deleted file mode 100644 index 940efe702..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_not_focused.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml index 880f9f0b1..9fccc2454 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml @@ -1,4 +1,19 @@ + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml index 7be6ec48b..0329874e6 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml @@ -1,6 +1,21 @@ + - + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml index 2dd9d9fc3..152e7e6f8 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml @@ -1,4 +1,19 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml index dca2934de..bea8d6689 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml @@ -1,5 +1,20 @@ + - - + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml index 4893247fa..b4fd39ec4 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml @@ -1,4 +1,19 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml index 4652b0b3e..d6a1023c3 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml @@ -1,4 +1,19 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml index 43cbeacb2..74cccd0f5 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml @@ -1,4 +1,19 @@ + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml new file mode 100644 index 000000000..90c69b611 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml index b6cf93f7a..9d2eda6c7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml @@ -1,4 +1,19 @@ + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view_content.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view_content.xml new file mode 100644 index 000000000..5140ed7e6 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view_content.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml deleted file mode 100644 index c24c187b4..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml deleted file mode 100644 index b1cc798e1..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/icon_card_footer.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml deleted file mode 100644 index 31c56360f..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml deleted file mode 100644 index d8f86e783..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/image_card_footer.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml index aadc10525..b8d660d50 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml @@ -1,4 +1,19 @@ + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml deleted file mode 100644 index 84ca560b3..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/single_line_card_footer.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml index a11ac68ab..339549a07 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml @@ -1,29 +1,79 @@ - - - + + + + android:fontFamily="sans-serif-condensed" + android:lines="7" + android:maxLines="7" + android:paddingBottom="14dp" + android:paddingLeft="15dp" + android:paddingRight="15dp" + android:paddingTop="12dp" + lb:layout_viewType="main"/> + + + + - - - \ No newline at end of file + android:maxLines="1" + /> + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml deleted file mode 100644 index 717c63aaa..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card_footer.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml index 8a1286997..ff5be6929 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml @@ -1,6 +1,20 @@ + - \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json deleted file mode 100644 index 84184a2da..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_card_example.json +++ /dev/null @@ -1,559 +0,0 @@ -[ - { - "title": "Standard", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Two Line Title", - "cards": [ - { - "type": "THIN_RATING", - "title": "The Amazing Spuder-Man", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN_RATING", - "title": "American Psycho", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN_RATING", - "title": "Big Hero 6", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN_RATING", - "title": "Edge of Tomorrow", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN_RATING", - "title": "The Hobbit: The Desolation of Smaug", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN_RATING", - "title": "Interstellar", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN_RATING", - "title": "Jurassic Park", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN_RATING", - "title": "The Hunger Games: Mockingjay Part I", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN_RATING", - "title": "Planes", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Two Line Title + Icon", - "cards": [ - { - "type": "THIN_RATING", - "description": "$3.99", - "title": "The Amazing Spider-Man", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN_RATING", - "title": "American Psycho", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN_RATING", - "title": "Big Hero 6", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN_RATING", - "title": "Edge of Tomorrow", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN_RATING", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN_RATING", - "title": "Interstellar", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN_RATING", - "title": "Jurassic Park", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN_RATING", - "description": "$3.99", - "title": "The Hunger Games: Mockingjay Part I", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN_RATING", - "title": "Planes", - "description": "$3.99", - "footerIconLocalImageResource": "stars_red", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Standard Square", - "cards": [ - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#bf360C", - "localImageResource": "card_image_music_02" - }, - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#b93221", - "localImageResource": "card_image_music_13" - }, - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#311b92", - "localImageResource": "card_image_music_08" - }, - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#33691e", - "localImageResource": "card_image_music_05" - }, - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#37474f", - "localImageResource": "card_image_music_06" - }, - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#3e2723", - "localImageResource": "card_image_music_09" - }, - { - "type": "SQUARE_BIG", - "title": "Blue in Green", - "description": "Miles Davis", - "footerColor": "#01579B", - "localImageResource": "card_image_music_11" - } - ] - }, - { - "title": "Side Info", - "cards": [ - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_02" - }, - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_13" - }, - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_08" - }, - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_05" - }, - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_06" - }, - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_09" - }, - { - "type": "SIDE_INFO", - "title": "The Life Aquatic", - "description": "Seu Jorge", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "card_image_music_11" - } - ] - }, - { - "title": "Wide (Games)", - "cards": [ - { - "type": "WIDE_SHORT", - "title": "Angry Birds", - "description": "Purchased", - "localImageResource": "game_angry_bird_w", - "footerIconLocalImageResource": "ic_installed" - }, - { - "type": "WIDE_SHORT", - "title": "Badland", - "description": "Purchased", - "localImageResource": "game_badland_w", - "footerIconLocalImageResource": "ic_installed" - }, - { - "type": "WIDE_SHORT", - "title": "Leo's Fortune", - "description": "Purchased", - "localImageResource": "game_leos_fortune_w", - "footerIconLocalImageResource": "ic_installed" - }, - { - "type": "WIDE_SHORT", - "title": "Minion Rush", - "description": "Purchased", - "localImageResource": "game_minion_rush_w", - "footerIconLocalImageResource": "ic_installed" - }, - { - "type": "WIDE_SHORT", - "title": "Monument Valley", - "description": "Purchased", - "localImageResource": "game_monument_valley_w", - "footerIconLocalImageResource": "ic_installed" - } - ] - }, - { - "title": "Wide (Videos)", - "cards": [ - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_01" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_02" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_03" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_04" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_05" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_06" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_07" - }, - { - "type": "DEFAULT", - "title": "Marseille sea food tour", - "description": "9,089 views 3 years ago by ADELAIDE", - "localImageResource": "coffee_and_tea_08" - } - ] - }, - { - "title": "Text", - "cards": [ - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_01" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_02" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_03" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_04" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_05" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_06" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_07" - }, - { - "type": "TEXT", - "title": "Jonathan Max", - "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", - "localImageResource": "face_08" - } - ] - }, - { - "title": "Launcher", - "cards": [ - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_01" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_02" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_03" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_04" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_05" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_06" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_07" - }, - { - "type": "SIDE_INFO_TEST_1", - "title": "Harry Potter", - "description": "$3.99", - "localImageResource": "coffee_and_tea_08" - } - ] - }, - { - "title": "Single Line", - "cards": [ - { - "type": "SQUARE", - "title": "Action & Adventure", - "footerColor": "#dd004e", - "localImageResource": "category_action" - }, - { - "type": "SQUARE", - "title": "Animation", - "footerColor": "#c51162", - "localImageResource": "category_animation" - }, - { - "type": "SQUARE", - "title": "Classics", - "footerColor": "#9c27b0", - "localImageResource": "category_classics" - }, - { - "type": "SQUARE", - "title": "Comedy", - "footerColor": "#cf4900", - "localImageResource": "category_comedy" - }, - { - "type": "SQUARE", - "title": "Crime", - "footerColor": "#3f51b5", - "localImageResource": "category_crime" - }, - { - "type": "SQUARE", - "title": "Documentary", - "footerColor": "#02639b", - "localImageResource": "category_documentary" - }, - { - "type": "SQUARE", - "title": "Drama", - "footerColor": "#2a56c6", - "localImageResource": "category_drama" - } - ] - }, - { - "title": "Icon", - "shadow": false, - "cards": [ - { - "type": "ICON", - "title": "Settings", - "localImageResource": "ic_settings_settings" - }, - { - "type": "ICON", - "title": "WiFi", - "localImageResource": "ic_settings_wifi_3_bar" - }, - { - "type": "ICON", - "title": "Parental Control", - "localImageResource": "ic_settings_parental_control" - }, - { - "type": "ICON", - "title": "Time", - "localImageResource": "ic_settings_time" - } - ] - } -] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_example.json new file mode 100644 index 000000000..8b52b02ab --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_example.json @@ -0,0 +1,506 @@ +[ + { + "title": "Standard", + "cards": [ + { + "type": "MOVIE", + "title": "The Amazing Spider-Man", + "description": "$3.99", + "localImageResource": "card_image_movie_01" + }, + { + "type": "MOVIE", + "title": "American Psycho", + "description": "$3.99", + "localImageResource": "card_image_movie_02" + }, + { + "type": "MOVIE", + "title": "Big Hero 6", + "description": "$3.99", + "localImageResource": "card_image_movie_03" + }, + { + "type": "MOVIE", + "title": "Edge of Tomorrow", + "description": "$3.99", + "localImageResource": "card_image_movie_04" + }, + { + "type": "MOVIE", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "localImageResource": "card_image_movie_05" + }, + { + "type": "MOVIE", + "title": "Interstellar", + "description": "$3.99", + "localImageResource": "card_image_movie_06" + }, + { + "type": "MOVIE", + "title": "Jurassic Park", + "description": "$3.99", + "localImageResource": "card_image_movie_07" + }, + { + "type": "MOVIE", + "title": "The Hunger Games: Mockingjay Part I", + "description": "$3.99", + "localImageResource": "card_image_movie_08" + }, + { + "type": "MOVIE", + "title": "Planes", + "description": "$3.99", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Two Line Title", + "cards": [ + { + "type": "MOVIE_BASE", + "title": "The Amazing Spider-Man", + "localImageResource": "card_image_movie_01" + }, + { + "type": "MOVIE_BASE", + "title": "American Psycho", + "localImageResource": "card_image_movie_02" + }, + { + "type": "MOVIE_BASE", + "title": "Big Hero 6", + "localImageResource": "card_image_movie_03" + }, + { + "type": "MOVIE_BASE", + "title": "Edge of Tomorrow", + "localImageResource": "card_image_movie_04" + }, + { + "type": "MOVIE_BASE", + "title": "The Hobbit: The Desolation of Smaug", + "localImageResource": "card_image_movie_05" + }, + { + "type": "MOVIE_BASE", + "title": "Interstellar", + "localImageResource": "card_image_movie_06" + }, + { + "type": "MOVIE_BASE", + "title": "Jurassic Park", + "localImageResource": "card_image_movie_07" + }, + { + "type": "MOVIE_BASE", + "title": "The Hunger Games: Mockingjay Part I", + "localImageResource": "card_image_movie_08" + }, + { + "type": "MOVIE_BASE", + "title": "Planes", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Two Line Title + Icon", + "cards": [ + { + "type": "MOVIE_COMPLETE", + "description": "$3.99", + "title": "The Amazing Spider-Man", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_01" + }, + { + "type": "MOVIE_COMPLETE", + "title": "American Psycho", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_02" + }, + { + "type": "MOVIE_COMPLETE", + "title": "Big Hero 6", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_03" + }, + { + "type": "MOVIE_COMPLETE", + "title": "Edge of Tomorrow", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_04" + }, + { + "type": "MOVIE_COMPLETE", + "title": "The Hobbit: The Desolation of Smaug", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_05" + }, + { + "type": "MOVIE_COMPLETE", + "title": "Interstellar", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_06" + }, + { + "type": "MOVIE_COMPLETE", + "title": "Jurassic Park", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_07" + }, + { + "type": "MOVIE_COMPLETE", + "description": "$3.99", + "title": "The Hunger Games: Mockingjay Part I", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_08" + }, + { + "type": "MOVIE_COMPLETE", + "title": "Planes", + "description": "$3.99", + "footerIconLocalImageResource": "stars_red", + "localImageResource": "card_image_movie_09" + } + ] + }, + { + "title": "Standard Square", + "cards": [ + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#bf360C", + "localImageResource": "card_image_music_02" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#b93221", + "localImageResource": "card_image_music_13" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#311b92", + "localImageResource": "card_image_music_08" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#33691e", + "localImageResource": "card_image_music_05" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#37474f", + "localImageResource": "card_image_music_06" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#3e2723", + "localImageResource": "card_image_music_09" + }, + { + "type": "SQUARE_BIG", + "title": "Blue in Green", + "description": "Miles Davis", + "footerColor": "#01579B", + "localImageResource": "card_image_music_11" + } + ] + }, + { + "title": "Side Info", + "cards": [ + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_02" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_13" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_08" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_05" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_06" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_09" + }, + { + "type": "SIDE_INFO", + "title": "The Life Aquatic", + "description": "Seu Jorge", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "card_image_music_11" + } + ] + }, + { + "title": "Wide (Games)", + "cards": [ + { + "type": "GAME", + "title": "Angry Birds", + "description": "Purchased", + "localImageResource": "game_angry_bird_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "GAME", + "title": "Badland", + "description": "Purchased", + "localImageResource": "game_badland_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "GAME", + "title": "Leo's Fortune", + "description": "Purchased", + "localImageResource": "game_leos_fortune_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "GAME", + "title": "Minion Rush", + "description": "Purchased", + "localImageResource": "game_minion_rush_w", + "footerIconLocalImageResource": "ic_installed" + }, + { + "type": "GAME", + "title": "Monument Valley", + "description": "Purchased", + "localImageResource": "game_monument_valley_w", + "footerIconLocalImageResource": "ic_installed" + } + ] + }, + { + "title": "Wide (Videos)", + "cards": [ + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_01" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_02" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_03" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_04" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_05" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_06" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_07" + }, + { + "type": "DEFAULT", + "title": "Marseille sea food tour", + "description": "9,089 views 3 years ago by ADELAIDE", + "localImageResource": "coffee_and_tea_08" + } + ] + }, + { + "title": "Text", + "cards": [ + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_01" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_02" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_03" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_04" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_05" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_06" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_07" + }, + { + "type": "TEXT", + "title": "Jonathan Max", + "extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.", + "localImageResource": "face_08" + } + ] + }, + { + "title": "Single Line", + "cards": [ + { + "type": "SINGLE_LINE", + "title": "Action & Adventure", + "footerColor": "#dd004e", + "localImageResource": "category_action" + }, + { + "type": "SINGLE_LINE", + "title": "Animation", + "footerColor": "#c51162", + "localImageResource": "category_animation" + }, + { + "type": "SINGLE_LINE", + "title": "Classics", + "footerColor": "#9c27b0", + "localImageResource": "category_classics" + }, + { + "type": "SINGLE_LINE", + "title": "Comedy", + "footerColor": "#cf4900", + "localImageResource": "category_comedy" + }, + { + "type": "SINGLE_LINE", + "title": "Crime", + "footerColor": "#3f51b5", + "localImageResource": "category_crime" + }, + { + "type": "SINGLE_LINE", + "title": "Documentary", + "footerColor": "#02639b", + "localImageResource": "category_documentary" + }, + { + "type": "SINGLE_LINE", + "title": "Drama", + "footerColor": "#2a56c6", + "localImageResource": "category_drama" + } + ] + }, + { + "title": "Icon", + "shadow": false, + "cards": [ + { + "type": "ICON", + "title": "Settings", + "localImageResource": "ic_settings_settings" + }, + { + "type": "ICON", + "title": "WiFi", + "localImageResource": "ic_settings_wifi_3_bar" + }, + { + "type": "ICON", + "title": "Parental Control", + "localImageResource": "ic_settings_parental_control" + }, + { + "type": "ICON", + "title": "Time", + "localImageResource": "ic_settings_time" + } + ] + } +] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json index b01a2d45e..b6d06e26a 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json @@ -49,55 +49,55 @@ ], "recommended": [ { - "type": "THIN", + "type": "MOVIE", "title": "The Amazing Spuder-Man", "description": "$3.99", "localImageResource": "card_image_movie_01" }, { - "type": "THIN", + "type": "MOVIE", "title": "American Psycho", "description": "$3.99", "localImageResource": "card_image_movie_02" }, { - "type": "THIN", + "type": "MOVIE", "title": "Big Hero 6", "description": "$3.99", "localImageResource": "card_image_movie_03" }, { - "type": "THIN", + "type": "MOVIE", "title": "Edge of Tomorrow", "description": "$3.99", "localImageResource": "card_image_movie_04" }, { - "type": "THIN", + "type": "MOVIE", "title": "The Hobbit: The Desolation of Smaug", "description": "$3.99", "localImageResource": "card_image_movie_05" }, { - "type": "THIN", + "type": "MOVIE", "title": "Interstellar", "description": "$3.99", "localImageResource": "card_image_movie_06" }, { - "type": "THIN", + "type": "MOVIE", "title": "Jurassic Park", "description": "$3.99", "localImageResource": "card_image_movie_07" }, { - "type": "THIN", + "type": "MOVIE", "title": "The Hunger Games: Mockingjay Part I", "description": "$3.99", "localImageResource": "card_image_movie_08" }, { - "type": "THIN", + "type": "MOVIE", "title": "Planes", "description": "$3.99", "localImageResource": "card_image_movie_09" diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml index 7984d7e6c..6305c4119 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml @@ -1,3 +1,18 @@ + + #FFFFFF #DDDDDD diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml index d12d7900b..07c802733 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml @@ -1,10 +1,24 @@ + 224dp 126dp - 120dp - 172dp + 120dp + 172dp 224dp 109dp diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml index fab46b074..4c2c673ac 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml @@ -1,3 +1,18 @@ + + ShowcaseApp diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml index 1ac8724f5..490f442d1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml @@ -1,41 +1,162 @@ + - + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml index 38244aac3..8d5551592 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml @@ -1,3 +1,18 @@ + + + + -- cgit v1.2.3 From 9f8ccdc5af34f09167fc424851c90c54af94b875 Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Tue, 4 Aug 2015 14:58:39 -0700 Subject: Rearranged classes and removed unused resources. Rearranged classes into packages to provide a better overview as well as removing an unused mp3 file. Change-Id: I9e3b63ceef919d6f0d57479260c93376578793cf --- .../app/src/main/AndroidManifest.xml | 10 +- .../BrowserExample01Fragment.java | 88 ---- .../CardExampleFragment.java | 91 ----- .../supportleanbackshowcase/CardListRow.java | 44 -- .../supportleanbackshowcase/Constants.java | 17 - .../DetailViewExampleActivity.java | 54 --- .../DetailViewExampleFragment.java | 150 ------- .../supportleanbackshowcase/DetailedCard.java | 71 ---- .../DetailsDescriptionPresenter.java | 59 --- .../DialogExampleActivity.java | 36 -- .../DialogExampleFragment.java | 66 --- .../supportleanbackshowcase/GridExample.java | 56 --- .../supportleanbackshowcase/MainActivity.java | 38 -- .../supportleanbackshowcase/MainFragment.java | 263 ------------ .../supportleanbackshowcase/MediaPlayerGlue.java | 446 --------------------- .../leanback/supportleanbackshowcase/Movie.java | 50 --- .../MusicConsumptionExampleFragment.java | 150 ------- .../PicassoBackgroundManagerTarget.java | 61 --- .../supportleanbackshowcase/ResourceCache.java | 36 -- .../SettingsExampleActivity.java | 30 -- .../SettingsExampleFragment.java | 101 ----- .../ShadowRowPresenterSelector.java | 43 -- .../supportleanbackshowcase/SongListRow.java | 20 - .../supportleanbackshowcase/TrackListHeader.java | 49 --- .../leanback/supportleanbackshowcase/Utils.java | 95 ----- .../VideoConsumptionExampleFragment.java | 109 ----- .../VideoMediaPlayerGlue.java | 56 --- .../VideoSurfaceFragment.java | 38 -- .../WizardExample1stStepFragment.java | 81 ---- .../WizardExample2ndStepFragment.java | 108 ----- .../WizardExample3rdStepFragment.java | 101 ----- .../WizardExample4thStepFragment.java | 71 ---- .../WizardExampleActivity.java | 71 ---- .../WizardExampleBaseStepFragment.java | 49 --- .../app/BrowserExample01Fragment.java | 92 +++++ .../app/CardExampleFragment.java | 95 +++++ .../supportleanbackshowcase/app/GridExample.java | 58 +++ .../supportleanbackshowcase/app/MainActivity.java | 39 ++ .../supportleanbackshowcase/app/MainFragment.java | 274 +++++++++++++ .../app/details/DetailViewExampleActivity.java | 32 ++ .../app/details/DetailViewExampleFragment.java | 154 +++++++ .../app/details/DetailsDescriptionPresenter.java | 62 +++ .../app/details/ShadowRowPresenterSelector.java | 44 ++ .../app/dialog/DialogExampleActivity.java | 35 ++ .../app/dialog/DialogExampleFragment.java | 67 ++++ .../app/media/MediaPlayerGlue.java | 446 +++++++++++++++++++++ .../app/media/MusicConsumptionExampleFragment.java | 155 +++++++ .../app/media/SongListRow.java | 20 + .../app/media/TrackListHeader.java | 50 +++ .../app/media/VideoConsumptionExampleFragment.java | 109 +++++ .../app/media/VideoMediaPlayerGlue.java | 57 +++ .../app/media/VideoSurfaceFragment.java | 39 ++ .../app/settings/SettingsExampleActivity.java | 31 ++ .../app/settings/SettingsExampleFragment.java | 102 +++++ .../app/wizard/WizardExample1stStepFragment.java | 75 ++++ .../app/wizard/WizardExample2ndStepFragment.java | 109 +++++ .../app/wizard/WizardExample3rdStepFragment.java | 102 +++++ .../app/wizard/WizardExample4thStepFragment.java | 71 ++++ .../app/wizard/WizardExampleActivity.java | 70 ++++ .../app/wizard/WizardExampleBaseStepFragment.java | 46 +++ .../cards/CharacterCardView.java | 3 +- .../cards/TextCardView.java | 3 +- .../supportleanbackshowcase/cards/models/Card.java | 129 ------ .../cards/models/CardRow.java | 44 -- .../supportleanbackshowcase/cards/models/Song.java | 116 ------ .../cards/models/SongList.java | 31 -- .../cards/presenters/AbstractCardPresenter.java | 2 +- .../cards/presenters/CardPresenterSelector.java | 2 +- .../cards/presenters/CharacterCardPresenter.java | 2 +- .../cards/presenters/ImageCardViewPresenter.java | 2 +- .../cards/presenters/SideInfoCardPresenter.java | 2 +- .../cards/presenters/SingleLineCardPresenter.java | 2 +- .../cards/presenters/TextCardPresenter.java | 2 +- .../supportleanbackshowcase/models/Card.java | 129 ++++++ .../supportleanbackshowcase/models/CardRow.java | 44 ++ .../models/DetailedCard.java | 71 ++++ .../supportleanbackshowcase/models/Movie.java | 50 +++ .../supportleanbackshowcase/models/Song.java | 116 ++++++ .../supportleanbackshowcase/models/SongList.java | 31 ++ .../supportleanbackshowcase/utils/CardListRow.java | 45 +++ .../supportleanbackshowcase/utils/Constants.java | 17 + .../utils/PicassoBackgroundManagerTarget.java | 61 +++ .../utils/ResourceCache.java | 36 ++ .../supportleanbackshowcase/utils/Utils.java | 95 +++++ .../main/res/layout/activity_detail_example.xml | 2 +- .../main/res/layout/activity_settings_example.xml | 2 +- ...an_view_from_above_i_know_its_super_awesome.mp3 | Bin 10415387 -> 0 bytes 87 files changed, 3145 insertions(+), 3136 deletions(-) delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailsDescriptionPresenter.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/ShadowRowPresenterSelector.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MediaPlayerGlue.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicConsumptionExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/SongListRow.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/TrackListHeader.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoMediaPlayerGlue.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoSurfaceFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Card.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/CardRow.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/DetailedCard.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Movie.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Song.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/SongList.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/CardListRow.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Constants.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/PicassoBackgroundManagerTarget.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/ResourceCache.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index c15f13513..ec5220bc7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ android:largeHeap="true" android:theme="@style/Theme.Example.Leanback"> diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java deleted file mode 100644 index 2d3353fe2..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/BrowserExample01Fragment.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.SearchOrbView; -import android.view.View; -import android.widget.Toast; - -import com.google.gson.Gson; - - -public class BrowserExample01Fragment extends BrowseFragment { - - private static final String TAG = "BrowserExample01Fragment"; - - private ArrayObjectAdapter mRowsAdapter; - - @Override public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setupUi(); - setupRowAdapter(); - } - - private void setupUi() { - setHeadersState(HEADERS_ENABLED); - setHeadersTransitionOnBackEnabled(true); - setSearchAffordanceColors( - new SearchOrbView.Colors(getResources().getColor(R.color.search_color), - getResources().getColor(R.color.search_bright_color), - getResources().getColor(R.color.search_icon_color))); - setBrandColor(getResources().getColor(R.color.fastlane_background)); - setTitle("Browser Example 01"); - setOnSearchClickedListener(new View.OnClickListener() { - @Override public void onClick(View v) { - Toast.makeText(getActivity(), getString(R.string.implement_search), - Toast.LENGTH_LONG).show(); - } - }); - } - - private void setupRowAdapter() { - mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); - createRows(); - setAdapter(mRowsAdapter); - } - - private void createRows() { - String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.browsing_example_01)); - CardRow[] rows = new Gson().fromJson(json, CardRow[].class); - for (CardRow row : rows) { - mRowsAdapter.add(createCardRow(row)); - } - } - - private ListRow createCardRow(final CardRow cardRow) { - // Build main row using the ImageCardViewPresenter. - PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); - for (Card card : cardRow.getCards()) { - listRowAdapter.add(card); - } - HeaderItem header = new HeaderItem(cardRow.getTitle()); - return new CardListRow(header, listRowAdapter, cardRow); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java deleted file mode 100644 index 4ece60db1..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardExampleFragment.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.SearchOrbView; -import android.view.View; -import android.widget.Toast; - -import com.google.gson.Gson; - -/** - * This fragment will be shown when the "Card Examples" card is selected at the home menu. It will - * display multiple card types. - */ -public class CardExampleFragment extends BrowseFragment { - - private static final String TAG = "CardExampleFragment"; - - private ArrayObjectAdapter mRowsAdapter; - - @Override public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setupUi(); - setupRowAdapter(); - } - - private void setupUi() { - setHeadersState(HEADERS_ENABLED); - setHeadersTransitionOnBackEnabled(true); - setSearchAffordanceColors( - new SearchOrbView.Colors(getResources().getColor(R.color.search_color), - getResources().getColor(R.color.search_bright_color), - getResources().getColor(R.color.search_icon_color))); - setBrandColor(getResources().getColor(R.color.fastlane_background)); - setTitle(getString(R.string.card_examples_title)); - setOnSearchClickedListener(new View.OnClickListener() { - @Override public void onClick(View v) { - Toast.makeText(getActivity(), getString(R.string.implement_search), - Toast.LENGTH_LONG).show(); - } - }); - } - - private void setupRowAdapter() { - mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); - createRows(); - setAdapter(mRowsAdapter); - } - - private void createRows() { - String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.cards_example)); - CardRow[] rows = new Gson().fromJson(json, CardRow[].class); - for (CardRow row : rows) { - mRowsAdapter.add(createCardRow(row)); - } - } - - private ListRow createCardRow(final CardRow cardRow) { - // Build main row using the ImageCardViewPresenter. - PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); - for (Card card : cardRow.getCards()) { - listRowAdapter.add(card); - } - HeaderItem header = new HeaderItem(cardRow.getTitle()); - return new CardListRow(header, listRowAdapter, cardRow); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java deleted file mode 100644 index d23bd39b7..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/CardListRow.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.ObjectAdapter; - -/** - * The {@link CardListRow} allows the {@link ShadowRowPresenterSelector} to access the {@link CardRow} - * held by the row and determine whether to use a {@link android.support.v17.leanback.widget.Presenter} - * with or without a shadow. - */ -public class CardListRow extends ListRow { - - private CardRow mCardRow; - - public CardListRow(HeaderItem header, ObjectAdapter adapter, CardRow cardRow) { - super(header, adapter); - setCardRow(cardRow); - } - - public CardRow getCardRow() { - return mCardRow; - } - - public void setCardRow(CardRow cardRow) { - this.mCardRow = cardRow; - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java deleted file mode 100644 index 2effa72b9..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Constants.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -public class Constants { - - public static final boolean LOCAL_LOGD = true; - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java deleted file mode 100644 index e301f58f5..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleActivity.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Activity; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.support.v17.leanback.app.DetailsFragment; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.ClassPresenterSelector; -import android.support.v17.leanback.widget.DetailsOverviewRow; -import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.ListRowPresenter; -import android.support.v17.leanback.widget.OnItemViewClickedListener; -import android.support.v17.leanback.widget.OnItemViewSelectedListener; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Toast; - -import com.google.gson.Gson; - -/** - * Contains a {@link DetailsFragment} in order to display more details for a given card. - */ -public class DetailViewExampleActivity extends Activity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_detail_example); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java deleted file mode 100644 index 543358707..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailViewExampleFragment.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.v17.leanback.app.DetailsFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.ClassPresenterSelector; -import android.support.v17.leanback.widget.DetailsOverviewRow; -import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.ListRowPresenter; -import android.support.v17.leanback.widget.OnItemViewClickedListener; -import android.support.v17.leanback.widget.OnItemViewSelectedListener; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Toast; - -import com.google.gson.Gson; - -/** - * Displays a card with more details using a {@link DetailsFragment}. - */ -public class DetailViewExampleFragment extends DetailsFragment implements OnItemViewClickedListener, - OnItemViewSelectedListener { - - private ArrayObjectAdapter mRowsAdapter; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setupUi(); - setupEventListeners(); - } - - private void setupUi() { - // Load the card we want to display from a JSON resource. This JSON data could come from - // anywhere in a real world app, e.g. a server. - String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.detail_example)); - DetailedCard data = new Gson().fromJson(json, DetailedCard.class); - - // Setup fragment - setTitle(getString(R.string.detail_view_title)); - - FullWidthDetailsOverviewRowPresenter rowPresenter = new FullWidthDetailsOverviewRowPresenter( - new DetailsDescriptionPresenter(getActivity())) { - - @Override - protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { - // Customize Actionbar and Content by using custom colors. - RowPresenter.ViewHolder viewHolder = super.createRowViewHolder(parent); - - View actionsView = viewHolder.view. - findViewById(R.id.details_overview_actions_background); - actionsView.setBackgroundColor(getActivity().getResources(). - getColor(R.color.detail_view_actionbar_background, null)); - - View detailsView = viewHolder.view.findViewById(R.id.details_frame); - detailsView.setBackgroundColor( - getResources().getColor(R.color.detail_view_background, null)); - return viewHolder; - } - }; - ListRowPresenter shadowDisabledRowPresenter = new ListRowPresenter(); - shadowDisabledRowPresenter.setShadowEnabled(false); - - // Setup PresenterSelector to distinguish between the different rows. - ClassPresenterSelector rowPresenterSelector = new ClassPresenterSelector(); - rowPresenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter); - rowPresenterSelector.addClassPresenter(CardListRow.class, shadowDisabledRowPresenter); - rowPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter()); - mRowsAdapter = new ArrayObjectAdapter(rowPresenterSelector); - - // Setup action and detail row. - DetailsOverviewRow detailsOverview = new DetailsOverviewRow(data); - int imageResId = data.getLocalImageResourceId(getActivity()); - detailsOverview.setImageDrawable(getResources().getDrawable(imageResId, null)); - ArrayObjectAdapter actionAdapter = new ArrayObjectAdapter(); - actionAdapter.add(new Action(1, getString(R.string.action_buy) + data.getPrice())); - actionAdapter.add(new Action(2, getString(R.string.action_wishlist))); - actionAdapter.add(new Action(3, getString(R.string.action_related))); - detailsOverview.setActionsAdapter(actionAdapter); - mRowsAdapter.add(detailsOverview); - - // Setup related row. - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter( - new CardPresenterSelector(getActivity())); - for (Card characterCard : data.getCharacters()) listRowAdapter.add(characterCard); - HeaderItem header = new HeaderItem(0, getString(R.string.header_related)); - mRowsAdapter.add(new CardListRow(header, listRowAdapter, null)); - - // Setup recommended row. - listRowAdapter = new ArrayObjectAdapter(new CardPresenterSelector(getActivity())); - for (Card card : data.getRecommended()) listRowAdapter.add(card); - header = new HeaderItem(1, getString(R.string.header_recommended)); - mRowsAdapter.add(new ListRow(header, listRowAdapter)); - - setAdapter(mRowsAdapter); - } - - private void setupEventListeners() { - setOnItemViewSelectedListener(this); - setOnItemViewClickedListener(this); - } - - @Override - public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - if (!(item instanceof Action)) return; - Action action = (Action) item; - if (action.getId() == 3) { - setSelectedPosition(1); - } else { - Toast.makeText(getActivity(), getString(R.string.action_cicked), Toast.LENGTH_LONG) - .show(); - } - } - - @Override - public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - if (mRowsAdapter.indexOf(row) > 0) { - int backgroundColor = getResources().getColor(R.color.detail_view_related_background, - null); - getView().setBackgroundColor(backgroundColor); - } else { - getView().setBackgroundResource(R.drawable.background_canyon); - } - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java deleted file mode 100644 index 56cbd3679..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailedCard.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; - -import com.google.gson.annotations.SerializedName; - -public class DetailedCard { - - @SerializedName("title") private String mTitle = ""; - @SerializedName("description") private String mDescription = ""; - @SerializedName("text") private String mText = ""; - @SerializedName("localImageResource") private String mLocalImageResource = null; - @SerializedName("price") private String mPrice = null; - @SerializedName("characters") private Card[] mCharacters = null; - @SerializedName("recommended") private Card[] mRecommended = null; - @SerializedName("year") private int mYear = 0; - - - public String getPrice() { - return mPrice; - } - - public int getYear() { - return mYear; - } - - public String getLocalImageResource() { - return mLocalImageResource; - } - - public String getText() { - return mText; - } - - public String getDescription() { - return mDescription; - } - - public String getTitle() { - return mTitle; - } - - public Card[] getCharacters() { - return mCharacters; - } - - public Card[] getRecommended() { - return mRecommended; - } - - public int getLocalImageResourceId(Context context) { - return context.getResources() - .getIdentifier(getLocalImageResource(), "drawable", context.getPackageName()); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java deleted file mode 100644 index ebb5c53e6..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DetailsDescriptionPresenter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.content.Context; -import android.support.v17.leanback.widget.Presenter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -/** - * This presenter is used to render a {@link DetailedCard} in the {@link - * DetailViewExampleFragment}. - */ -public class DetailsDescriptionPresenter extends Presenter { - - private ResourceCache mResourceCache = new ResourceCache(); - private Context mContext; - - public DetailsDescriptionPresenter(Context context) { - mContext = context; - } - - @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { - View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view_content, null); - return new ViewHolder(view); - } - - @Override public void onBindViewHolder(ViewHolder viewHolder, Object item) { - TextView primaryText = mResourceCache.getViewById(viewHolder.view, R.id.primary_text); - TextView sndText1 = mResourceCache.getViewById(viewHolder.view, R.id.secondary_text_first); - TextView sndText2 = mResourceCache.getViewById(viewHolder.view, R.id.secondary_text_second); - TextView extraText = mResourceCache.getViewById(viewHolder.view, R.id.extra_text); - - DetailedCard card = (DetailedCard) item; - primaryText.setText(card.getTitle()); - sndText1.setText(card.getDescription()); - sndText2.setText(card.getYear() + ""); - extraText.setText(card.getText()); - } - - @Override public void onUnbindViewHolder(ViewHolder viewHolder) { - // Nothing to do here. - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java deleted file mode 100644 index f106df28c..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleActivity.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Activity; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.os.PersistableBundle; -import android.support.v17.leanback.app.GuidedStepFragment; - -/** - * TODO: Javadoc - */ -public class DialogExampleActivity extends Activity { - - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#21272A"))); - - GuidedStepFragment fragment = new DialogExampleFragment(); - GuidedStepFragment.add(getFragmentManager(), fragment); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java deleted file mode 100644 index 384839f62..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/DialogExampleFragment.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.widget.GuidanceStylist.Guidance; -import android.support.v17.leanback.widget.GuidedAction; -import android.widget.Toast; - -import java.util.List; - -/** - * TODO: Javadoc - */ -public class DialogExampleFragment extends GuidedStepFragment { - - private static final int ACTION_ID_POSITIVE = 1; - private static final int ACTION_ID_NEGATIVE = ACTION_ID_POSITIVE + 1; - - @NonNull - @Override - public Guidance onCreateGuidance(Bundle savedInstanceState) { - Guidance guidance = new Guidance(getString(R.string.dialog_example_title), - getString(R.string.dialog_example_description), - "", null); - return guidance; - } - - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - GuidedAction action = new GuidedAction.Builder() - .id(ACTION_ID_POSITIVE) - .title(getString(R.string.dialog_example_button_positive)).build(); - actions.add(action); - action = new GuidedAction.Builder() - .id(ACTION_ID_NEGATIVE) - .title(getString(R.string.dialog_example_button_negative)).build(); - actions.add(action); - } - - @Override - public void onGuidedActionClicked(GuidedAction action) { - if (ACTION_ID_POSITIVE == action.getId()) { - Toast.makeText(getActivity(), R.string.dialog_example_button_toast_positive_clicked, - Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(getActivity(), R.string.dialog_example_button_toast_negative_clicked, - Toast.LENGTH_SHORT).show(); - } - getActivity().finish(); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java deleted file mode 100644 index 507a56c2f..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/GridExample.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.v17.leanback.app.VerticalGridFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.FocusHighlight; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.VerticalGridPresenter; - -import com.google.gson.Gson; - -/** - * An example how to use leanback's {@link VerticalGridFragment}. - */ -public class GridExample extends VerticalGridFragment { - - private static final String TAG = "GridExample"; - private static final int COLUMNS = 4; - private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_NONE; - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTitle(getString(R.string.grid_example_title)); - setupRowAdapter(); - } - - private void setupRowAdapter() { - VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); - gridPresenter.setNumberOfColumns(COLUMNS); - setGridPresenter(gridPresenter); - - PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); - String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); - CardRow row = new Gson().fromJson(json, CardRow.class); - adapter.addAll(0, row.getCards()); - setAdapter(adapter); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java deleted file mode 100644 index e1f5623fb..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainActivity.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Activity; -import android.app.Fragment; -import android.os.Bundle; - -/* - * MainActivity class that loads MainFragment - */ -public class MainActivity extends Activity { - - /** - * Called when the activity is first created. - */ - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - if (savedInstanceState == null) { - Fragment fragment = new MainFragment(); - getFragmentManager().beginTransaction().replace(R.id.fragmentContainer, fragment) - .commit(); - } - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java deleted file mode 100644 index 6486a10b6..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MainFragment.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Fragment; -import android.content.Intent; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Handler; -import android.support.v17.leanback.app.BackgroundManager; -import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.ListRowPresenter; -import android.support.v17.leanback.widget.OnItemViewClickedListener; -import android.support.v17.leanback.widget.OnItemViewSelectedListener; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.util.DisplayMetrics; -import android.util.Log; - -import com.google.gson.Gson; -import com.squareup.picasso.Picasso; -import com.squareup.picasso.Target; - -import java.net.URI; -import java.util.Timer; -import java.util.TimerTask; - - -public class MainFragment extends BrowseFragment { - - public static final String VIDEO_SURFACE_FRAGMENT_TAG = "VIDEO_SURFACE"; - private static final String TAG = "MainFragment"; - private static final int BACKGROUND_UPDATE_DELAY = 300; - private static final int DEFAULT_BACKGROUND_IMAGE = R.drawable.default_background; - private final Handler mHandler = new Handler(); - private ArrayObjectAdapter mRowsAdapter; - private Target mBackgroundTarget; - private Timer mBackgroundTimer; - private URI mBackgroundURI; - private BackgroundManager mBackgroundManager; - private DisplayMetrics mMetrics; - - @Override public void onActivityCreated(Bundle savedInstanceState) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onActivityCreated"); - super.onActivityCreated(savedInstanceState); - - setupBackgroundManager(); - setupUIElements(); - setupRowAdapter(); - setupEventListeners(); - } - - @Override public void onDestroy() { - super.onDestroy(); - if (null != mBackgroundTimer) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onDestroy: " + mBackgroundTimer.toString()); - mBackgroundTimer.cancel(); - } - } - - private void setupRowAdapter() { - mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); - createRows(); - setAdapter(mRowsAdapter); - } - - private void createRows() { - String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.cards_launcher)); - CardRow[] rows = new Gson().fromJson(json, CardRow[].class); - for (CardRow row : rows) { - mRowsAdapter.add(createCardRow(row)); - } - } - - private ListRow createCardRow(CardRow cardRow) { - PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); - for (Card card : cardRow.getCards()) { - listRowAdapter.add(card); - } - return new ListRow(listRowAdapter); - } - - private void setupBackgroundManager() { - mBackgroundManager = BackgroundManager.getInstance(getActivity()); - mBackgroundManager.setThemeDrawableResourceId(DEFAULT_BACKGROUND_IMAGE); - mBackgroundManager.attach(getActivity().getWindow()); - - mBackgroundTarget = new PicassoBackgroundManagerTarget(mBackgroundManager); - mMetrics = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); - getView().setBackgroundResource(R.drawable.bg_living_room_wide); - //updateBackgroundImage(R.drawable.bg_living_room_wide); - } - - private void setupUIElements() { - setTitle(getString(R.string.browse_title)); - setBadgeDrawable(getResources().getDrawable(R.drawable.title_android_tv, null)); - setHeadersState(HEADERS_DISABLED); - setHeadersTransitionOnBackEnabled(false); - setBrandColor(getResources().getColor(R.color.fastlane_background)); - } - - private void setupEventListeners() { - setOnItemViewClickedListener(new ItemViewClickedListener()); - setOnItemViewSelectedListener(new ItemViewSelectedListener()); - } - - protected void updateBackgroundImage(URI uri) { - // Deactivated until we decide whether to load a background image from an URL or resource. @hahnr - if (true) return; - Picasso.with(getActivity()).load(uri.toString()) - .resize(mMetrics.widthPixels, mMetrics.heightPixels).centerCrop() - .error(DEFAULT_BACKGROUND_IMAGE).into(mBackgroundTarget); - } - - protected void updateBackgroundImage(Drawable drawable) { - mBackgroundManager.setDrawable(drawable); - } - - protected void updateBackgroundImage(int resId) { - mBackgroundManager.setDrawable(getResources().getDrawable(resId, null)); - } - - private void startBackgroundTimer() { - if (null != mBackgroundTimer) { - mBackgroundTimer.cancel(); - } - mBackgroundTimer = new Timer(); - mBackgroundTimer.schedule(new UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY); - } - - private final class ItemViewClickedListener implements OnItemViewClickedListener { - - @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - Card card = (Card) item; - int id = card.getId(); - switch (id) { - case 0: { - updateBackgroundImage(new ColorDrawable( - getResources().getColor(R.color.card_examples_background))); - Fragment fragment = new CardExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); - break; - } - case 2: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_canyon, null)); - Fragment fragment = new GridExample(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); - break; - } - case 3: { - Intent intent = new Intent(getActivity().getBaseContext(), - DetailViewExampleActivity.class); - startActivity(intent); - break; - } - case 4: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_canyon, null)); - Fragment fragment = new VideoConsumptionExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, new VideoSurfaceFragment(), - VIDEO_SURFACE_FRAGMENT_TAG) - .add(R.id.fragmentContainer, fragment).addToBackStack(null) - .commit(); - break; - } - case 5: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_sax, null)); - Fragment fragment = new MusicConsumptionExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); - break; - } - case 6: { - // Let's create a new Wizard for a given Movie. The movie can come from any sort - // of data source. To simplify this example we decode it from a JSON source - // which might be loaded from a server in a real world example. - Intent intent = new Intent(getActivity().getBaseContext(), - WizardExampleActivity.class); - - // Prepare extras which contains the Movie and will be passed to the Activity - // which is started through the Intent/. - Bundle extras = new Bundle(); - String json = Utils.inputStreamToString( - getResources().openRawResource(R.raw.wizard_example)); - Movie movie = new Gson().fromJson(json, Movie.class); - extras.putSerializable("movie", movie); - intent.putExtras(extras); - - // Finally, start the wizard Activity. - startActivity(intent); - break; - } - case 7: { - Intent intent = new Intent(getActivity().getBaseContext(), - SettingsExampleActivity.class); - startActivity(intent); - break; - } - case 8: { - Intent intent = new Intent(getActivity().getBaseContext(), - DialogExampleActivity.class); - startActivity(intent); - break; - } - default: - break; - } - } - } - - private final class ItemViewSelectedListener implements OnItemViewSelectedListener { - - @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - } - } - - private class UpdateBackgroundTask extends TimerTask { - - @Override public void run() { - mHandler.post(new Runnable() { - @Override public void run() { - if (mBackgroundURI != null) { - updateBackgroundImage(mBackgroundURI); - } - } - }); - } - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java deleted file mode 100644 index 89d81ee5d..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MediaPlayerGlue.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.net.Uri; -import android.os.Handler; -import android.support.v17.leanback.app.PlaybackControlGlue; -import android.support.v17.leanback.app.PlaybackOverlayFragment; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.ControlButtonPresenterSelector; -import android.support.v17.leanback.widget.OnItemViewSelectedListener; -import android.support.v17.leanback.widget.PlaybackControlsRow; -import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.util.Log; -import android.view.KeyEvent; -import android.view.SurfaceHolder; -import android.view.View; - -import java.io.IOException; - -/** - * This glue extends the {@link PlaybackControlGlue} with a {@link MediaPlayer} synchronization. It - * supports 7 actions:

  • {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction}
  • - *
  • {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}
  • {@link - * android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction}
  • {@link - * android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction}
  • {@link - * android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction}
  • {@link - * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction}
  • {@link - * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction}
- *

- */ -public abstract class MediaPlayerGlue extends PlaybackControlGlue implements - OnItemViewSelectedListener { - - public static final int FAST_FORWARD_REWIND_STEP = 10 * 1000; // in milliseconds - public static final int FAST_FORWARD_REWIND_REPEAT_DELAY = 200; // in milliseconds - private static final String TAG = "MediaPlayerGlue"; - protected final PlaybackControlsRow.ThumbsDownAction mThumbsDownAction; - protected final PlaybackControlsRow.ThumbsUpAction mThumbsUpAction; - private final Context mContext; - private final MediaPlayer mPlayer = new MediaPlayer(); - private final PlaybackControlsRow.RepeatAction mRepeatAction; - private final PlaybackControlsRow.ShuffleAction mShuffleAction; - private PlaybackControlsRow mControlsRow; - private Runnable mRunnable; - private Handler mHandler = new Handler(); - private boolean mPaused = false; - private boolean mInitialized = false; // true when the MediaPlayer is prepared/initialized - private OnMediaFileFinishedPlayingListener mMediaFileFinishedPlayingListener; - private Action mSelectedAction; // the action which is currently selected by the user - private long mLastKeyDownEvent = 0L; // timestamp when the last DPAD_CENTER KEY_DOWN occurred - private MetaData mMetaData; - private Uri mMediaSourceUri = null; - private String mMediaSourcePath = null; - - public MediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { - super(context, fragment, new int[]{1}); - mContext = context; - - // Instantiate secondary actions - mShuffleAction = new PlaybackControlsRow.ShuffleAction(mContext); - mRepeatAction = new PlaybackControlsRow.RepeatAction(mContext); - mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(mContext); - mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(mContext); - mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); - mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); - - // Setup controls and notify UI about change. - setFadingEnabled(false); - onStateChanged(); - - // Register selected listener such that we know what action the user currently has focused. - fragment.setOnItemViewSelectedListener(this); - } - - /** - * Will reset the {@link MediaPlayer} and the glue such that a new file can be played. You are - * not required to call this method before playing the first file. However you have to call it - * before playing a second one. - */ - public void reset() { - mPaused = mInitialized = false; - mPlayer.reset(); - } - - public void setOnMediaFileFinishedPlayingListener(OnMediaFileFinishedPlayingListener listener) { - mMediaFileFinishedPlayingListener = listener; - } - - /** - * Override this method in case you need to add different secondary actions. - * - * @param secondaryActionsAdapter The adapter you need to add the {@link Action}s to. - */ - protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { - secondaryActionsAdapter.add(mShuffleAction); - secondaryActionsAdapter.add(mRepeatAction); - secondaryActionsAdapter.add(mThumbsDownAction); - secondaryActionsAdapter.add(mThumbsUpAction); - } - - /** - * @see MediaPlayer#setDisplay(SurfaceHolder) - */ - public void setDisplay(SurfaceHolder surfaceHolder) { - mPlayer.setDisplay(surfaceHolder); - } - - /** - * Use this method to setup the {@link PlaybackControlsRowPresenter}. It'll be called - * after the {@link PlaybackControlsRowPresenter} has been created and the primary and - * secondary actions have been added. - * - * @param presenter The PlaybackControlsRowPresenter used to display the controls. - */ - public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { - // TODO: hahnr@ move into resources - presenter.setProgressColor(Color.parseColor("#feab91")); - presenter.setBackgroundColor(Color.parseColor("#db2a0f")); - } - - @Override public PlaybackControlsRowPresenter createControlsRowAndPresenter() { - PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter(); - mControlsRow = getControlsRow(); - - // Add secondary actions and change the control row color. - ArrayObjectAdapter secondaryActions = new ArrayObjectAdapter( - new ControlButtonPresenterSelector()); - mControlsRow.setSecondaryActionsAdapter(secondaryActions); - addSecondaryActions(secondaryActions); - setupControlsRowPresenter(presenter); - return presenter; - } - - @Override public void enableProgressUpdating(final boolean enabled) { - if (!enabled) { - if (mRunnable != null) mHandler.removeCallbacks(mRunnable); - return; - } - mRunnable = new Runnable() { - @Override public void run() { - updateProgress(); - Log.d(TAG, "enableProgressUpdating(boolean)"); - mHandler.postDelayed(this, getUpdatePeriod()); - } - }; - mHandler.postDelayed(mRunnable, getUpdatePeriod()); - } - - @Override public void onActionClicked(Action action) { - // If either 'Shuffle' or 'Repeat' has been clicked we need to make sure the acitons index - // is incremented and the UI updated such that we can display the new state. - super.onActionClicked(action); - if (action instanceof PlaybackControlsRow.ShuffleAction) { - mShuffleAction.nextIndex(); - } else if (action instanceof PlaybackControlsRow.RepeatAction) { - mRepeatAction.nextIndex(); - } else if (action instanceof PlaybackControlsRow.ThumbsUpAction) { - if (mThumbsUpAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { - mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); - } else { - mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); - mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); - } - } else if (action instanceof PlaybackControlsRow.ThumbsDownAction) { - if (mThumbsDownAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { - mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); - } else { - mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); - mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); - } - } - onMetadataChanged(); - } - - @Override public boolean onKey(View v, int keyCode, KeyEvent event) { - // This method is overridden in order to make implement fast forwarding and rewinding when - // the user keeps the corresponding action pressed. - // We only consume DPAD_CENTER Action_DOWN events on the Fast-Forward and Rewind action and - // only if it has not been pressed in the last X milliseconds. - boolean consume = mSelectedAction instanceof PlaybackControlsRow.RewindAction; - consume = consume || mSelectedAction instanceof PlaybackControlsRow.FastForwardAction; - consume = consume && mInitialized; - consume = consume && event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER; - consume = consume && event.getAction() == KeyEvent.ACTION_DOWN; - consume = consume && System - .currentTimeMillis() - mLastKeyDownEvent > FAST_FORWARD_REWIND_REPEAT_DELAY; - if (consume) { - mLastKeyDownEvent = System.currentTimeMillis(); - int newPosition = getCurrentPosition() + FAST_FORWARD_REWIND_STEP; - if (mSelectedAction instanceof PlaybackControlsRow.RewindAction) { - newPosition = getCurrentPosition() - FAST_FORWARD_REWIND_STEP; - } - // Make sure the new calculated duration is in the range 0 >= X >= MediaDuration - if (newPosition < 0) newPosition = 0; - if (newPosition > getMediaDuration()) newPosition = getMediaDuration(); - seekTo(newPosition); - return true; - } - return super.onKey(v, keyCode, event); - } - - @Override public boolean hasValidMedia() { - return mMetaData != null; - } - - @Override public boolean isMediaPlaying() { - return mPlayer.isPlaying(); - } - - @Override public CharSequence getMediaTitle() { - return hasValidMedia() ? mMetaData.getTitle() : "N/a"; - } - - @Override public CharSequence getMediaSubtitle() { - return hasValidMedia() ? mMetaData.getArtist() : "N/a"; - } - - @Override public int getMediaDuration() { - return mInitialized ? mPlayer.getDuration() : 0; - } - - @Override public Drawable getMediaArt() { - return hasValidMedia() ? mMetaData.getCover() : null; - } - - @Override public long getSupportedActions() { - return PlaybackControlGlue.ACTION_PLAY_PAUSE | PlaybackControlGlue.ACTION_FAST_FORWARD | PlaybackControlGlue.ACTION_REWIND; - } - - @Override public int getCurrentSpeedId() { - // 0 = Pause, 1 = Normal Playback Speed - return mPlayer.isPlaying() ? 1 : 0; - } - - @Override public int getCurrentPosition() { - return mInitialized ? mPlayer.getCurrentPosition() : 0; - } - - @Override protected void startPlayback(int speed) throws IllegalStateException { - if (mPaused) { - mPlayer.start(); - } else if (!isMediaPlaying()) { - reset(); - try { - if (mMediaSourceUri != null) mPlayer.setDataSource(getContext(), mMediaSourceUri); - else mPlayer.setDataSource(mMediaSourcePath); - } catch (IOException e) { - throw new RuntimeException(e); - } - mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); - mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { - @Override public void onPrepared(MediaPlayer mp) { - mInitialized = true; - mPaused = false; - mPlayer.start(); - onMetadataChanged(); - onStateChanged(); - updateProgress(); - } - }); - mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { - @Override public void onCompletion(MediaPlayer mp) { - if (mInitialized && mMediaFileFinishedPlayingListener != null) - mMediaFileFinishedPlayingListener.onMediaFileFinishedPlaying(mMetaData); - } - }); - mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { - @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { - mControlsRow.setBufferedProgress((int) (mp.getDuration() * (percent / 100f))); - } - }); - mPlayer.prepareAsync(); - onStateChanged(); - } - } - - @Override protected void pausePlayback() { - if (mPlayer.isPlaying()) { - mPlayer.pause(); - mPaused = true; - } - } - - @Override protected void skipToNext() { - // Not supported. - } - - @Override protected void skipToPrevious() { - // Not supported. - } - - /** - * Called whenever the user presses fast-forward/rewind or when the user keeps the corresponding - * action pressed. - * - * @param newPosition The new position of the media track in milliseconds. - */ - protected void seekTo(int newPosition) { - mPlayer.seekTo(newPosition); - } - - /** - * @see MediaPlayer#setDataSource(Context, Uri) - */ - public void setMediaSource(Uri uri) { - mMediaSourceUri = uri; - } - - /** - * @see MediaPlayer#setDataSource(String) - */ - public void setMediaSource(String path) { - mMediaSourcePath = path; - } - - /** - * Call to startPlayback(1). - * - * @throws IllegalStateException See {@link MediaPlayer} for further information about it's - * different states when setting a data source and preparing it to be played. - */ - public void startPlayback() throws IllegalStateException { - startPlayback(1); - } - - /** - * @return Returns true iff 'Shuffle' is ON. - */ - public boolean useShuffle() { - return mShuffleAction.getIndex() == PlaybackControlsRow.ShuffleAction.ON; - } - - /** - * @return Returns true iff 'Repeat-One' is ON. - */ - public boolean repeatOne() { - return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ONE; - } - - /** - * @return Returns true iff 'Repeat-All' is ON. - */ - public boolean repeatAll() { - return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ALL; - } - - public void setMetaData(MetaData metaData) { - mMetaData = metaData; - onMetadataChanged(); - } - - /** - * This is a listener implementation for the {@link OnItemViewSelectedListener} of the {@link - * PlaybackOverlayFragment}. This implementation is required in order to detect KEY_DOWN events - * on the {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction} and - * {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}. Thus you should - * NOT set another {@link OnItemViewSelectedListener} on your {@link - * PlaybackOverlayFragment}. Instead, override this method and call its super (this) - * implementation. - * - * @see OnItemViewSelectedListener#onItemSelected(Presenter.ViewHolder, Object, - * RowPresenter.ViewHolder, Row) - */ - @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - if (item instanceof Action) { - mSelectedAction = (Action) item; - } else { - mSelectedAction = null; - } - } - - /** - * A listener which will be called whenever a track is finished playing. - */ - public interface OnMediaFileFinishedPlayingListener { - - /** - * Called when a track is finished playing. - * - * @param metaData The track's {@link MetaData} which just finished playing. - */ - void onMediaFileFinishedPlaying(MetaData metaData); - - } - - /** - * Holds the meta data such as track title, artist and cover art. It'll be used by the {@link - * MediaPlayerGlue}. - */ - public static class MetaData { - - private String mTitle; - private String mArtist; - private Drawable mCover; - - - public String getTitle() { - return mTitle; - } - - public void setTitle(String title) { - this.mTitle = title; - } - - public String getArtist() { - return mArtist; - } - - public void setArtist(String artist) { - this.mArtist = artist; - } - - public Drawable getCover() { - return mCover; - } - - public void setCover(Drawable cover) { - this.mCover = cover; - } - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java deleted file mode 100644 index 4d590aebd..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Movie.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import com.google.gson.annotations.SerializedName; - -import java.io.Serializable; - -public class Movie implements Serializable { - - private static final long serialVersionUID = 133742L; - - @SerializedName("title") - private String mTitle = ""; - @SerializedName("price_hd") - private String mPriceHd = "n/a"; - @SerializedName("price_sd") - private String mPriceSd = "n/a"; - @SerializedName("breadcrump") - private String mBreadcrump = ""; - - public String getTitle() { - return mTitle; - } - - public String getBreadcrump() { - return mBreadcrump; - } - - public String getPriceHd() { - return mPriceHd; - } - - public String getPriceSd() { - return mPriceSd; - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java deleted file mode 100644 index 17e010a93..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/MusicConsumptionExampleFragment.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.net.Uri; -import android.os.Bundle; -import android.support.v17.leanback.app.PlaybackOverlayFragment; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Song; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.SongList; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.ClassPresenterSelector; -import android.support.v17.leanback.widget.OnItemViewClickedListener; -import android.support.v17.leanback.widget.PlaybackControlsRow; -import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.util.Log; - -import com.google.gson.Gson; - -import java.util.List; - -/** - * This example shows how to play music files and build a simple track list. - */ -public class MusicConsumptionExampleFragment extends PlaybackOverlayFragment implements - OnItemViewClickedListener, Song.OnSongRowClickListener, - MediaPlayerGlue.OnMediaFileFinishedPlayingListener { - - private static final String TAG = "MusicConsumptionExampleFragment"; - private ArrayObjectAdapter mRowsAdapter; - private MediaPlayerGlue mGlue; - private int mCurrentSongIndex = 0; - private List mSongList; - private boolean mAdapterNotified = false; - - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreate"); - - mGlue = new MediaPlayerGlue(getActivity(), this) { - - @Override protected void onRowChanged(PlaybackControlsRow row) { - if (mRowsAdapter == null || mAdapterNotified) return; - //mAdapterNotified = true; - mRowsAdapter.notifyArrayItemRangeChanged(0, 1); - } - }; - mGlue.setOnMediaFileFinishedPlayingListener(this); - - String json = Utils.inputStreamToString( - getResources().openRawResource(R.raw.music_consumption_example)); - mSongList = new Gson().fromJson(json, SongList.class).getSongs(); - Song song = mSongList.get(mCurrentSongIndex); - MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); - metaData.setArtist(song.getDescription()); - metaData.setTitle(song.getTitle()); - metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); - Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); - mGlue.setMetaData(metaData); - mGlue.setMediaSource(uri); - - setBackgroundType(PlaybackOverlayFragment.BG_LIGHT); - addPlaybackControlsRow(); - } - - @Override public void onStart() { - super.onStart(); - mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); - } - - @Override public void onStop() { - super.onStop(); - mGlue.enableProgressUpdating(false); - mGlue.reset(); - } - - private void addPlaybackControlsRow() { - final PlaybackControlsRowPresenter controlsPresenter = mGlue - .createControlsRowAndPresenter(); - ClassPresenterSelector selector = new ClassPresenterSelector(); - Song.Presenter songPresenter = new Song.Presenter(getActivity()); - songPresenter.setOnClickListener(this); - selector.addClassPresenter(Song.class, songPresenter); - selector.addClassPresenter(TrackListHeader.class, - new TrackListHeader.Presenter(getActivity())); - selector.addClassPresenter(PlaybackControlsRow.class, controlsPresenter); - mRowsAdapter = new ArrayObjectAdapter(selector); - mRowsAdapter.add(mGlue.getControlsRow()); - mRowsAdapter.add(new TrackListHeader()); - mRowsAdapter.addAll(2, mSongList); - setAdapter(mRowsAdapter); - setOnItemViewClickedListener(this); - } - - @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - if (!(item instanceof Action)) return; - mGlue.onActionClicked((Action) item); - } - - - @Override public void onSongRowClicked(Song song) { - mCurrentSongIndex = mSongList.indexOf(song); - startPlayback(); - } - - - @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData song) { - if (mGlue.repeatOne()) { - startPlayback(); - return; - } - if (mGlue.useShuffle()) { - mCurrentSongIndex = (int) (Math.random() * mSongList.size()); - } else mCurrentSongIndex++; - if (mCurrentSongIndex >= mSongList.size()) { - mCurrentSongIndex = 0; - if (!mGlue.repeatAll()) return; - } - startPlayback(); - } - - private void startPlayback() { - Song song = mSongList.get(mCurrentSongIndex); - MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); - metaData.setArtist(song.getDescription()); - metaData.setTitle(song.getTitle()); - metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); - - Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); - mGlue.setMetaData(metaData); - mGlue.setMediaSource(uri); - mGlue.startPlayback(); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java deleted file mode 100644 index 012c08e6d..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/PicassoBackgroundManagerTarget.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.support.v17.leanback.app.BackgroundManager; - -import com.squareup.picasso.Picasso; -import com.squareup.picasso.Target; - -/** - * Picasso target for updating default_background images - */ -public class PicassoBackgroundManagerTarget implements Target { - - private BackgroundManager mBackgroundManager; - - public PicassoBackgroundManagerTarget(BackgroundManager backgroundManager) { - this.mBackgroundManager = backgroundManager; - } - - @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) { - this.mBackgroundManager.setBitmap(bitmap); - } - - @Override public void onBitmapFailed(Drawable drawable) { - this.mBackgroundManager.setDrawable(drawable); - } - - @Override public void onPrepareLoad(Drawable drawable) { - // Do nothing, default_background manager has its own transitions - } - - @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - PicassoBackgroundManagerTarget that = (PicassoBackgroundManagerTarget) o; - - if (!mBackgroundManager.equals(that.mBackgroundManager)) return false; - - return true; - } - - @Override public int hashCode() { - return mBackgroundManager.hashCode(); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java deleted file mode 100644 index c7c858939..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ResourceCache.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.util.SparseArray; -import android.view.View; - -/** - * ResourceCache allows retrieving children from a given view and caches the resulting views in - * order to prevent future lookups. - */ -public class ResourceCache { - - private final SparseArray mCachedViews = new SparseArray(); - - public ViewType getViewById(View view, int resId) { - View child = mCachedViews.get(resId, null); - if (child == null) { - child = view.findViewById(resId); - mCachedViews.put(resId, child); - } - return (ViewType) child; - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java deleted file mode 100644 index dee2cab92..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleActivity.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Activity; -import android.app.Fragment; -import android.os.Bundle; - -/* - * TODO: Javadoc - */ -public class SettingsExampleActivity extends Activity { - - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_settings_example); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java deleted file mode 100644 index 44930f2b4..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SettingsExampleFragment.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import android.support.v14.preference.PreferenceFragment; -import android.support.v17.preference.LeanbackPreferenceDialogFragment; -import android.support.v17.preference.LeanbackPreferenceFragment; -import android.support.v17.preference.LeanbackSettingsFragment; -import android.support.v7.preference.DialogPreference; -import android.support.v7.preference.ListPreference; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; -import android.util.Log; - -import java.util.Stack; - -public class SettingsExampleFragment extends LeanbackSettingsFragment implements DialogPreference.TargetFragment { - - public static final String TAG = "SettingsExampleFragment"; - private final Stack fragments = new Stack(); - - @Override - public void onPreferenceStartInitialScreen() { - startPreferenceFragment(buildPreferenceFragment(R.xml.prefs, null)); - } - - @Override - public boolean onPreferenceStartFragment(PreferenceFragment preferenceFragment, - Preference preference) { - return false; - } - - @Override - public boolean onPreferenceStartScreen(PreferenceFragment preferenceFragment, - PreferenceScreen preferenceScreen) { - PreferenceFragment frag = buildPreferenceFragment(R.xml.prefs, preferenceScreen.getKey()); - if ("prefs_wifi_screen_key".equals(preferenceScreen.getKey())) { - ListPreference pref = (ListPreference)preferenceScreen.findPreference("prefs_wifi_key"); - pref.setEntries(new String[] {"Wi-Fi Network 01"}); - pref.setEntryValues(new String[] {"01"}); - if (Constants.LOCAL_LOGD) Log.d(TAG, "pref: " + pref); - } - startPreferenceFragment(frag); - return true; - } - - @Override - public Preference findPreference(CharSequence prefKey) { - return ((PreferenceFragment) fragments.peek()).findPreference(prefKey); - } - - private PreferenceFragment buildPreferenceFragment(int preferenceResId, String root) { - PreferenceFragment fragment = new PrefFragment(); - Bundle args = new Bundle(); - args.putInt("preferenceResource", preferenceResId); - args.putString("root", root); - fragment.setArguments(args); - return fragment; - } - - private class PrefFragment extends LeanbackPreferenceFragment { - - @Override - public void onCreatePreferences(Bundle bundle, String s) { - String root = getArguments().getString("root", null); - int prefResId = getArguments().getInt("preferenceResource"); - if (root == null) { - addPreferencesFromResource(prefResId); - } else { - setPreferencesFromResource(prefResId, root); - } - } - - @Override - public void onAttach(Context context) { - fragments.push(this); - super.onAttach(context); - } - - @Override - public void onDetach() { - fragments.pop(); - super.onDetach(); - } - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java deleted file mode 100644 index f11a26cd8..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/ShadowRowPresenterSelector.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.support.v17.leanback.supportleanbackshowcase.cards.models.CardRow; -import android.support.v17.leanback.widget.ListRowPresenter; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.PresenterSelector; - -/** - * This {@link PresenterSelector} will return a {@link ListRowPresenter} which has shadow support - * enabled or not depending on {@link CardRow#useShadow()} for a given row. - */ -public class ShadowRowPresenterSelector extends PresenterSelector { - - private ListRowPresenter mShadowEnabledRowPresenter = new ListRowPresenter(); - private ListRowPresenter mShadowDisabledRowPresenter = new ListRowPresenter(); - - public ShadowRowPresenterSelector() { - mShadowDisabledRowPresenter.setShadowEnabled(false); - } - - @Override public Presenter getPresenter(Object item) { - if (!(item instanceof CardListRow)) return mShadowDisabledRowPresenter; - CardListRow listRow = (CardListRow) item; - CardRow row = listRow.getCardRow(); - if (row.useShadow()) return mShadowEnabledRowPresenter; - return mShadowDisabledRowPresenter; - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java deleted file mode 100644 index 53a60d770..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/SongListRow.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.support.v17.leanback.widget.Row; - -public class SongListRow extends Row {} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java deleted file mode 100644 index a68a37479..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/TrackListHeader.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.content.Context; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -public class TrackListHeader extends Row { - - public static class Presenter extends RowPresenter { - - private final Context mContext; - - public Presenter(Context context) { - mContext = context; - setHeaderPresenter(null); - } - - @Override public boolean isUsingDefaultSelectEffect() { - return false; - } - - @Override protected ViewHolder createRowViewHolder(ViewGroup parent) { - View view = LayoutInflater.from(mContext).inflate(R.layout.row_track_list_header, parent, false); - view.setFocusable(false); - view.setFocusableInTouchMode(false); - return new ViewHolder(view); - } - } - - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java deleted file mode 100644 index 61efee9e8..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/Utils.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.content.ContentResolver; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.widget.ImageView; - -import com.squareup.picasso.Picasso; -import com.squareup.picasso.RequestCreator; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; - -/** - * A collection of utility methods, all static. - */ -public class Utils { - - public static int convertDpToPixel(Context ctx, int dp) { - float density = ctx.getResources().getDisplayMetrics().density; - return Math.round((float) dp * density); - } - - /** - * Will read the content from a given {@link InputStream} and return it as a {@link String}. - * - * @param inputStream The {@link InputStream} which should be read. - * @return Returns null if the the {@link InputStream} could not be read. Else - * returns the content of the {@link InputStream} as {@link String}. - */ - public static String inputStreamToString(InputStream inputStream) { - try { - byte[] bytes = new byte[inputStream.available()]; - inputStream.read(bytes, 0, bytes.length); - String json = new String(bytes); - return json; - } catch (IOException e) { - return null; - } - } - - /** - * The method uses {@link Picasso} to fetch an image from a given url, resize it (if required) - * and display it inside an {@link ImageView}. - * - * @param context Context which is used to create a {@link Picasso} instance. - * @param uri The {@link URI} to fetch the image from. - * @param target The {@link ImageView} which shall display the image. - * @param resizeWidthInDp The target width of the image. Pass -1 if you don't want - * to resize the image. - * @param resizeHeightInDp The target height of the image. Pass -1 if you don't - * want to resize the image. - * @param centerCrop Centers and scales an image to fit the requested bounds. - * @param errorDrawable A drawable which will be shown in case the image could not be fetched - * from the server. - * @see {@link Picasso#with(Context)} - * @see {@link RequestCreator#resize(int, int)} - * @see {@link RequestCreator#centerCrop()} - * @see {@link RequestCreator#error(Drawable)} - */ - public static void loadImageFromUri(Context context, URI uri, ImageView target, - int resizeWidthInDp, int resizeHeightInDp, - boolean centerCrop, Drawable errorDrawable) { - if (uri == null) return; - RequestCreator builder = Picasso.with(context).load(uri.toString()); - if (resizeHeightInDp != -1 && resizeWidthInDp != -1) - builder.resize(Utils.convertDpToPixel(context, resizeWidthInDp), - Utils.convertDpToPixel(context, resizeHeightInDp)); - if (centerCrop) builder.centerCrop(); - builder.error(errorDrawable).into(target); - } - - public static Uri getResourceUri(Context context, int resID) { - return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + - context.getResources().getResourcePackageName(resID) + '/' + - context.getResources().getResourceTypeName(resID) + '/' + - context.getResources().getResourceEntryName(resID)); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java deleted file mode 100644 index 29e82a875..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoConsumptionExampleFragment.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Fragment; -import android.os.Bundle; -import android.support.v17.leanback.app.PlaybackOverlayFragment; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.OnItemViewClickedListener; -import android.support.v17.leanback.widget.PlaybackControlsRow; -import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; -import android.support.v17.leanback.widget.Presenter; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.util.Log; -import android.view.SurfaceHolder; -import android.view.SurfaceView; - - -public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment implements - OnItemViewClickedListener, MediaPlayerGlue.OnMediaFileFinishedPlayingListener { - - private static final String URL = "http://techslides.com/demos/sample-videos/small.mp4"; - private ArrayObjectAdapter mRowsAdapter; - private MediaPlayerGlue mGlue; - - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mGlue = new VideoMediaPlayerGlue(getActivity(), this) { - - @Override protected void onRowChanged(PlaybackControlsRow row) { - if (mRowsAdapter == null) return; - mRowsAdapter.notifyArrayItemRangeChanged(0, 1); - } - }; - mGlue.setOnMediaFileFinishedPlayingListener(this); - MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); - metaData.setArtist("A Googler"); - metaData.setTitle("Diving with Sharks"); - mGlue.setMetaData(metaData); - mGlue.setMediaSource(URL); - - Fragment videoSurfaceFragment = getFragmentManager() - .findFragmentByTag(MainFragment.VIDEO_SURFACE_FRAGMENT_TAG); - SurfaceView surface = (SurfaceView) videoSurfaceFragment.getView(); - surface.getHolder().addCallback(new SurfaceHolder.Callback() { - @Override public void surfaceCreated(SurfaceHolder holder) { - mGlue.setDisplay(holder); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - // Nothing to do - } - - @Override public void surfaceDestroyed(SurfaceHolder holder) { - } - }); - - setBackgroundType(PlaybackOverlayFragment.BG_LIGHT); - addPlaybackControlsRow(); - } - - @Override public void onStart() { - super.onStart(); - mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); - } - - @Override public void onStop() { - super.onStop(); - mGlue.enableProgressUpdating(false); - mGlue.reset(); - } - - private void addPlaybackControlsRow() { - final PlaybackControlsRowPresenter controlsPresenter = mGlue - .createControlsRowAndPresenter(); - mRowsAdapter = new ArrayObjectAdapter(controlsPresenter); - mRowsAdapter.add(mGlue.getControlsRow()); - setAdapter(mRowsAdapter); - setOnItemViewClickedListener(this); - } - - @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - if (!(item instanceof Action)) return; - mGlue.onActionClicked((Action) item); - } - - - @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData metaData) { - mGlue.startPlayback(); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java deleted file mode 100644 index 79aacd310..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoMediaPlayerGlue.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.content.Context; -import android.graphics.Color; -import android.support.v17.leanback.app.PlaybackOverlayFragment; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.PlaybackControlsRow; -import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; - -public abstract class VideoMediaPlayerGlue extends MediaPlayerGlue { - - private final PlaybackControlsRow.ClosedCaptioningAction mClosedCaptioningAction; - - public VideoMediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { - super(context, fragment); - - // Instantiate secondary actions - mClosedCaptioningAction = new PlaybackControlsRow.ClosedCaptioningAction(context); - setFadingEnabled(true); - } - - @Override protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { - secondaryActionsAdapter.add(mClosedCaptioningAction); - secondaryActionsAdapter.add(mThumbsDownAction); - secondaryActionsAdapter.add(mThumbsUpAction); - } - - @Override public void onActionClicked(Action action) { - super.onActionClicked(action); - if (action == mClosedCaptioningAction) { - mClosedCaptioningAction.nextIndex(); - } - } - - public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { - // TODO: hahnr@ move into resources - presenter.setProgressColor(Color.parseColor("#EEFF41")); - presenter.setBackgroundColor(Color.parseColor("#007236")); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java deleted file mode 100644 index 5f25c2806..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/VideoSurfaceFragment.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Fragment; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - - -public class VideoSurfaceFragment extends Fragment { - - private static final String TAG = "VideoSurfaceFragment"; - - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - } - - @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.video_surface_fragment, null); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java deleted file mode 100644 index 4c4200ed8..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample1stStepFragment.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.widget.GuidanceStylist; -import android.support.v17.leanback.widget.GuidedAction; -import android.support.v17.leanback.widget.GuidedActionsStylist; -import android.view.ContextThemeWrapper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import java.util.List; - -/** - * TODO: JavaDoc - */ -public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment { - - private static final int ACTION_ID_BUY_HD = 1; - private static final int ACTION_ID_BUY_SD = ACTION_ID_BUY_HD + 1; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(1); - } - - @NonNull - @Override - public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), - getString(R.string.wizard_example_choose_rent_options), - mMovie.getBreadcrump(), null); - return guidance; - } - - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - GuidedAction action = new GuidedAction.Builder() - .id(ACTION_ID_BUY_HD) - .title(getString(R.string.wizard_example_rent_hd)) - .description(mMovie.getPriceHd() + " " + - getString(R.string.wizard_example_watch_hd)) - .build(); - actions.add(action); - action = new GuidedAction.Builder() - .id(ACTION_ID_BUY_SD) - .title(getString(R.string.wizard_example_rent_sd)) - .description(mMovie.getPriceSd() + " " + - getString(R.string.wizard_example_watch_sd)) - .build(); - actions.add(action); - } - - @Override - public void onGuidedActionClicked(GuidedAction action) { - GuidedStepFragment fragment = new WizardExample2ndStepFragment(); - Bundle args = getArguments(); // Reuse the same arguments this fragment was given. - args.putBoolean("hd", ACTION_ID_BUY_HD == action.getId()); - fragment.setArguments(args); - add(getFragmentManager(), fragment); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java deleted file mode 100644 index ea532880b..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample2ndStepFragment.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.widget.GuidanceStylist; -import android.support.v17.leanback.widget.GuidedAction; -import android.support.v17.leanback.widget.GuidedActionsStylist; -import android.widget.Toast; - -import java.util.List; - -/** - * TODO: JavaDoc - */ -public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment { - - private static final int ACTION_ID_CONFIRM = 1; - private static final int ACTION_ID_PAYMENT_METHOD = ACTION_ID_CONFIRM + 1; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(2); - } - - @NonNull - @Override - public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), - getString(R.string.wizard_example_rental_period), - mMovie.getBreadcrump(), null); - return guidance; - } - - @Override - public GuidedActionsStylist onCreateActionsStylist() { - GuidedActionsStylist stylist = new GuidedActionsStylist() { - - @Override - public void onBindViewHolder(ViewHolder vh, GuidedAction action) { - super.onBindViewHolder(vh, action); - - if (ACTION_ID_CONFIRM == action.getId()) { - Drawable background = getResources().getDrawable( - R.drawable.wizard_important_action_item_background, null); - vh.view.setBackground(background); - vh.getTitleView().setTextColor(Color.parseColor("#666666")); - vh.getDescriptionView().setTextColor(Color.parseColor("#666666")); - } else { - vh.view.setBackground(null); - vh.getTitleView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, - getActivity().getTheme())); - vh.getDescriptionView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, - getActivity().getTheme())); - } - } - }; - return stylist; - } - - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - boolean rentHighDefinition = getArguments().getBoolean("hd"); - - GuidedAction action = new GuidedAction.Builder() - .id(ACTION_ID_CONFIRM) - .title(getString(R.string.wizard_example_rent)) - .description(rentHighDefinition ? mMovie.getPriceHd() : mMovie.getPriceSd()) - .build(); - actions.add(action); - action = new GuidedAction.Builder() - .id(ACTION_ID_PAYMENT_METHOD) - .title(getString(R.string.wizard_example_payment_method)) - .description("Visa - 1234 Balance $60.00") - .build(); - actions.add(action); - } - - @Override - public void onGuidedActionClicked(GuidedAction action) { - if (ACTION_ID_PAYMENT_METHOD == action.getId()) { - Toast.makeText(getActivity(), - getString(R.string.wizard_example_toast_payment_method_clicked), - Toast.LENGTH_SHORT).show(); - } else { - GuidedStepFragment fragment = new WizardExample3rdStepFragment(); - fragment.setArguments(getArguments()); - add(getFragmentManager(), fragment); - } - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java deleted file mode 100644 index fccf7c9ee..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample3rdStepFragment.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.os.Handler; -import android.support.annotation.NonNull; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.widget.GuidanceStylist; -import android.support.v17.leanback.widget.GuidedAction; -import android.support.v17.leanback.widget.GuidedActionsStylist; - -import java.util.List; - -/** - * TODO: JavaDoc - */ -public class WizardExample3rdStepFragment extends WizardExampleBaseStepFragment { - - private static final int ACTION_ID_PROCESSING = 1; - private final Handler mFakeHttpHandler = new Handler(); - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(3); - } - - @Override - public void onStart() { - super.onStart(); - - // Fake Http call by creating some sort of delay. - mFakeHttpHandler.postDelayed(fakeHttpRequestRunnable, 4000L); - } - - @Override - public GuidedActionsStylist onCreateActionsStylist() { - GuidedActionsStylist stylist = new GuidedActionsStylist() { - @Override - public int onProvideItemLayoutId() { - return R.layout.wizard_progress_action_item; - } - - @Override - public int onProvideLayoutId() { - return R.layout.wizard_progress_action_container; - } - }; - return stylist; - } - - @Override - public void onStop() { - super.onStop(); - - // Make sure to cancel the execution of the Runnable in case the fragment is stopped. - mFakeHttpHandler.removeCallbacks(fakeHttpRequestRunnable); - } - - @NonNull - @Override - public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), - "Just a second...", - mMovie.getBreadcrump(), null); - return guidance; - } - - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - GuidedAction action = new GuidedAction.Builder() - .id(ACTION_ID_PROCESSING) - .title(getString(R.string.wizard_example_processing)) - .infoOnly(true) - .build(); - actions.add(action); - } - - private final Runnable fakeHttpRequestRunnable = new Runnable() { - @Override - public void run() { - GuidedStepFragment fragment = new WizardExample4thStepFragment(); - fragment.setArguments(getArguments()); - add(getFragmentManager(), fragment); - } - }; - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java deleted file mode 100644 index 82a8a3d65..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExample4thStepFragment.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.widget.GuidanceStylist; -import android.support.v17.leanback.widget.GuidedAction; -import android.widget.Toast; - -import java.util.List; - -/** - * TODO: JavaDoc - */ -public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment { - - private static final int ACTION_ID_WATCH = 1; - private static final int ACTION_ID_LATER = ACTION_ID_WATCH + 1; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(4); - } - - @NonNull - @Override - public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), - getString(R.string.wizard_example_rental_period), - mMovie.getBreadcrump(), null); - return guidance; - } - - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - GuidedAction action = new GuidedAction.Builder() - .id(ACTION_ID_WATCH) - .title(getString(R.string.wizard_example_watch_now)) - .build(); - actions.add(action); - action = new GuidedAction.Builder() - .id(ACTION_ID_LATER) - .title(getString(R.string.wizard_example_later)) - .build(); - actions.add(action); - } - - @Override - public void onGuidedActionClicked(GuidedAction action) { - if (ACTION_ID_WATCH == action.getId()) { - Toast.makeText(getActivity(), getString(R.string.wizard_example_watch_now_clicked), - Toast.LENGTH_SHORT).show(); - } - getActivity().finish(); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java deleted file mode 100644 index 819fc774c..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleActivity.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.app.Activity; -import android.app.Fragment; -import android.os.Bundle; -import android.os.PersistableBundle; -import android.support.v17.leanback.app.BackgroundManager; -import android.support.v17.leanback.app.GuidedStepFragment; - -/** - * TODO: Javadoc - */ -public class WizardExampleActivity extends Activity { - - // When the user 'bought' the product and presses back, we don't want to show the 'Processing..' - // screen again, instead we want to go back to the very first step or close the wizard. Thus, we - // have to save the current step of the wizard and make it accessible to it's children. - private int mStep = 0; - - @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWindow().setBackgroundDrawableResource(R.drawable.wizard_background_blackned); - - // Recover old step state. - if (savedInstanceState != null) { - mStep = savedInstanceState.getInt("step"); - } - - GuidedStepFragment fragment = new WizardExample1stStepFragment(); - fragment.setArguments(getIntent().getExtras()); // Delegate Movie to first step. - GuidedStepFragment.add(getFragmentManager(), fragment); - } - - public int getStep() { - return mStep; - } - - public void setStep(int step) { - mStep = step; - } - - @Override - public void onBackPressed() { - if (4 == getStep()) { - // The user 'bought' the product. When he presses 'Back' the Wizard will be closed and - // he will not be send back to 'Processing Payment...'-Screen. - finish(); - } else super.onBackPressed(); - } - - @Override - public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { - // Save current step persitently. - outPersistentState.putInt("step", mStep); - super.onSaveInstanceState(outState, outPersistentState); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java deleted file mode 100644 index 0b0be50e2..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/WizardExampleBaseStepFragment.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v17.leanback.app.GuidedStepFragment; -import android.support.v17.leanback.widget.GuidanceStylist; -import android.support.v17.leanback.widget.GuidedAction; - -import java.util.List; - -/** - * TODO: JavaDoc - */ -public class WizardExampleBaseStepFragment extends GuidedStepFragment { - - protected Movie mMovie; - - @Override - public int onProvideTheme() { - return R.style.Theme_Example_LeanbackWizard; - } - - WizardExampleActivity getWizardActivity() { - if (!(getActivity() instanceof WizardExampleActivity)) { - throw new IllegalStateException(WizardExampleActivity.class.getName() + " expected."); - } - return (WizardExampleActivity)getActivity(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - mMovie = (Movie)getArguments().getSerializable("movie"); - super.onCreate(savedInstanceState); - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java new file mode 100644 index 000000000..1575c8507 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app; + +import android.os.Bundle; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.SearchOrbView; +import android.view.View; +import android.widget.Toast; + +import com.google.gson.Gson; + + +public class BrowserExample01Fragment extends BrowseFragment { + + private static final String TAG = "BrowserExample01Fragment"; + + private ArrayObjectAdapter mRowsAdapter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupRowAdapter(); + } + + private void setupUi() { + setHeadersState(HEADERS_ENABLED); + setHeadersTransitionOnBackEnabled(true); + setSearchAffordanceColors( + new SearchOrbView.Colors(getResources().getColor(R.color.search_color), + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + setTitle("Browser Example 01"); + setOnSearchClickedListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.implement_search), + Toast.LENGTH_LONG).show(); + } + }); + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.browsing_example_01)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(final CardRow cardRow) { + // Build main row using the ImageCardViewPresenter. + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + HeaderItem header = new HeaderItem(cardRow.getTitle()); + return new CardListRow(header, listRowAdapter, cardRow); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java new file mode 100644 index 000000000..7e1646f09 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app; + +import android.os.Bundle; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.SearchOrbView; +import android.view.View; +import android.widget.Toast; + +import com.google.gson.Gson; + +/** + * This fragment will be shown when the "Card Examples" card is selected at the home menu. It will + * display multiple card types. + */ +public class CardExampleFragment extends BrowseFragment { + + private static final String TAG = "CardExampleFragment"; + + private ArrayObjectAdapter mRowsAdapter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupRowAdapter(); + } + + private void setupUi() { + setHeadersState(HEADERS_ENABLED); + setHeadersTransitionOnBackEnabled(true); + setSearchAffordanceColors( + new SearchOrbView.Colors(getResources().getColor(R.color.search_color), + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + setTitle(getString(R.string.card_examples_title)); + setOnSearchClickedListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.implement_search), + Toast.LENGTH_LONG).show(); + } + }); + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.cards_example)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(final CardRow cardRow) { + // Build main row using the ImageCardViewPresenter. + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + HeaderItem header = new HeaderItem(cardRow.getTitle()); + return new CardListRow(header, listRowAdapter, cardRow); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java new file mode 100644 index 000000000..1c6177ff1 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app; + +import android.os.Bundle; +import android.support.v17.leanback.app.VerticalGridFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.FocusHighlight; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.VerticalGridPresenter; + +import com.google.gson.Gson; + +/** + * An example how to use leanback's {@link VerticalGridFragment}. + */ +public class GridExample extends VerticalGridFragment { + + private static final String TAG = "GridExample"; + private static final int COLUMNS = 4; + private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_NONE; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(getString(R.string.grid_example_title)); + setupRowAdapter(); + } + + private void setupRowAdapter() { + VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); + gridPresenter.setNumberOfColumns(COLUMNS); + setGridPresenter(gridPresenter); + + PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); + String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); + CardRow row = new Gson().fromJson(json, CardRow.class); + adapter.addAll(0, row.getCards()); + setAdapter(adapter); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainActivity.java new file mode 100644 index 000000000..e84c8cc8c --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainActivity.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/* + * MainActivity class that loads MainFragment + */ +public class MainActivity extends Activity { + + /** + * Called when the activity is first created. + */ + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + if (savedInstanceState == null) { + Fragment fragment = new MainFragment(); + getFragmentManager().beginTransaction().replace(R.id.fragmentContainer, fragment) + .commit(); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java new file mode 100644 index 000000000..e836ad218 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app; + +import android.app.Fragment; +import android.content.Intent; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.support.v17.leanback.app.BackgroundManager; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.dialog.DialogExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.media.MusicConsumptionExampleFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.media.VideoConsumptionExampleFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.media.VideoSurfaceFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.settings.SettingsExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.wizard.WizardExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.utils.Constants; +import android.support.v17.leanback.supportleanbackshowcase.models.Movie; +import android.support.v17.leanback.supportleanbackshowcase.utils.PicassoBackgroundManagerTarget; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.DisplayMetrics; +import android.util.Log; + +import com.google.gson.Gson; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +import java.net.URI; +import java.util.Timer; +import java.util.TimerTask; + + +public class MainFragment extends BrowseFragment { + + public static final String VIDEO_SURFACE_FRAGMENT_TAG = "VIDEO_SURFACE"; + private static final String TAG = "MainFragment"; + private static final int BACKGROUND_UPDATE_DELAY = 300; + private static final int DEFAULT_BACKGROUND_IMAGE = R.drawable.default_background; + private final Handler mHandler = new Handler(); + private ArrayObjectAdapter mRowsAdapter; + private Target mBackgroundTarget; + private Timer mBackgroundTimer; + private URI mBackgroundURI; + private BackgroundManager mBackgroundManager; + private DisplayMetrics mMetrics; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onActivityCreated"); + super.onActivityCreated(savedInstanceState); + + setupBackgroundManager(); + setupUIElements(); + setupRowAdapter(); + setupEventListeners(); + } + + @Override public void onDestroy() { + super.onDestroy(); + if (null != mBackgroundTimer) { + if (Constants.LOCAL_LOGD) Log.d(TAG, "onDestroy: " + mBackgroundTimer.toString()); + mBackgroundTimer.cancel(); + } + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.cards_launcher)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(CardRow cardRow) { + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + return new ListRow(listRowAdapter); + } + + private void setupBackgroundManager() { + mBackgroundManager = BackgroundManager.getInstance(getActivity()); + mBackgroundManager.setThemeDrawableResourceId(DEFAULT_BACKGROUND_IMAGE); + mBackgroundManager.attach(getActivity().getWindow()); + + mBackgroundTarget = new PicassoBackgroundManagerTarget(mBackgroundManager); + mMetrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); + getView().setBackgroundResource(R.drawable.bg_living_room_wide); + //updateBackgroundImage(R.drawable.bg_living_room_wide); + } + + private void setupUIElements() { + setTitle(getString(R.string.browse_title)); + setBadgeDrawable(getResources().getDrawable(R.drawable.title_android_tv, null)); + setHeadersState(HEADERS_DISABLED); + setHeadersTransitionOnBackEnabled(false); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + } + + private void setupEventListeners() { + setOnItemViewClickedListener(new ItemViewClickedListener()); + setOnItemViewSelectedListener(new ItemViewSelectedListener()); + } + + protected void updateBackgroundImage(URI uri) { + // Deactivated until we decide whether to load a background image from an URL or resource. @hahnr + if (true) return; + Picasso.with(getActivity()).load(uri.toString()) + .resize(mMetrics.widthPixels, mMetrics.heightPixels).centerCrop() + .error(DEFAULT_BACKGROUND_IMAGE).into(mBackgroundTarget); + } + + protected void updateBackgroundImage(Drawable drawable) { + mBackgroundManager.setDrawable(drawable); + } + + protected void updateBackgroundImage(int resId) { + mBackgroundManager.setDrawable(getResources().getDrawable(resId, null)); + } + + private void startBackgroundTimer() { + if (null != mBackgroundTimer) { + mBackgroundTimer.cancel(); + } + mBackgroundTimer = new Timer(); + mBackgroundTimer.schedule(new UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY); + } + + private final class ItemViewClickedListener implements OnItemViewClickedListener { + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + Card card = (Card) item; + int id = card.getId(); + switch (id) { + case 0: { + updateBackgroundImage(new ColorDrawable( + getResources().getColor(R.color.card_examples_background))); + Fragment fragment = new CardExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 2: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_canyon, null)); + Fragment fragment = new GridExample(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 3: { + Intent intent = new Intent(getActivity().getBaseContext(), + DetailViewExampleActivity.class); + startActivity(intent); + break; + } + case 4: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_canyon, null)); + Fragment fragment = new VideoConsumptionExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, new VideoSurfaceFragment(), + VIDEO_SURFACE_FRAGMENT_TAG) + .add(R.id.fragmentContainer, fragment).addToBackStack(null) + .commit(); + break; + } + case 5: { + updateBackgroundImage( + getResources().getDrawable(R.drawable.background_sax, null)); + Fragment fragment = new MusicConsumptionExampleFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.fragmentContainer, fragment) + .addToBackStack(null).commit(); + break; + } + case 6: { + // Let's create a new Wizard for a given Movie. The movie can come from any sort + // of data source. To simplify this example we decode it from a JSON source + // which might be loaded from a server in a real world example. + Intent intent = new Intent(getActivity().getBaseContext(), + WizardExampleActivity.class); + + // Prepare extras which contains the Movie and will be passed to the Activity + // which is started through the Intent/. + Bundle extras = new Bundle(); + String json = Utils.inputStreamToString( + getResources().openRawResource(R.raw.wizard_example)); + Movie movie = new Gson().fromJson(json, Movie.class); + extras.putSerializable("movie", movie); + intent.putExtras(extras); + + // Finally, start the wizard Activity. + startActivity(intent); + break; + } + case 7: { + Intent intent = new Intent(getActivity().getBaseContext(), + SettingsExampleActivity.class); + startActivity(intent); + break; + } + case 8: { + Intent intent = new Intent(getActivity().getBaseContext(), + DialogExampleActivity.class); + startActivity(intent); + break; + } + default: + break; + } + } + } + + private final class ItemViewSelectedListener implements OnItemViewSelectedListener { + + @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + } + } + + private class UpdateBackgroundTask extends TimerTask { + + @Override public void run() { + mHandler.post(new Runnable() { + @Override public void run() { + if (mBackgroundURI != null) { + updateBackgroundImage(mBackgroundURI); + } + } + }); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleActivity.java new file mode 100644 index 000000000..6b9c1434f --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleActivity.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.details; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v17.leanback.app.DetailsFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/** + * Contains a {@link DetailsFragment} in order to display more details for a given card. + */ +public class DetailViewExampleActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java new file mode 100644 index 000000000..9c541e237 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.details; + +import android.os.Bundle; +import android.support.v17.leanback.app.DetailsFragment; +import android.support.v17.leanback.supportleanbackshowcase.models.DetailedCard; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.DetailsOverviewRow; +import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.google.gson.Gson; + +/** + * Displays a card with more details using a {@link DetailsFragment}. + */ +public class DetailViewExampleFragment extends DetailsFragment implements OnItemViewClickedListener, + OnItemViewSelectedListener { + + private ArrayObjectAdapter mRowsAdapter; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupEventListeners(); + } + + private void setupUi() { + // Load the card we want to display from a JSON resource. This JSON data could come from + // anywhere in a real world app, e.g. a server. + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.detail_example)); + DetailedCard data = new Gson().fromJson(json, DetailedCard.class); + + // Setup fragment + setTitle(getString(R.string.detail_view_title)); + + FullWidthDetailsOverviewRowPresenter rowPresenter = new FullWidthDetailsOverviewRowPresenter( + new DetailsDescriptionPresenter(getActivity())) { + + @Override + protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { + // Customize Actionbar and Content by using custom colors. + RowPresenter.ViewHolder viewHolder = super.createRowViewHolder(parent); + + View actionsView = viewHolder.view. + findViewById(R.id.details_overview_actions_background); + actionsView.setBackgroundColor(getActivity().getResources(). + getColor(R.color.detail_view_actionbar_background, null)); + + View detailsView = viewHolder.view.findViewById(R.id.details_frame); + detailsView.setBackgroundColor( + getResources().getColor(R.color.detail_view_background, null)); + return viewHolder; + } + }; + ListRowPresenter shadowDisabledRowPresenter = new ListRowPresenter(); + shadowDisabledRowPresenter.setShadowEnabled(false); + + // Setup PresenterSelector to distinguish between the different rows. + ClassPresenterSelector rowPresenterSelector = new ClassPresenterSelector(); + rowPresenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter); + rowPresenterSelector.addClassPresenter(CardListRow.class, shadowDisabledRowPresenter); + rowPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter()); + mRowsAdapter = new ArrayObjectAdapter(rowPresenterSelector); + + // Setup action and detail row. + DetailsOverviewRow detailsOverview = new DetailsOverviewRow(data); + int imageResId = data.getLocalImageResourceId(getActivity()); + detailsOverview.setImageDrawable(getResources().getDrawable(imageResId, null)); + ArrayObjectAdapter actionAdapter = new ArrayObjectAdapter(); + actionAdapter.add(new Action(1, getString(R.string.action_buy) + data.getPrice())); + actionAdapter.add(new Action(2, getString(R.string.action_wishlist))); + actionAdapter.add(new Action(3, getString(R.string.action_related))); + detailsOverview.setActionsAdapter(actionAdapter); + mRowsAdapter.add(detailsOverview); + + // Setup related row. + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter( + new CardPresenterSelector(getActivity())); + for (Card characterCard : data.getCharacters()) listRowAdapter.add(characterCard); + HeaderItem header = new HeaderItem(0, getString(R.string.header_related)); + mRowsAdapter.add(new CardListRow(header, listRowAdapter, null)); + + // Setup recommended row. + listRowAdapter = new ArrayObjectAdapter(new CardPresenterSelector(getActivity())); + for (Card card : data.getRecommended()) listRowAdapter.add(card); + header = new HeaderItem(1, getString(R.string.header_recommended)); + mRowsAdapter.add(new ListRow(header, listRowAdapter)); + + setAdapter(mRowsAdapter); + } + + private void setupEventListeners() { + setOnItemViewSelectedListener(this); + setOnItemViewClickedListener(this); + } + + @Override + public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (!(item instanceof Action)) return; + Action action = (Action) item; + if (action.getId() == 3) { + setSelectedPosition(1); + } else { + Toast.makeText(getActivity(), getString(R.string.action_cicked), Toast.LENGTH_LONG) + .show(); + } + } + + @Override + public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (mRowsAdapter.indexOf(row) > 0) { + int backgroundColor = getResources().getColor(R.color.detail_view_related_background, + null); + getView().setBackgroundColor(backgroundColor); + } else { + getView().setBackgroundResource(R.drawable.background_canyon); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailsDescriptionPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailsDescriptionPresenter.java new file mode 100644 index 000000000..b8488a11e --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailsDescriptionPresenter.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.details; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.models.DetailedCard; +import android.support.v17.leanback.supportleanbackshowcase.utils.ResourceCache; +import android.support.v17.leanback.widget.Presenter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +/** + * This presenter is used to render a {@link DetailedCard} in the {@link + * DetailViewExampleFragment}. + */ +public class DetailsDescriptionPresenter extends Presenter { + + private ResourceCache mResourceCache = new ResourceCache(); + private Context mContext; + + public DetailsDescriptionPresenter(Context context) { + mContext = context; + } + + @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view_content, null); + return new ViewHolder(view); + } + + @Override public void onBindViewHolder(ViewHolder viewHolder, Object item) { + TextView primaryText = mResourceCache.getViewById(viewHolder.view, R.id.primary_text); + TextView sndText1 = mResourceCache.getViewById(viewHolder.view, R.id.secondary_text_first); + TextView sndText2 = mResourceCache.getViewById(viewHolder.view, R.id.secondary_text_second); + TextView extraText = mResourceCache.getViewById(viewHolder.view, R.id.extra_text); + + DetailedCard card = (DetailedCard) item; + primaryText.setText(card.getTitle()); + sndText1.setText(card.getDescription()); + sndText2.setText(card.getYear() + ""); + extraText.setText(card.getText()); + } + + @Override public void onUnbindViewHolder(ViewHolder viewHolder) { + // Nothing to do here. + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/ShadowRowPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/ShadowRowPresenterSelector.java new file mode 100644 index 000000000..987365a87 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/ShadowRowPresenterSelector.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.details; + +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.PresenterSelector; + +/** + * This {@link PresenterSelector} will return a {@link ListRowPresenter} which has shadow support + * enabled or not depending on {@link CardRow#useShadow()} for a given row. + */ +public class ShadowRowPresenterSelector extends PresenterSelector { + + private ListRowPresenter mShadowEnabledRowPresenter = new ListRowPresenter(); + private ListRowPresenter mShadowDisabledRowPresenter = new ListRowPresenter(); + + public ShadowRowPresenterSelector() { + mShadowDisabledRowPresenter.setShadowEnabled(false); + } + + @Override public Presenter getPresenter(Object item) { + if (!(item instanceof CardListRow)) return mShadowDisabledRowPresenter; + CardListRow listRow = (CardListRow) item; + CardRow row = listRow.getCardRow(); + if (row.useShadow()) return mShadowEnabledRowPresenter; + return mShadowDisabledRowPresenter; + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java new file mode 100644 index 000000000..763a18e37 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.dialog; + +import android.app.Activity; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.support.v17.leanback.app.GuidedStepFragment; + +/** + * TODO: Javadoc + */ +public class DialogExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#21272A"))); + + GuidedStepFragment fragment = new DialogExampleFragment(); + GuidedStepFragment.add(getFragmentManager(), fragment); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleFragment.java new file mode 100644 index 000000000..80b22a931 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleFragment.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.dialog; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.GuidanceStylist.Guidance; +import android.support.v17.leanback.widget.GuidedAction; +import android.widget.Toast; + +import java.util.List; + +/** + * TODO: Javadoc + */ +public class DialogExampleFragment extends GuidedStepFragment { + + private static final int ACTION_ID_POSITIVE = 1; + private static final int ACTION_ID_NEGATIVE = ACTION_ID_POSITIVE + 1; + + @NonNull + @Override + public Guidance onCreateGuidance(Bundle savedInstanceState) { + Guidance guidance = new Guidance(getString(R.string.dialog_example_title), + getString(R.string.dialog_example_description), + "", null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_POSITIVE) + .title(getString(R.string.dialog_example_button_positive)).build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_NEGATIVE) + .title(getString(R.string.dialog_example_button_negative)).build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_POSITIVE == action.getId()) { + Toast.makeText(getActivity(), R.string.dialog_example_button_toast_positive_clicked, + Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getActivity(), R.string.dialog_example_button_toast_negative_clicked, + Toast.LENGTH_SHORT).show(); + } + getActivity().finish(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MediaPlayerGlue.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MediaPlayerGlue.java new file mode 100644 index 000000000..bc757cd19 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MediaPlayerGlue.java @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Handler; +import android.support.v17.leanback.app.PlaybackControlGlue; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ControlButtonPresenterSelector; +import android.support.v17.leanback.widget.OnItemViewSelectedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.Log; +import android.view.KeyEvent; +import android.view.SurfaceHolder; +import android.view.View; + +import java.io.IOException; + +/** + * This glue extends the {@link PlaybackControlGlue} with a {@link MediaPlayer} synchronization. It + * supports 7 actions:

  • {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction}
  • + *
  • {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction}
  • {@link + * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction}
+ *

+ */ +public abstract class MediaPlayerGlue extends PlaybackControlGlue implements + OnItemViewSelectedListener { + + public static final int FAST_FORWARD_REWIND_STEP = 10 * 1000; // in milliseconds + public static final int FAST_FORWARD_REWIND_REPEAT_DELAY = 200; // in milliseconds + private static final String TAG = "MediaPlayerGlue"; + protected final PlaybackControlsRow.ThumbsDownAction mThumbsDownAction; + protected final PlaybackControlsRow.ThumbsUpAction mThumbsUpAction; + private final Context mContext; + private final MediaPlayer mPlayer = new MediaPlayer(); + private final PlaybackControlsRow.RepeatAction mRepeatAction; + private final PlaybackControlsRow.ShuffleAction mShuffleAction; + private PlaybackControlsRow mControlsRow; + private Runnable mRunnable; + private Handler mHandler = new Handler(); + private boolean mPaused = false; + private boolean mInitialized = false; // true when the MediaPlayer is prepared/initialized + private OnMediaFileFinishedPlayingListener mMediaFileFinishedPlayingListener; + private Action mSelectedAction; // the action which is currently selected by the user + private long mLastKeyDownEvent = 0L; // timestamp when the last DPAD_CENTER KEY_DOWN occurred + private MetaData mMetaData; + private Uri mMediaSourceUri = null; + private String mMediaSourcePath = null; + + public MediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { + super(context, fragment, new int[]{1}); + mContext = context; + + // Instantiate secondary actions + mShuffleAction = new PlaybackControlsRow.ShuffleAction(mContext); + mRepeatAction = new PlaybackControlsRow.RepeatAction(mContext); + mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(mContext); + mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(mContext); + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + + // Setup controls and notify UI about change. + setFadingEnabled(false); + onStateChanged(); + + // Register selected listener such that we know what action the user currently has focused. + fragment.setOnItemViewSelectedListener(this); + } + + /** + * Will reset the {@link MediaPlayer} and the glue such that a new file can be played. You are + * not required to call this method before playing the first file. However you have to call it + * before playing a second one. + */ + public void reset() { + mPaused = mInitialized = false; + mPlayer.reset(); + } + + public void setOnMediaFileFinishedPlayingListener(OnMediaFileFinishedPlayingListener listener) { + mMediaFileFinishedPlayingListener = listener; + } + + /** + * Override this method in case you need to add different secondary actions. + * + * @param secondaryActionsAdapter The adapter you need to add the {@link Action}s to. + */ + protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { + secondaryActionsAdapter.add(mShuffleAction); + secondaryActionsAdapter.add(mRepeatAction); + secondaryActionsAdapter.add(mThumbsDownAction); + secondaryActionsAdapter.add(mThumbsUpAction); + } + + /** + * @see MediaPlayer#setDisplay(SurfaceHolder) + */ + public void setDisplay(SurfaceHolder surfaceHolder) { + mPlayer.setDisplay(surfaceHolder); + } + + /** + * Use this method to setup the {@link PlaybackControlsRowPresenter}. It'll be called + * after the {@link PlaybackControlsRowPresenter} has been created and the primary and + * secondary actions have been added. + * + * @param presenter The PlaybackControlsRowPresenter used to display the controls. + */ + public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { + // TODO: hahnr@ move into resources + presenter.setProgressColor(Color.parseColor("#feab91")); + presenter.setBackgroundColor(Color.parseColor("#db2a0f")); + } + + @Override public PlaybackControlsRowPresenter createControlsRowAndPresenter() { + PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter(); + mControlsRow = getControlsRow(); + + // Add secondary actions and change the control row color. + ArrayObjectAdapter secondaryActions = new ArrayObjectAdapter( + new ControlButtonPresenterSelector()); + mControlsRow.setSecondaryActionsAdapter(secondaryActions); + addSecondaryActions(secondaryActions); + setupControlsRowPresenter(presenter); + return presenter; + } + + @Override public void enableProgressUpdating(final boolean enabled) { + if (!enabled) { + if (mRunnable != null) mHandler.removeCallbacks(mRunnable); + return; + } + mRunnable = new Runnable() { + @Override public void run() { + updateProgress(); + Log.d(TAG, "enableProgressUpdating(boolean)"); + mHandler.postDelayed(this, getUpdatePeriod()); + } + }; + mHandler.postDelayed(mRunnable, getUpdatePeriod()); + } + + @Override public void onActionClicked(Action action) { + // If either 'Shuffle' or 'Repeat' has been clicked we need to make sure the acitons index + // is incremented and the UI updated such that we can display the new state. + super.onActionClicked(action); + if (action instanceof PlaybackControlsRow.ShuffleAction) { + mShuffleAction.nextIndex(); + } else if (action instanceof PlaybackControlsRow.RepeatAction) { + mRepeatAction.nextIndex(); + } else if (action instanceof PlaybackControlsRow.ThumbsUpAction) { + if (mThumbsUpAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } else { + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } + } else if (action instanceof PlaybackControlsRow.ThumbsDownAction) { + if (mThumbsDownAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } else { + mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); + mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); + } + } + onMetadataChanged(); + } + + @Override public boolean onKey(View v, int keyCode, KeyEvent event) { + // This method is overridden in order to make implement fast forwarding and rewinding when + // the user keeps the corresponding action pressed. + // We only consume DPAD_CENTER Action_DOWN events on the Fast-Forward and Rewind action and + // only if it has not been pressed in the last X milliseconds. + boolean consume = mSelectedAction instanceof PlaybackControlsRow.RewindAction; + consume = consume || mSelectedAction instanceof PlaybackControlsRow.FastForwardAction; + consume = consume && mInitialized; + consume = consume && event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER; + consume = consume && event.getAction() == KeyEvent.ACTION_DOWN; + consume = consume && System + .currentTimeMillis() - mLastKeyDownEvent > FAST_FORWARD_REWIND_REPEAT_DELAY; + if (consume) { + mLastKeyDownEvent = System.currentTimeMillis(); + int newPosition = getCurrentPosition() + FAST_FORWARD_REWIND_STEP; + if (mSelectedAction instanceof PlaybackControlsRow.RewindAction) { + newPosition = getCurrentPosition() - FAST_FORWARD_REWIND_STEP; + } + // Make sure the new calculated duration is in the range 0 >= X >= MediaDuration + if (newPosition < 0) newPosition = 0; + if (newPosition > getMediaDuration()) newPosition = getMediaDuration(); + seekTo(newPosition); + return true; + } + return super.onKey(v, keyCode, event); + } + + @Override public boolean hasValidMedia() { + return mMetaData != null; + } + + @Override public boolean isMediaPlaying() { + return mPlayer.isPlaying(); + } + + @Override public CharSequence getMediaTitle() { + return hasValidMedia() ? mMetaData.getTitle() : "N/a"; + } + + @Override public CharSequence getMediaSubtitle() { + return hasValidMedia() ? mMetaData.getArtist() : "N/a"; + } + + @Override public int getMediaDuration() { + return mInitialized ? mPlayer.getDuration() : 0; + } + + @Override public Drawable getMediaArt() { + return hasValidMedia() ? mMetaData.getCover() : null; + } + + @Override public long getSupportedActions() { + return PlaybackControlGlue.ACTION_PLAY_PAUSE | PlaybackControlGlue.ACTION_FAST_FORWARD | PlaybackControlGlue.ACTION_REWIND; + } + + @Override public int getCurrentSpeedId() { + // 0 = Pause, 1 = Normal Playback Speed + return mPlayer.isPlaying() ? 1 : 0; + } + + @Override public int getCurrentPosition() { + return mInitialized ? mPlayer.getCurrentPosition() : 0; + } + + @Override protected void startPlayback(int speed) throws IllegalStateException { + if (mPaused) { + mPlayer.start(); + } else if (!isMediaPlaying()) { + reset(); + try { + if (mMediaSourceUri != null) mPlayer.setDataSource(getContext(), mMediaSourceUri); + else mPlayer.setDataSource(mMediaSourcePath); + } catch (IOException e) { + throw new RuntimeException(e); + } + mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override public void onPrepared(MediaPlayer mp) { + mInitialized = true; + mPaused = false; + mPlayer.start(); + onMetadataChanged(); + onStateChanged(); + updateProgress(); + } + }); + mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override public void onCompletion(MediaPlayer mp) { + if (mInitialized && mMediaFileFinishedPlayingListener != null) + mMediaFileFinishedPlayingListener.onMediaFileFinishedPlaying(mMetaData); + } + }); + mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { + @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { + mControlsRow.setBufferedProgress((int) (mp.getDuration() * (percent / 100f))); + } + }); + mPlayer.prepareAsync(); + onStateChanged(); + } + } + + @Override protected void pausePlayback() { + if (mPlayer.isPlaying()) { + mPlayer.pause(); + mPaused = true; + } + } + + @Override protected void skipToNext() { + // Not supported. + } + + @Override protected void skipToPrevious() { + // Not supported. + } + + /** + * Called whenever the user presses fast-forward/rewind or when the user keeps the corresponding + * action pressed. + * + * @param newPosition The new position of the media track in milliseconds. + */ + protected void seekTo(int newPosition) { + mPlayer.seekTo(newPosition); + } + + /** + * @see MediaPlayer#setDataSource(Context, Uri) + */ + public void setMediaSource(Uri uri) { + mMediaSourceUri = uri; + } + + /** + * @see MediaPlayer#setDataSource(String) + */ + public void setMediaSource(String path) { + mMediaSourcePath = path; + } + + /** + * Call to startPlayback(1). + * + * @throws IllegalStateException See {@link MediaPlayer} for further information about it's + * different states when setting a data source and preparing it to be played. + */ + public void startPlayback() throws IllegalStateException { + startPlayback(1); + } + + /** + * @return Returns true iff 'Shuffle' is ON. + */ + public boolean useShuffle() { + return mShuffleAction.getIndex() == PlaybackControlsRow.ShuffleAction.ON; + } + + /** + * @return Returns true iff 'Repeat-One' is ON. + */ + public boolean repeatOne() { + return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ONE; + } + + /** + * @return Returns true iff 'Repeat-All' is ON. + */ + public boolean repeatAll() { + return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ALL; + } + + public void setMetaData(MetaData metaData) { + mMetaData = metaData; + onMetadataChanged(); + } + + /** + * This is a listener implementation for the {@link OnItemViewSelectedListener} of the {@link + * PlaybackOverlayFragment}. This implementation is required in order to detect KEY_DOWN events + * on the {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction} and + * {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}. Thus you should + * NOT set another {@link OnItemViewSelectedListener} on your {@link + * PlaybackOverlayFragment}. Instead, override this method and call its super (this) + * implementation. + * + * @see OnItemViewSelectedListener#onItemSelected(Presenter.ViewHolder, Object, + * RowPresenter.ViewHolder, Row) + */ + @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (item instanceof Action) { + mSelectedAction = (Action) item; + } else { + mSelectedAction = null; + } + } + + /** + * A listener which will be called whenever a track is finished playing. + */ + public interface OnMediaFileFinishedPlayingListener { + + /** + * Called when a track is finished playing. + * + * @param metaData The track's {@link MetaData} which just finished playing. + */ + void onMediaFileFinishedPlaying(MetaData metaData); + + } + + /** + * Holds the meta data such as track title, artist and cover art. It'll be used by the {@link + * MediaPlayerGlue}. + */ + public static class MetaData { + + private String mTitle; + private String mArtist; + private Drawable mCover; + + + public String getTitle() { + return mTitle; + } + + public void setTitle(String title) { + this.mTitle = title; + } + + public String getArtist() { + return mArtist; + } + + public void setArtist(String artist) { + this.mArtist = artist; + } + + public Drawable getCover() { + return mCover; + } + + public void setCover(Drawable cover) { + this.mCover = cover; + } + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicConsumptionExampleFragment.java new file mode 100644 index 000000000..fdb8ec41f --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicConsumptionExampleFragment.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.net.Uri; +import android.os.Bundle; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.supportleanbackshowcase.utils.Constants; +import android.support.v17.leanback.supportleanbackshowcase.app.media.MediaPlayerGlue; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.media.TrackListHeader; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.Song; +import android.support.v17.leanback.supportleanbackshowcase.models.SongList; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.util.Log; + +import com.google.gson.Gson; + +import java.util.List; + +/** + * This example shows how to play music files and build a simple track list. + */ +public class MusicConsumptionExampleFragment extends PlaybackOverlayFragment implements + OnItemViewClickedListener, Song.OnSongRowClickListener, + MediaPlayerGlue.OnMediaFileFinishedPlayingListener { + + private static final String TAG = "MusicConsumptionExampleFragment"; + private ArrayObjectAdapter mRowsAdapter; + private MediaPlayerGlue mGlue; + private int mCurrentSongIndex = 0; + private List mSongList; + private boolean mAdapterNotified = false; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreate"); + + mGlue = new MediaPlayerGlue(getActivity(), this) { + + @Override protected void onRowChanged(PlaybackControlsRow row) { + if (mRowsAdapter == null || mAdapterNotified) return; + //mAdapterNotified = true; + mRowsAdapter.notifyArrayItemRangeChanged(0, 1); + } + }; + mGlue.setOnMediaFileFinishedPlayingListener(this); + + String json = Utils.inputStreamToString( + getResources().openRawResource(R.raw.music_consumption_example)); + mSongList = new Gson().fromJson(json, SongList.class).getSongs(); + Song song = mSongList.get(mCurrentSongIndex); + MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); + metaData.setArtist(song.getDescription()); + metaData.setTitle(song.getTitle()); + metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); + Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); + mGlue.setMetaData(metaData); + mGlue.setMediaSource(uri); + + setBackgroundType(PlaybackOverlayFragment.BG_LIGHT); + addPlaybackControlsRow(); + } + + @Override public void onStart() { + super.onStart(); + mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); + } + + @Override public void onStop() { + super.onStop(); + mGlue.enableProgressUpdating(false); + mGlue.reset(); + } + + private void addPlaybackControlsRow() { + final PlaybackControlsRowPresenter controlsPresenter = mGlue + .createControlsRowAndPresenter(); + ClassPresenterSelector selector = new ClassPresenterSelector(); + Song.Presenter songPresenter = new Song.Presenter(getActivity()); + songPresenter.setOnClickListener(this); + selector.addClassPresenter(Song.class, songPresenter); + selector.addClassPresenter(TrackListHeader.class, + new TrackListHeader.Presenter(getActivity())); + selector.addClassPresenter(PlaybackControlsRow.class, controlsPresenter); + mRowsAdapter = new ArrayObjectAdapter(selector); + mRowsAdapter.add(mGlue.getControlsRow()); + mRowsAdapter.add(new TrackListHeader()); + mRowsAdapter.addAll(2, mSongList); + setAdapter(mRowsAdapter); + setOnItemViewClickedListener(this); + } + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (!(item instanceof Action)) return; + mGlue.onActionClicked((Action) item); + } + + + @Override public void onSongRowClicked(Song song) { + mCurrentSongIndex = mSongList.indexOf(song); + startPlayback(); + } + + + @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData song) { + if (mGlue.repeatOne()) { + startPlayback(); + return; + } + if (mGlue.useShuffle()) { + mCurrentSongIndex = (int) (Math.random() * mSongList.size()); + } else mCurrentSongIndex++; + if (mCurrentSongIndex >= mSongList.size()) { + mCurrentSongIndex = 0; + if (!mGlue.repeatAll()) return; + } + startPlayback(); + } + + private void startPlayback() { + Song song = mSongList.get(mCurrentSongIndex); + MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); + metaData.setArtist(song.getDescription()); + metaData.setTitle(song.getTitle()); + metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); + + Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); + mGlue.setMetaData(metaData); + mGlue.setMediaSource(uri); + mGlue.startPlayback(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/SongListRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/SongListRow.java new file mode 100644 index 000000000..409613241 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/SongListRow.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.support.v17.leanback.widget.Row; + +public class SongListRow extends Row {} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/TrackListHeader.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/TrackListHeader.java new file mode 100644 index 000000000..ff794a24d --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/TrackListHeader.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class TrackListHeader extends Row { + + public static class Presenter extends RowPresenter { + + private final Context mContext; + + public Presenter(Context context) { + mContext = context; + setHeaderPresenter(null); + } + + @Override public boolean isUsingDefaultSelectEffect() { + return false; + } + + @Override protected ViewHolder createRowViewHolder(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.row_track_list_header, parent, false); + view.setFocusable(false); + view.setFocusableInTouchMode(false); + return new ViewHolder(view); + } + } + + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java new file mode 100644 index 000000000..991a95f39 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.MainFragment; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + + +public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment implements + OnItemViewClickedListener, MediaPlayerGlue.OnMediaFileFinishedPlayingListener { + + private static final String URL = "http://techslides.com/demos/sample-videos/small.mp4"; + private ArrayObjectAdapter mRowsAdapter; + private MediaPlayerGlue mGlue; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mGlue = new VideoMediaPlayerGlue(getActivity(), this) { + + @Override protected void onRowChanged(PlaybackControlsRow row) { + if (mRowsAdapter == null) return; + mRowsAdapter.notifyArrayItemRangeChanged(0, 1); + } + }; + mGlue.setOnMediaFileFinishedPlayingListener(this); + MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); + metaData.setArtist("A Googler"); + metaData.setTitle("Diving with Sharks"); + mGlue.setMetaData(metaData); + mGlue.setMediaSource(URL); + + Fragment videoSurfaceFragment = getFragmentManager() + .findFragmentByTag(MainFragment.VIDEO_SURFACE_FRAGMENT_TAG); + SurfaceView surface = (SurfaceView) videoSurfaceFragment.getView(); + surface.getHolder().addCallback(new SurfaceHolder.Callback() { + @Override public void surfaceCreated(SurfaceHolder holder) { + mGlue.setDisplay(holder); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + // Nothing to do + } + + @Override public void surfaceDestroyed(SurfaceHolder holder) { + } + }); + + setBackgroundType(PlaybackOverlayFragment.BG_LIGHT); + addPlaybackControlsRow(); + } + + @Override public void onStart() { + super.onStart(); + mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); + } + + @Override public void onStop() { + super.onStop(); + mGlue.enableProgressUpdating(false); + mGlue.reset(); + } + + private void addPlaybackControlsRow() { + final PlaybackControlsRowPresenter controlsPresenter = mGlue + .createControlsRowAndPresenter(); + mRowsAdapter = new ArrayObjectAdapter(controlsPresenter); + mRowsAdapter.add(mGlue.getControlsRow()); + setAdapter(mRowsAdapter); + setOnItemViewClickedListener(this); + } + + @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + if (!(item instanceof Action)) return; + mGlue.onActionClicked((Action) item); + } + + + @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData metaData) { + mGlue.startPlayback(); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoMediaPlayerGlue.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoMediaPlayerGlue.java new file mode 100644 index 000000000..52ab09fb9 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoMediaPlayerGlue.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.content.Context; +import android.graphics.Color; +import android.support.v17.leanback.app.PlaybackOverlayFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.media.MediaPlayerGlue; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; + +public abstract class VideoMediaPlayerGlue extends MediaPlayerGlue { + + private final PlaybackControlsRow.ClosedCaptioningAction mClosedCaptioningAction; + + public VideoMediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { + super(context, fragment); + + // Instantiate secondary actions + mClosedCaptioningAction = new PlaybackControlsRow.ClosedCaptioningAction(context); + setFadingEnabled(true); + } + + @Override protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { + secondaryActionsAdapter.add(mClosedCaptioningAction); + secondaryActionsAdapter.add(mThumbsDownAction); + secondaryActionsAdapter.add(mThumbsUpAction); + } + + @Override public void onActionClicked(Action action) { + super.onActionClicked(action); + if (action == mClosedCaptioningAction) { + mClosedCaptioningAction.nextIndex(); + } + } + + public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { + // TODO: hahnr@ move into resources + presenter.setProgressColor(Color.parseColor("#EEFF41")); + presenter.setBackgroundColor(Color.parseColor("#007236")); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoSurfaceFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoSurfaceFragment.java new file mode 100644 index 000000000..158a048c4 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoSurfaceFragment.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + +public class VideoSurfaceFragment extends Fragment { + + private static final String TAG = "VideoSurfaceFragment"; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.video_surface_fragment, null); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleActivity.java new file mode 100644 index 000000000..01963caf7 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleActivity.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.settings; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/* + * TODO: Javadoc + */ +public class SettingsExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java new file mode 100644 index 000000000..72766d1c2 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.settings; + +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.support.v14.preference.PreferenceFragment; +import android.support.v17.leanback.supportleanbackshowcase.utils.Constants; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.preference.LeanbackPreferenceFragment; +import android.support.v17.preference.LeanbackSettingsFragment; +import android.support.v7.preference.DialogPreference; +import android.support.v7.preference.ListPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.util.Log; + +import java.util.Stack; + +public class SettingsExampleFragment extends LeanbackSettingsFragment implements DialogPreference.TargetFragment { + + public static final String TAG = "SettingsExampleFragment"; + private final Stack fragments = new Stack(); + + @Override + public void onPreferenceStartInitialScreen() { + startPreferenceFragment(buildPreferenceFragment(R.xml.prefs, null)); + } + + @Override + public boolean onPreferenceStartFragment(PreferenceFragment preferenceFragment, + Preference preference) { + return false; + } + + @Override + public boolean onPreferenceStartScreen(PreferenceFragment preferenceFragment, + PreferenceScreen preferenceScreen) { + PreferenceFragment frag = buildPreferenceFragment(R.xml.prefs, preferenceScreen.getKey()); + if ("prefs_wifi_screen_key".equals(preferenceScreen.getKey())) { + ListPreference pref = (ListPreference)preferenceScreen.findPreference("prefs_wifi_key"); + pref.setEntries(new String[] {"Wi-Fi Network 01"}); + pref.setEntryValues(new String[] {"01"}); + if (Constants.LOCAL_LOGD) Log.d(TAG, "pref: " + pref); + } + startPreferenceFragment(frag); + return true; + } + + @Override + public Preference findPreference(CharSequence prefKey) { + return ((PreferenceFragment) fragments.peek()).findPreference(prefKey); + } + + private PreferenceFragment buildPreferenceFragment(int preferenceResId, String root) { + PreferenceFragment fragment = new PrefFragment(); + Bundle args = new Bundle(); + args.putInt("preferenceResource", preferenceResId); + args.putString("root", root); + fragment.setArguments(args); + return fragment; + } + + private class PrefFragment extends LeanbackPreferenceFragment { + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + String root = getArguments().getString("root", null); + int prefResId = getArguments().getInt("preferenceResource"); + if (root == null) { + addPreferencesFromResource(prefResId); + } else { + setPreferencesFromResource(prefResId, root); + } + } + + @Override + public void onAttach(Context context) { + fragments.push(this); + super.onAttach(context); + } + + @Override + public void onDetach() { + fragments.pop(); + super.onDetach(); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java new file mode 100644 index 000000000..d9ddf7f27 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.wizard; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_BUY_HD = 1; + private static final int ACTION_ID_BUY_SD = ACTION_ID_BUY_HD + 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(1); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + getString(R.string.wizard_example_choose_rent_options), + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_BUY_HD) + .title(getString(R.string.wizard_example_rent_hd)) + .description(mMovie.getPriceHd() + " " + + getString(R.string.wizard_example_watch_hd)) + .build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_BUY_SD) + .title(getString(R.string.wizard_example_rent_sd)) + .description(mMovie.getPriceSd() + " " + + getString(R.string.wizard_example_watch_sd)) + .build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + GuidedStepFragment fragment = new WizardExample2ndStepFragment(); + Bundle args = getArguments(); // Reuse the same arguments this fragment was given. + args.putBoolean("hd", ACTION_ID_BUY_HD == action.getId()); + fragment.setArguments(args); + add(getFragmentManager(), fragment); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java new file mode 100644 index 000000000..4ed46eee8 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.wizard; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.support.v17.leanback.widget.GuidedActionsStylist; +import android.widget.Toast; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_CONFIRM = 1; + private static final int ACTION_ID_PAYMENT_METHOD = ACTION_ID_CONFIRM + 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(2); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + getString(R.string.wizard_example_rental_period), + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public GuidedActionsStylist onCreateActionsStylist() { + GuidedActionsStylist stylist = new GuidedActionsStylist() { + + @Override + public void onBindViewHolder(ViewHolder vh, GuidedAction action) { + super.onBindViewHolder(vh, action); + + if (ACTION_ID_CONFIRM == action.getId()) { + Drawable background = getResources().getDrawable( + R.drawable.wizard_important_action_item_background, null); + vh.view.setBackground(background); + vh.getTitleView().setTextColor(Color.parseColor("#666666")); + vh.getDescriptionView().setTextColor(Color.parseColor("#666666")); + } else { + vh.view.setBackground(null); + vh.getTitleView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, + getActivity().getTheme())); + vh.getDescriptionView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, + getActivity().getTheme())); + } + } + }; + return stylist; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + boolean rentHighDefinition = getArguments().getBoolean("hd"); + + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_CONFIRM) + .title(getString(R.string.wizard_example_rent)) + .description(rentHighDefinition ? mMovie.getPriceHd() : mMovie.getPriceSd()) + .build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_PAYMENT_METHOD) + .title(getString(R.string.wizard_example_payment_method)) + .description("Visa - 1234 Balance $60.00") + .build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_PAYMENT_METHOD == action.getId()) { + Toast.makeText(getActivity(), + getString(R.string.wizard_example_toast_payment_method_clicked), + Toast.LENGTH_SHORT).show(); + } else { + GuidedStepFragment fragment = new WizardExample3rdStepFragment(); + fragment.setArguments(getArguments()); + add(getFragmentManager(), fragment); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java new file mode 100644 index 000000000..7a336c77f --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.wizard; + +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.support.v17.leanback.widget.GuidedActionsStylist; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample3rdStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_PROCESSING = 1; + private final Handler mFakeHttpHandler = new Handler(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(3); + } + + @Override + public void onStart() { + super.onStart(); + + // Fake Http call by creating some sort of delay. + mFakeHttpHandler.postDelayed(fakeHttpRequestRunnable, 4000L); + } + + @Override + public GuidedActionsStylist onCreateActionsStylist() { + GuidedActionsStylist stylist = new GuidedActionsStylist() { + @Override + public int onProvideItemLayoutId() { + return R.layout.wizard_progress_action_item; + } + + @Override + public int onProvideLayoutId() { + return R.layout.wizard_progress_action_container; + } + }; + return stylist; + } + + @Override + public void onStop() { + super.onStop(); + + // Make sure to cancel the execution of the Runnable in case the fragment is stopped. + mFakeHttpHandler.removeCallbacks(fakeHttpRequestRunnable); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + "Just a second...", + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_PROCESSING) + .title(getString(R.string.wizard_example_processing)) + .infoOnly(true) + .build(); + actions.add(action); + } + + private final Runnable fakeHttpRequestRunnable = new Runnable() { + @Override + public void run() { + GuidedStepFragment fragment = new WizardExample4thStepFragment(); + fragment.setArguments(getArguments()); + add(getFragmentManager(), fragment); + } + }; + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java new file mode 100644 index 000000000..255705ca5 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.wizard; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.widget.Toast; + +import java.util.List; + +/** + * TODO: JavaDoc + */ +public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment { + + private static final int ACTION_ID_WATCH = 1; + private static final int ACTION_ID_LATER = ACTION_ID_WATCH + 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWizardActivity().setStep(4); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), + getString(R.string.wizard_example_rental_period), + mMovie.getBreadcrump(), null); + return guidance; + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + GuidedAction action = new GuidedAction.Builder() + .id(ACTION_ID_WATCH) + .title(getString(R.string.wizard_example_watch_now)) + .build(); + actions.add(action); + action = new GuidedAction.Builder() + .id(ACTION_ID_LATER) + .title(getString(R.string.wizard_example_later)) + .build(); + actions.add(action); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_WATCH == action.getId()) { + Toast.makeText(getActivity(), getString(R.string.wizard_example_watch_now_clicked), + Toast.LENGTH_SHORT).show(); + } + getActivity().finish(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java new file mode 100644 index 000000000..1f132342a --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.wizard; + +import android.app.Activity; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/** + * TODO: Javadoc + */ +public class WizardExampleActivity extends Activity { + + // When the user 'bought' the product and presses back, we don't want to show the 'Processing..' + // screen again, instead we want to go back to the very first step or close the wizard. Thus, we + // have to save the current step of the wizard and make it accessible to it's children. + private int mStep = 0; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setBackgroundDrawableResource(R.drawable.wizard_background_blackned); + + // Recover old step state. + if (savedInstanceState != null) { + mStep = savedInstanceState.getInt("step"); + } + + GuidedStepFragment fragment = new WizardExample1stStepFragment(); + fragment.setArguments(getIntent().getExtras()); // Delegate Movie to first step. + GuidedStepFragment.add(getFragmentManager(), fragment); + } + + public int getStep() { + return mStep; + } + + public void setStep(int step) { + mStep = step; + } + + @Override + public void onBackPressed() { + if (4 == getStep()) { + // The user 'bought' the product. When he presses 'Back' the Wizard will be closed and + // he will not be send back to 'Processing Payment...'-Screen. + finish(); + } else super.onBackPressed(); + } + + @Override + public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { + // Save current step persitently. + outPersistentState.putInt("step", mStep); + super.onSaveInstanceState(outState, outPersistentState); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java new file mode 100644 index 000000000..b83bd983a --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.wizard; + +import android.os.Bundle; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.models.Movie; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/** + * TODO: JavaDoc + */ +public class WizardExampleBaseStepFragment extends GuidedStepFragment { + + protected Movie mMovie; + + @Override + public int onProvideTheme() { + return R.style.Theme_Example_LeanbackWizard; + } + + WizardExampleActivity getWizardActivity() { + if (!(getActivity() instanceof WizardExampleActivity)) { + throw new IllegalStateException(WizardExampleActivity.class.getName() + " expected."); + } + return (WizardExampleActivity)getActivity(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + mMovie = (Movie)getArguments().getSerializable("movie"); + super.onCreate(savedInstanceState); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java index 311f88518..eeda4dae8 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java @@ -18,11 +18,10 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.BaseCardView; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java index 4f661e098..ed1dd4a80 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java @@ -18,12 +18,11 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.BaseCardView; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; import android.view.LayoutInflater; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java deleted file mode 100644 index 79f951938..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Card.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.models; - -import android.content.Context; -import android.graphics.Color; -import android.util.Log; - -import com.google.gson.annotations.SerializedName; - -import java.net.URI; -import java.net.URISyntaxException; - -/** - * This is a generic example of a custom data object, containing info we might want to keep with - * each card on the home screen - */ -public class Card { - - @SerializedName("title") private String mTitle = ""; - @SerializedName("description") private String mDescription = ""; - @SerializedName("extraText") private String mExtraText = ""; - @SerializedName("imageUrl") private String mImageUrl; - @SerializedName("footerColor") private String mFooterColor = null; - @SerializedName("selectedColor") private String mSelectedColor = null; - @SerializedName("localImageResource") private String mLocalImageResource = null; - @SerializedName("footerIconLocalImageResource") private String mFooterResource = null; - @SerializedName("type") private Card.Type mType; - @SerializedName("id") private int mId; - @SerializedName("width") private int mWidth; - @SerializedName("height") private int mHeight; - - public String getTitle() { - return mTitle; - } - - public int getWidth() { - return mWidth; - } - - public int getHeight() { - return mHeight; - } - - public int getId() { - return mId; - } - - public Card.Type getType() { - return mType; - } - - public String getDescription() { - return mDescription; - } - - public String getExtraText() { - return mExtraText; - } - - public int getFooterColor() { - if (mFooterColor == null) return -1; - return Color.parseColor(mFooterColor); - } - - public int getSelectedColor() { - if (mSelectedColor == null) return -1; - return Color.parseColor(mSelectedColor); - } - - public String getImageUrl() { - return mImageUrl; - } - - public URI getImageURI() { - if (getImageUrl() == null) return null; - try { - return new URI(getImageUrl()); - } catch (URISyntaxException e) { - Log.d("URI exception: ", getImageUrl()); - return null; - } - } - - public int getLocalImageResourceId(Context context) { - return context.getResources().getIdentifier(getLocalImageResourceName(), "drawable", - context.getPackageName()); - } - - public String getLocalImageResourceName() { - return mLocalImageResource; - } - - public String getFooterLocalImageResourceName() { - return mFooterResource; - } - - public enum Type { - - MOVIE_COMPLETE, - MOVIE, - MOVIE_BASE, - ICON, - SQUARE_BIG, - SINGLE_LINE, - GAME, - SQUARE_SMALL, - DEFAULT, - SIDE_INFO, - SIDE_INFO_TEST_1, - TEXT, - CHARACTER, - GRID_SQUARE - - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java deleted file mode 100644 index b2312cd61..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/CardRow.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.models; - -import com.google.gson.annotations.SerializedName; - -import java.util.List; - -/** - * This class represents a row of cards. In a real world application you might want to store more - * data than in this example. - */ -public class CardRow { - - // Used to determine whether the row shall use shadows when displaying its cards or not. - @SerializedName("shadow") private boolean mShadow = true; - @SerializedName("title") private String mTitle; - @SerializedName("cards") private List mCards; - - public String getTitle() { - return mTitle; - } - - public boolean useShadow() { - return mShadow; - } - - public List getCards() { - return mCards; - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java deleted file mode 100644 index 0445a1bd4..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/Song.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - * - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.models; - -import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.widget.Row; -import android.support.v17.leanback.widget.RowPresenter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.google.gson.annotations.SerializedName; - -public class Song extends Row { - - @SerializedName("title") private String mTitle = ""; - @SerializedName("description") private String mDescription = ""; - @SerializedName("text") private String mText = ""; - @SerializedName("image") private String mImage = null; - @SerializedName("file") private String mFile = null; - @SerializedName("duration") private String mDuration = null; - @SerializedName("number") private int mNumber = 0; - - - public String getDuration() { - return mDuration; - } - - public int getNumber() { - return mNumber; - } - - public String getText() { - return mText; - } - - public String getDescription() { - return mDescription; - } - - public String getTitle() { - return mTitle; - } - - public int getFileResource(Context context) { - return context.getResources() - .getIdentifier(mFile, "raw", context.getPackageName()); - } - - public int getImageResource(Context context) { - return context.getResources() - .getIdentifier(mImage, "drawable", context.getPackageName()); - } - - public interface OnSongRowClickListener { - - void onSongRowClicked(Song song); - - } - - public static class Presenter extends RowPresenter implements View.OnClickListener { - - private final Context mContext; - private OnSongRowClickListener mClickListener; - - - public Presenter(Context context) { - mContext = context; - setHeaderPresenter(null); - } - - public void setOnClickListener(OnSongRowClickListener listener) { - mClickListener = listener; - } - - @Override protected ViewHolder createRowViewHolder(ViewGroup parent) { - View view = LayoutInflater.from(mContext).inflate(R.layout.row_song, parent, false); - view.findViewById(R.id.rowContainer).setOnClickListener(this); - return new ViewHolder(view); - } - - @Override public boolean isUsingDefaultSelectEffect() { - return false; - } - - @Override protected void onBindRowViewHolder(ViewHolder vh, Object item) { - super.onBindRowViewHolder(vh, item); - Song song = (Song) item; - ((TextView) vh.view.findViewById(R.id.trackNumber)).setText("" + song.getNumber()); - ((TextView) vh.view.findViewById(R.id.trackDuration)).setText(song.getDuration()); - String text = song.getTitle() + " / " + song.getDescription(); - ((TextView) vh.view.findViewById(R.id.trackName)).setText(text); - vh.view.findViewById(R.id.rowContainer).setTag(item); - } - - @Override public void onClick(View v) { - if (mClickListener == null) return; - mClickListener.onSongRowClicked((Song) v.getTag()); - } - } -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java deleted file mode 100644 index 603f9aa41..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/models/SongList.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.cards.models; - -import com.google.gson.annotations.SerializedName; - -import java.util.List; - -/** - */ -public class SongList { - - @SerializedName("songs") private List mSongs; - - public List getSongs() { - return mSongs; - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java index b81f119ed..0301cdc1c 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java @@ -14,7 +14,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.BaseCardView; import android.support.v17.leanback.widget.Presenter; import android.view.ViewGroup; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java index 53d462069..1228b14a9 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java @@ -17,7 +17,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.PresenterSelector; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java index 60fa5b2aa..35a42a969 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java @@ -16,7 +16,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.cards.CharacterCardView; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; /** * This Presenter is used to display the characters card row in the DetailView examples. diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java index bf03753e8..09a9b672f 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java @@ -16,7 +16,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.ImageCardView; /** diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java index dfe34e22a..dcd7b80e1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java @@ -16,7 +16,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.BaseCardView; import android.view.LayoutInflater; import android.view.View; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java index f48a3cab1..24dedd5c6 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java @@ -16,7 +16,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.ImageCardView; /** diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java index a688f444c..7e65f0f13 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java @@ -16,7 +16,7 @@ package android.support.v17.leanback.supportleanbackshowcase.cards.presenters; import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.cards.TextCardView; -import android.support.v17.leanback.supportleanbackshowcase.cards.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; /** * The Presenter displays a card consisting of text as a replacement for a big image. The footer is diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Card.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Card.java new file mode 100644 index 000000000..ccaaf72df --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Card.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.models; + +import android.content.Context; +import android.graphics.Color; +import android.util.Log; + +import com.google.gson.annotations.SerializedName; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * This is a generic example of a custom data object, containing info we might want to keep with + * each card on the home screen + */ +public class Card { + + @SerializedName("title") private String mTitle = ""; + @SerializedName("description") private String mDescription = ""; + @SerializedName("extraText") private String mExtraText = ""; + @SerializedName("imageUrl") private String mImageUrl; + @SerializedName("footerColor") private String mFooterColor = null; + @SerializedName("selectedColor") private String mSelectedColor = null; + @SerializedName("localImageResource") private String mLocalImageResource = null; + @SerializedName("footerIconLocalImageResource") private String mFooterResource = null; + @SerializedName("type") private Card.Type mType; + @SerializedName("id") private int mId; + @SerializedName("width") private int mWidth; + @SerializedName("height") private int mHeight; + + public String getTitle() { + return mTitle; + } + + public int getWidth() { + return mWidth; + } + + public int getHeight() { + return mHeight; + } + + public int getId() { + return mId; + } + + public Card.Type getType() { + return mType; + } + + public String getDescription() { + return mDescription; + } + + public String getExtraText() { + return mExtraText; + } + + public int getFooterColor() { + if (mFooterColor == null) return -1; + return Color.parseColor(mFooterColor); + } + + public int getSelectedColor() { + if (mSelectedColor == null) return -1; + return Color.parseColor(mSelectedColor); + } + + public String getImageUrl() { + return mImageUrl; + } + + public URI getImageURI() { + if (getImageUrl() == null) return null; + try { + return new URI(getImageUrl()); + } catch (URISyntaxException e) { + Log.d("URI exception: ", getImageUrl()); + return null; + } + } + + public int getLocalImageResourceId(Context context) { + return context.getResources().getIdentifier(getLocalImageResourceName(), "drawable", + context.getPackageName()); + } + + public String getLocalImageResourceName() { + return mLocalImageResource; + } + + public String getFooterLocalImageResourceName() { + return mFooterResource; + } + + public enum Type { + + MOVIE_COMPLETE, + MOVIE, + MOVIE_BASE, + ICON, + SQUARE_BIG, + SINGLE_LINE, + GAME, + SQUARE_SMALL, + DEFAULT, + SIDE_INFO, + SIDE_INFO_TEST_1, + TEXT, + CHARACTER, + GRID_SQUARE + + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/CardRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/CardRow.java new file mode 100644 index 000000000..932b9b940 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/CardRow.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.models; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * This class represents a row of cards. In a real world application you might want to store more + * data than in this example. + */ +public class CardRow { + + // Used to determine whether the row shall use shadows when displaying its cards or not. + @SerializedName("shadow") private boolean mShadow = true; + @SerializedName("title") private String mTitle; + @SerializedName("cards") private List mCards; + + public String getTitle() { + return mTitle; + } + + public boolean useShadow() { + return mShadow; + } + + public List getCards() { + return mCards; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/DetailedCard.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/DetailedCard.java new file mode 100644 index 000000000..8727a4053 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/DetailedCard.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.models; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; + +import com.google.gson.annotations.SerializedName; + +public class DetailedCard { + + @SerializedName("title") private String mTitle = ""; + @SerializedName("description") private String mDescription = ""; + @SerializedName("text") private String mText = ""; + @SerializedName("localImageResource") private String mLocalImageResource = null; + @SerializedName("price") private String mPrice = null; + @SerializedName("characters") private Card[] mCharacters = null; + @SerializedName("recommended") private Card[] mRecommended = null; + @SerializedName("year") private int mYear = 0; + + + public String getPrice() { + return mPrice; + } + + public int getYear() { + return mYear; + } + + public String getLocalImageResource() { + return mLocalImageResource; + } + + public String getText() { + return mText; + } + + public String getDescription() { + return mDescription; + } + + public String getTitle() { + return mTitle; + } + + public Card[] getCharacters() { + return mCharacters; + } + + public Card[] getRecommended() { + return mRecommended; + } + + public int getLocalImageResourceId(Context context) { + return context.getResources() + .getIdentifier(getLocalImageResource(), "drawable", context.getPackageName()); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Movie.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Movie.java new file mode 100644 index 000000000..83912b3a0 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Movie.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.models; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +public class Movie implements Serializable { + + private static final long serialVersionUID = 133742L; + + @SerializedName("title") + private String mTitle = ""; + @SerializedName("price_hd") + private String mPriceHd = "n/a"; + @SerializedName("price_sd") + private String mPriceSd = "n/a"; + @SerializedName("breadcrump") + private String mBreadcrump = ""; + + public String getTitle() { + return mTitle; + } + + public String getBreadcrump() { + return mBreadcrump; + } + + public String getPriceHd() { + return mPriceHd; + } + + public String getPriceSd() { + return mPriceSd; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Song.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Song.java new file mode 100644 index 000000000..89729be80 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Song.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.models; + +import android.content.Context; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.google.gson.annotations.SerializedName; + +public class Song extends Row { + + @SerializedName("title") private String mTitle = ""; + @SerializedName("description") private String mDescription = ""; + @SerializedName("text") private String mText = ""; + @SerializedName("image") private String mImage = null; + @SerializedName("file") private String mFile = null; + @SerializedName("duration") private String mDuration = null; + @SerializedName("number") private int mNumber = 0; + + + public String getDuration() { + return mDuration; + } + + public int getNumber() { + return mNumber; + } + + public String getText() { + return mText; + } + + public String getDescription() { + return mDescription; + } + + public String getTitle() { + return mTitle; + } + + public int getFileResource(Context context) { + return context.getResources() + .getIdentifier(mFile, "raw", context.getPackageName()); + } + + public int getImageResource(Context context) { + return context.getResources() + .getIdentifier(mImage, "drawable", context.getPackageName()); + } + + public interface OnSongRowClickListener { + + void onSongRowClicked(Song song); + + } + + public static class Presenter extends RowPresenter implements View.OnClickListener { + + private final Context mContext; + private OnSongRowClickListener mClickListener; + + + public Presenter(Context context) { + mContext = context; + setHeaderPresenter(null); + } + + public void setOnClickListener(OnSongRowClickListener listener) { + mClickListener = listener; + } + + @Override protected ViewHolder createRowViewHolder(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.row_song, parent, false); + view.findViewById(R.id.rowContainer).setOnClickListener(this); + return new ViewHolder(view); + } + + @Override public boolean isUsingDefaultSelectEffect() { + return false; + } + + @Override protected void onBindRowViewHolder(ViewHolder vh, Object item) { + super.onBindRowViewHolder(vh, item); + Song song = (Song) item; + ((TextView) vh.view.findViewById(R.id.trackNumber)).setText("" + song.getNumber()); + ((TextView) vh.view.findViewById(R.id.trackDuration)).setText(song.getDuration()); + String text = song.getTitle() + " / " + song.getDescription(); + ((TextView) vh.view.findViewById(R.id.trackName)).setText(text); + vh.view.findViewById(R.id.rowContainer).setTag(item); + } + + @Override public void onClick(View v) { + if (mClickListener == null) return; + mClickListener.onSongRowClicked((Song) v.getTag()); + } + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/SongList.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/SongList.java new file mode 100644 index 000000000..034ae19b5 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/SongList.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.models; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + */ +public class SongList { + + @SerializedName("songs") private List mSongs; + + public List getSongs() { + return mSongs; + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/CardListRow.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/CardListRow.java new file mode 100644 index 000000000..19f2437da --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/CardListRow.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package android.support.v17.leanback.supportleanbackshowcase.utils; + +import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ObjectAdapter; + +/** + * The {@link CardListRow} allows the {@link ShadowRowPresenterSelector} to access the {@link CardRow} + * held by the row and determine whether to use a {@link android.support.v17.leanback.widget.Presenter} + * with or without a shadow. + */ +public class CardListRow extends ListRow { + + private CardRow mCardRow; + + public CardListRow(HeaderItem header, ObjectAdapter adapter, CardRow cardRow) { + super(header, adapter); + setCardRow(cardRow); + } + + public CardRow getCardRow() { + return mCardRow; + } + + public void setCardRow(CardRow cardRow) { + this.mCardRow = cardRow; + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Constants.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Constants.java new file mode 100644 index 000000000..1c9dd9cf6 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Constants.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.utils; + +public class Constants { + + public static final boolean LOCAL_LOGD = true; + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/PicassoBackgroundManagerTarget.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/PicassoBackgroundManagerTarget.java new file mode 100644 index 000000000..2723d0b07 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/PicassoBackgroundManagerTarget.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.utils; + +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.support.v17.leanback.app.BackgroundManager; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +/** + * Picasso target for updating default_background images + */ +public class PicassoBackgroundManagerTarget implements Target { + + private BackgroundManager mBackgroundManager; + + public PicassoBackgroundManagerTarget(BackgroundManager backgroundManager) { + this.mBackgroundManager = backgroundManager; + } + + @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) { + this.mBackgroundManager.setBitmap(bitmap); + } + + @Override public void onBitmapFailed(Drawable drawable) { + this.mBackgroundManager.setDrawable(drawable); + } + + @Override public void onPrepareLoad(Drawable drawable) { + // Do nothing, default_background manager has its own transitions + } + + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PicassoBackgroundManagerTarget that = (PicassoBackgroundManagerTarget) o; + + if (!mBackgroundManager.equals(that.mBackgroundManager)) return false; + + return true; + } + + @Override public int hashCode() { + return mBackgroundManager.hashCode(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/ResourceCache.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/ResourceCache.java new file mode 100644 index 000000000..09a196565 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/ResourceCache.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.utils; + +import android.util.SparseArray; +import android.view.View; + +/** + * ResourceCache allows retrieving children from a given view and caches the resulting views in + * order to prevent future lookups. + */ +public class ResourceCache { + + private final SparseArray mCachedViews = new SparseArray(); + + public ViewType getViewById(View view, int resId) { + View child = mCachedViews.get(resId, null); + if (child == null) { + child = view.findViewById(resId); + mCachedViews.put(resId, child); + } + return (ViewType) child; + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java new file mode 100644 index 000000000..257aedbd0 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.utils; + +import android.content.ContentResolver; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.widget.ImageView; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.RequestCreator; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +/** + * A collection of utility methods, all static. + */ +public class Utils { + + public static int convertDpToPixel(Context ctx, int dp) { + float density = ctx.getResources().getDisplayMetrics().density; + return Math.round((float) dp * density); + } + + /** + * Will read the content from a given {@link InputStream} and return it as a {@link String}. + * + * @param inputStream The {@link InputStream} which should be read. + * @return Returns null if the the {@link InputStream} could not be read. Else + * returns the content of the {@link InputStream} as {@link String}. + */ + public static String inputStreamToString(InputStream inputStream) { + try { + byte[] bytes = new byte[inputStream.available()]; + inputStream.read(bytes, 0, bytes.length); + String json = new String(bytes); + return json; + } catch (IOException e) { + return null; + } + } + + /** + * The method uses {@link Picasso} to fetch an image from a given url, resize it (if required) + * and display it inside an {@link ImageView}. + * + * @param context Context which is used to create a {@link Picasso} instance. + * @param uri The {@link URI} to fetch the image from. + * @param target The {@link ImageView} which shall display the image. + * @param resizeWidthInDp The target width of the image. Pass -1 if you don't want + * to resize the image. + * @param resizeHeightInDp The target height of the image. Pass -1 if you don't + * want to resize the image. + * @param centerCrop Centers and scales an image to fit the requested bounds. + * @param errorDrawable A drawable which will be shown in case the image could not be fetched + * from the server. + * @see {@link Picasso#with(Context)} + * @see {@link RequestCreator#resize(int, int)} + * @see {@link RequestCreator#centerCrop()} + * @see {@link RequestCreator#error(Drawable)} + */ + public static void loadImageFromUri(Context context, URI uri, ImageView target, + int resizeWidthInDp, int resizeHeightInDp, + boolean centerCrop, Drawable errorDrawable) { + if (uri == null) return; + RequestCreator builder = Picasso.with(context).load(uri.toString()); + if (resizeHeightInDp != -1 && resizeWidthInDp != -1) + builder.resize(Utils.convertDpToPixel(context, resizeWidthInDp), + Utils.convertDpToPixel(context, resizeHeightInDp)); + if (centerCrop) builder.centerCrop(); + builder.error(errorDrawable).into(target); + } + + public static Uri getResourceUri(Context context, int resID) { + return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + + context.getResources().getResourcePackageName(resID) + '/' + + context.getResources().getResourceTypeName(resID) + '/' + + context.getResources().getResourceEntryName(resID)); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml index 90c69b611..1dd92d8c9 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml @@ -19,7 +19,7 @@ android:layout_height="match_parent"> \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml index 34c3b3a2f..c6c81a3a1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml @@ -19,7 +19,7 @@ android:layout_height="match_parent"> \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 b/samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 deleted file mode 100644 index 5fdde6280..000000000 Binary files a/samples/SupportLeanbackShowcase/app/src/main/res/raw/koan_view_from_above_i_know_its_super_awesome.mp3 and /dev/null differ -- cgit v1.2.3 From 80116aacde385b9ff63b5aaccb5ef653b870fff3 Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Wed, 5 Aug 2015 10:04:31 -0700 Subject: Polished Wizard example for Showcase app Extracted Strings, added JavaDoc, refactored the call of the second Wizard screen to be less error-prone code. Change-Id: Ib8a8af7019818b29d71ee1bed1cac3e2b56e8c11 --- .../app/wizard/WizardExample1stStepFragment.java | 9 +++-- .../app/wizard/WizardExample2ndStepFragment.java | 42 +++++++--------------- .../app/wizard/WizardExample3rdStepFragment.java | 6 ++-- .../app/wizard/WizardExample4thStepFragment.java | 4 ++- .../app/wizard/WizardExampleActivity.java | 2 +- .../app/wizard/WizardExampleBaseStepFragment.java | 9 ++--- .../app/src/main/res/values/strings.xml | 2 ++ 7 files changed, 32 insertions(+), 42 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java index d9ddf7f27..0b0f6929c 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java @@ -24,7 +24,8 @@ import android.support.v17.leanback.widget.GuidedAction; import java.util.List; /** - * TODO: JavaDoc + * The first screen of the rental wizard. Gives the user the choice between renting the movie in SD + * or HD quality. */ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment { @@ -66,10 +67,8 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment @Override public void onGuidedActionClicked(GuidedAction action) { - GuidedStepFragment fragment = new WizardExample2ndStepFragment(); - Bundle args = getArguments(); // Reuse the same arguments this fragment was given. - args.putBoolean("hd", ACTION_ID_BUY_HD == action.getId()); - fragment.setArguments(args); + boolean rentHd = ACTION_ID_BUY_HD == action.getId(); + GuidedStepFragment fragment = WizardExample2ndStepFragment.build(rentHd, this); add(getFragmentManager(), fragment); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java index 4ed46eee8..7f3a83a39 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java @@ -28,13 +28,23 @@ import android.widget.Toast; import java.util.List; /** - * TODO: JavaDoc + * Displays the second screen of the rental wizard which requires the user to confirm his purchase. */ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment { + private static final String ARG_HD = "hd"; private static final int ACTION_ID_CONFIRM = 1; private static final int ACTION_ID_PAYMENT_METHOD = ACTION_ID_CONFIRM + 1; + public static GuidedStepFragment build(boolean hd, WizardExampleBaseStepFragment previousFragment) { + GuidedStepFragment fragment = new WizardExample2ndStepFragment(); + // Reuse the same arguments this fragment was given. + Bundle args = previousFragment.getArguments(); + args.putBoolean(ARG_HD, hd); + fragment.setArguments(args); + return fragment; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -50,35 +60,9 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment return guidance; } - @Override - public GuidedActionsStylist onCreateActionsStylist() { - GuidedActionsStylist stylist = new GuidedActionsStylist() { - - @Override - public void onBindViewHolder(ViewHolder vh, GuidedAction action) { - super.onBindViewHolder(vh, action); - - if (ACTION_ID_CONFIRM == action.getId()) { - Drawable background = getResources().getDrawable( - R.drawable.wizard_important_action_item_background, null); - vh.view.setBackground(background); - vh.getTitleView().setTextColor(Color.parseColor("#666666")); - vh.getDescriptionView().setTextColor(Color.parseColor("#666666")); - } else { - vh.view.setBackground(null); - vh.getTitleView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, - getActivity().getTheme())); - vh.getDescriptionView().setTextColor(getResources().getColor(android.support.v17.leanback.R.color.lb_guidedactions_item_unselected_text_color, - getActivity().getTheme())); - } - } - }; - return stylist; - } - @Override public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - boolean rentHighDefinition = getArguments().getBoolean("hd"); + boolean rentHighDefinition = getArguments().getBoolean(ARG_HD); GuidedAction action = new GuidedAction.Builder() .id(ACTION_ID_CONFIRM) @@ -89,7 +73,7 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment action = new GuidedAction.Builder() .id(ACTION_ID_PAYMENT_METHOD) .title(getString(R.string.wizard_example_payment_method)) - .description("Visa - 1234 Balance $60.00") + .description(getString(R.string.wizard_example_visa_balance)) .build(); actions.add(action); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java index 7a336c77f..0cc422150 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java @@ -26,7 +26,9 @@ import android.support.v17.leanback.widget.GuidedActionsStylist; import java.util.List; /** - * TODO: JavaDoc + * This is the third screen of the rental wizard which will display a progressbar while waiting for + * the server to process the rental. The server communication is faked for the sake of this example + * by waiting four seconds until continuing. */ public class WizardExample3rdStepFragment extends WizardExampleBaseStepFragment { @@ -75,7 +77,7 @@ public class WizardExample3rdStepFragment extends WizardExampleBaseStepFragment @Override public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(mMovie.getTitle(), - "Just a second...", + getString(R.string.wizard_example_just_a_second), mMovie.getBreadcrump(), null); return guidance; } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java index 255705ca5..450311c24 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java @@ -24,7 +24,9 @@ import android.widget.Toast; import java.util.List; /** - * TODO: JavaDoc + * The last screen of the Wizard gives to options to either watch the rented movie now or later. Due + * to keep this example simple and focused on the usage of the GuidedStepFragment, clicking on + * either action will end the wizard. You might however start a new Activity playing the movie. */ public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java index 1f132342a..bde1a06fd 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java @@ -21,7 +21,7 @@ import android.support.v17.leanback.app.GuidedStepFragment; import android.support.v17.leanback.supportleanbackshowcase.R; /** - * TODO: Javadoc + * An Activity displaying a wizard for renting a movie. */ public class WizardExampleActivity extends Activity { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java index b83bd983a..8fd59814b 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java @@ -20,9 +20,10 @@ import android.support.v17.leanback.supportleanbackshowcase.models.Movie; import android.support.v17.leanback.supportleanbackshowcase.R; /** - * TODO: JavaDoc + * A base class which provides all it's implementations with a method #getWizardActivity(). It also + * makes sure that the wizard is using the correct theme. */ -public class WizardExampleBaseStepFragment extends GuidedStepFragment { +public abstract class WizardExampleBaseStepFragment extends GuidedStepFragment { protected Movie mMovie; @@ -35,12 +36,12 @@ public class WizardExampleBaseStepFragment extends GuidedStepFragment { if (!(getActivity() instanceof WizardExampleActivity)) { throw new IllegalStateException(WizardExampleActivity.class.getName() + " expected."); } - return (WizardExampleActivity)getActivity(); + return (WizardExampleActivity) getActivity(); } @Override public void onCreate(Bundle savedInstanceState) { - mMovie = (Movie)getArguments().getSerializable("movie"); + mMovie = (Movie) getArguments().getSerializable("movie"); super.onCreate(savedInstanceState); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml index 4c2c673ac..9bc6ffa28 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml @@ -85,4 +85,6 @@ Watch now Later \'Watch now\' clicked. + Visa - 1234 Balance $60.00 + Just a second... \ No newline at end of file -- cgit v1.2.3 From 63e8181cee42782e4bac6817db2214d0c1954177 Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Wed, 5 Aug 2015 10:16:38 -0700 Subject: Removed Browsing example from Showcase app There are no plans for now to show a browsing example which is why it can be removed for now. There was no code written so far for this example. Change-Id: I0580021ddc0f385d616074c61cc1c449e75357ad --- .../app/BrowserExample01Fragment.java | 92 ------ .../supportleanbackshowcase/app/MainFragment.java | 2 +- .../app/src/main/res/raw/browsing_example_01.json | 356 --------------------- .../app/src/main/res/raw/cards_launcher.json | 70 ---- .../app/src/main/res/raw/launcher_cards.json | 63 ++++ 5 files changed, 64 insertions(+), 519 deletions(-) delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/raw/launcher_cards.json (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java deleted file mode 100644 index 1575c8507..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/BrowserExample01Fragment.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.app; - -import android.os.Bundle; -import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; -import android.support.v17.leanback.supportleanbackshowcase.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.SearchOrbView; -import android.view.View; -import android.widget.Toast; - -import com.google.gson.Gson; - - -public class BrowserExample01Fragment extends BrowseFragment { - - private static final String TAG = "BrowserExample01Fragment"; - - private ArrayObjectAdapter mRowsAdapter; - - @Override public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setupUi(); - setupRowAdapter(); - } - - private void setupUi() { - setHeadersState(HEADERS_ENABLED); - setHeadersTransitionOnBackEnabled(true); - setSearchAffordanceColors( - new SearchOrbView.Colors(getResources().getColor(R.color.search_color), - getResources().getColor(R.color.search_bright_color), - getResources().getColor(R.color.search_icon_color))); - setBrandColor(getResources().getColor(R.color.fastlane_background)); - setTitle("Browser Example 01"); - setOnSearchClickedListener(new View.OnClickListener() { - @Override public void onClick(View v) { - Toast.makeText(getActivity(), getString(R.string.implement_search), - Toast.LENGTH_LONG).show(); - } - }); - } - - private void setupRowAdapter() { - mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); - createRows(); - setAdapter(mRowsAdapter); - } - - private void createRows() { - String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.browsing_example_01)); - CardRow[] rows = new Gson().fromJson(json, CardRow[].class); - for (CardRow row : rows) { - mRowsAdapter.add(createCardRow(row)); - } - } - - private ListRow createCardRow(final CardRow cardRow) { - // Build main row using the ImageCardViewPresenter. - PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); - for (Card card : cardRow.getCards()) { - listRowAdapter.add(card); - } - HeaderItem header = new HeaderItem(cardRow.getTitle()); - return new CardListRow(header, listRowAdapter, cardRow); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java index e836ad218..42a7cc7e0 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java @@ -98,7 +98,7 @@ public class MainFragment extends BrowseFragment { private void createRows() { String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.cards_launcher)); + .inputStreamToString(getResources().openRawResource(R.raw.launcher_cards)); CardRow[] rows = new Gson().fromJson(json, CardRow[].class); for (CardRow row : rows) { mRowsAdapter.add(createCardRow(row)); diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json deleted file mode 100644 index addc33ca4..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/raw/browsing_example_01.json +++ /dev/null @@ -1,356 +0,0 @@ -[ - { - "title": "Movie Collection", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Recommendations", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Featured Movies", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Categories", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Favorites", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - }, - { - "title": "Settings", - "cards": [ - { - "type": "THIN", - "title": "The Amazing Spuder-Man", - "description": "$3.99", - "localImageResource": "card_image_movie_01" - }, - { - "type": "THIN", - "title": "American Psycho", - "description": "$3.99", - "localImageResource": "card_image_movie_02" - }, - { - "type": "THIN", - "title": "Big Hero 6", - "description": "$3.99", - "localImageResource": "card_image_movie_03" - }, - { - "type": "THIN", - "title": "Edge of Tomorrow", - "description": "$3.99", - "localImageResource": "card_image_movie_04" - }, - { - "type": "THIN", - "title": "The Hobbit: The Desolation of Smaug", - "description": "$3.99", - "localImageResource": "card_image_movie_05" - }, - { - "type": "THIN", - "title": "Interstellar", - "description": "$3.99", - "localImageResource": "card_image_movie_06" - }, - { - "type": "THIN", - "title": "Jurassic Park", - "description": "$3.99", - "localImageResource": "card_image_movie_07" - }, - { - "type": "THIN", - "title": "The Hunger Games: Mockingjay Part I", - "description": "$3.99", - "localImageResource": "card_image_movie_08" - }, - { - "type": "THIN", - "title": "Planes", - "description": "$3.99", - "localImageResource": "card_image_movie_09" - } - ] - } -] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json deleted file mode 100644 index 0f35a1536..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_launcher.json +++ /dev/null @@ -1,70 +0,0 @@ -[ - { - "title": "", - "cards": [ - { - "id": 0, - "type": "DEFAULT", - "title": "Card Examples", - "localImageResource": "thumbnail_example_cards", - "description": "Showcase of various card design and layouts" - }, - { - "id": 1, - "type": "DEFAULT", - "title": "Browsing Examples", - "localImageResource": "thumbnail_example_browse", - "description": "Showcase of various card design and layouts" - }, - { - "id": 2, - "type": "DEFAULT", - "title": "Grid Examples", - "localImageResource": "thumbnail_example_grid", - "description": "Showcase of various card design and layouts" - }, - { - "id": 3, - "type": "DEFAULT", - "title": "Detail Examples", - "localImageResource": "thumbnail_example_detail", - "description": "Showcase of various card design and layouts" - }, - { - "id": 4, - "type": "DEFAULT", - "title": "Video consumption Examples", - "localImageResource": "thumbnail_example_video_consumption", - "description": "Showcase of various card design and layouts" - }, - { - "id": 5, - "type": "DEFAULT", - "title": "Music consumption Examples", - "localImageResource": "thumbnail_example_music_consumption", - "description": "Showcase of various card design and layouts" - }, - { - "id": 6, - "type": "DEFAULT", - "title": "Wizard Examples", - "localImageResource": "thumbnail_example_wizard", - "description": "Showcase of various card design and layouts" - }, - { - "id": 7, - "type": "DEFAULT", - "title": "Settings Examples", - "localImageResource": "thumbnail_example_settings", - "description": "Showcase of various card design and layouts" - }, - { - "id": 8, - "type": "DEFAULT", - "title": "Dialog Examples", - "localImageResource": "thumbnail_example_dialog", - "description": "Showcase of various card design and layouts" - } - ] - } -] \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/raw/launcher_cards.json b/samples/SupportLeanbackShowcase/app/src/main/res/raw/launcher_cards.json new file mode 100644 index 000000000..20faafda0 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/launcher_cards.json @@ -0,0 +1,63 @@ +[ + { + "title": "", + "cards": [ + { + "id": 0, + "type": "DEFAULT", + "title": "Card Examples", + "localImageResource": "thumbnail_example_cards", + "description": "Showcase of various card design and layouts" + }, + { + "id": 2, + "type": "DEFAULT", + "title": "Grid Examples", + "localImageResource": "thumbnail_example_grid", + "description": "Showcase of various card design and layouts" + }, + { + "id": 3, + "type": "DEFAULT", + "title": "Detail Examples", + "localImageResource": "thumbnail_example_detail", + "description": "Showcase of various card design and layouts" + }, + { + "id": 4, + "type": "DEFAULT", + "title": "Video consumption Examples", + "localImageResource": "thumbnail_example_video_consumption", + "description": "Showcase of various card design and layouts" + }, + { + "id": 5, + "type": "DEFAULT", + "title": "Music consumption Examples", + "localImageResource": "thumbnail_example_music_consumption", + "description": "Showcase of various card design and layouts" + }, + { + "id": 6, + "type": "DEFAULT", + "title": "Wizard Examples", + "localImageResource": "thumbnail_example_wizard", + "description": "Showcase of various card design and layouts" + }, + { + "id": 7, + "type": "DEFAULT", + "title": "Settings Examples", + "localImageResource": "thumbnail_example_settings", + "description": "Showcase of various card design and layouts" + }, + { + "id": 8, + "type": "DEFAULT", + "title": "Dialog Examples", + "localImageResource": "thumbnail_example_dialog", + "description": "Showcase of various card design and layouts" + } + ] + } +] \ No newline at end of file -- cgit v1.2.3 From aeedeb7d6077254f7fb52f20f285d606904f49cf Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Wed, 5 Aug 2015 10:24:20 -0700 Subject: Cleaned up strings.xml Removed unused strings. Change-Id: I4752b86795a0b03b7de33bad3d736ba3ab2d8392 --- .../app/src/main/res/values/strings.xml | 34 ---------------------- 1 file changed, 34 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml index 9bc6ffa28..9a46e5496 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml @@ -16,42 +16,8 @@ ShowcaseApp - Related Videos - - Error - OK - Pause - Play - Stop - 00:00 - Play Pause Button - Loading… - No video was found - About DemoCast Player - Version: %1$s - Popular Videos - PREFERENCES - Grid View - Error Fragment - Personal Settings - Watch trailer - FREE - Rent By Day - From $1.99 - Buy and Own - AT $9.99 - Movie - shouldStart - startPosition - Search Results - Media loading timed out - Media server was not reachable - Failed to load video - An error occurred - Dismiss - Oops Implement your own in-app search. Card Examples DetailView Example -- cgit v1.2.3 From 26b7df1102ba372d3e430b7389a175d28dbd474f Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Wed, 5 Aug 2015 10:32:56 -0700 Subject: Polished Grid example and added a few missing details at Launcher fragment. Video- and Music examples now also use an Activity. BackgroundHandler in MainFragment removed. Removed unused Log-Tag field and added correct background. Changed Grid Zoom factor. Moved Grid- and Card example to their own packages and they now are started using an Activity. Launcher fragment uses correct primaryColor and its row has been lowered. Music and Video consumption example are using Activities as well. Thus BackgroundManager in MainFragment is unnecessair, which is why it got removed. Change-Id: I928614314677706f19e648666697f0a710d88e0a --- .../app/src/main/AndroidManifest.xml | 14 +- .../app/CardExampleFragment.java | 95 ------------- .../supportleanbackshowcase/app/GridExample.java | 58 -------- .../supportleanbackshowcase/app/MainFragment.java | 150 ++++----------------- .../app/cards/CardExampleActivity.java | 34 +++++ .../app/cards/CardExampleFragment.java | 93 +++++++++++++ .../app/details/DetailViewExampleFragment.java | 2 +- .../app/grid/GridExample.java | 57 ++++++++ .../app/grid/GridExampleActivity.java | 30 +++++ .../app/media/MusicExampleActivity.java | 30 +++++ .../app/media/VideoConsumptionExampleFragment.java | 28 ++-- .../app/media/VideoExampleActivity.java | 39 ++++++ .../app/settings/SettingsExampleFragment.java | 23 ++-- .../main/res/drawable-xhdpi/background_food.jpg | Bin 0 -> 233732 bytes .../src/main/res/layout/activity_cards_example.xml | 27 ++++ .../main/res/layout/activity_detail_example.xml | 1 + .../src/main/res/layout/activity_grid_example.xml | 27 ++++ .../app/src/main/res/layout/activity_main.xml | 1 + .../src/main/res/layout/activity_music_example.xml | 27 ++++ .../src/main/res/layout/activity_video_example.xml | 27 ++++ .../app/src/main/res/values/arrays.xml | 8 ++ .../app/src/main/res/values/styles.xml | 5 + .../app/src/main/res/values/themes.xml | 6 +- .../app/src/main/res/xml/prefs.xml | 57 +++++--- 24 files changed, 525 insertions(+), 314 deletions(-) delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoExampleActivity.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_food.jpg create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_music_example.xml create mode 100644 samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_video_example.xml (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index ec5220bc7..df351806c 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -17,7 +17,7 @@ android:icon="@mipmap/app_banner_sample_app" android:label="@string/app_name" android:largeHeap="true" - android:theme="@style/Theme.Example.Leanback"> + android:theme="@style/Theme.Example.LeanbackLauncher"> + + + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java deleted file mode 100644 index 7e1646f09..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/CardExampleFragment.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.app; - -import android.os.Bundle; -import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; -import android.support.v17.leanback.supportleanbackshowcase.models.Card; -import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.HeaderItem; -import android.support.v17.leanback.widget.ListRow; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.SearchOrbView; -import android.view.View; -import android.widget.Toast; - -import com.google.gson.Gson; - -/** - * This fragment will be shown when the "Card Examples" card is selected at the home menu. It will - * display multiple card types. - */ -public class CardExampleFragment extends BrowseFragment { - - private static final String TAG = "CardExampleFragment"; - - private ArrayObjectAdapter mRowsAdapter; - - @Override public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setupUi(); - setupRowAdapter(); - } - - private void setupUi() { - setHeadersState(HEADERS_ENABLED); - setHeadersTransitionOnBackEnabled(true); - setSearchAffordanceColors( - new SearchOrbView.Colors(getResources().getColor(R.color.search_color), - getResources().getColor(R.color.search_bright_color), - getResources().getColor(R.color.search_icon_color))); - setBrandColor(getResources().getColor(R.color.fastlane_background)); - setTitle(getString(R.string.card_examples_title)); - setOnSearchClickedListener(new View.OnClickListener() { - @Override public void onClick(View v) { - Toast.makeText(getActivity(), getString(R.string.implement_search), - Toast.LENGTH_LONG).show(); - } - }); - } - - private void setupRowAdapter() { - mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); - createRows(); - setAdapter(mRowsAdapter); - } - - private void createRows() { - String json = Utils - .inputStreamToString(getResources().openRawResource(R.raw.cards_example)); - CardRow[] rows = new Gson().fromJson(json, CardRow[].class); - for (CardRow row : rows) { - mRowsAdapter.add(createCardRow(row)); - } - } - - private ListRow createCardRow(final CardRow cardRow) { - // Build main row using the ImageCardViewPresenter. - PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); - for (Card card : cardRow.getCards()) { - listRowAdapter.add(card); - } - HeaderItem header = new HeaderItem(cardRow.getTitle()); - return new CardListRow(header, listRowAdapter, cardRow); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java deleted file mode 100644 index 1c6177ff1..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/GridExample.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.app; - -import android.os.Bundle; -import android.support.v17.leanback.app.VerticalGridFragment; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; -import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.FocusHighlight; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.VerticalGridPresenter; - -import com.google.gson.Gson; - -/** - * An example how to use leanback's {@link VerticalGridFragment}. - */ -public class GridExample extends VerticalGridFragment { - - private static final String TAG = "GridExample"; - private static final int COLUMNS = 4; - private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_NONE; - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTitle(getString(R.string.grid_example_title)); - setupRowAdapter(); - } - - private void setupRowAdapter() { - VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); - gridPresenter.setNumberOfColumns(COLUMNS); - setGridPresenter(gridPresenter); - - PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); - String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); - CardRow row = new Gson().fromJson(json, CardRow.class); - adapter.addAll(0, row.getCards()); - setAdapter(adapter); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java index 42a7cc7e0..643259def 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java @@ -14,29 +14,23 @@ package android.support.v17.leanback.supportleanbackshowcase.app; -import android.app.Fragment; import android.content.Intent; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.os.Handler; -import android.support.v17.leanback.app.BackgroundManager; import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.cards.CardExampleActivity; import android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleActivity; import android.support.v17.leanback.supportleanbackshowcase.app.dialog.DialogExampleActivity; -import android.support.v17.leanback.supportleanbackshowcase.app.media.MusicConsumptionExampleFragment; -import android.support.v17.leanback.supportleanbackshowcase.app.media.VideoConsumptionExampleFragment; -import android.support.v17.leanback.supportleanbackshowcase.app.media.VideoSurfaceFragment; +import android.support.v17.leanback.supportleanbackshowcase.app.grid.GridExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.media.MusicExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.media.VideoExampleActivity; import android.support.v17.leanback.supportleanbackshowcase.app.settings.SettingsExampleActivity; import android.support.v17.leanback.supportleanbackshowcase.app.wizard.WizardExampleActivity; -import android.support.v17.leanback.supportleanbackshowcase.utils.Constants; -import android.support.v17.leanback.supportleanbackshowcase.models.Movie; -import android.support.v17.leanback.supportleanbackshowcase.utils.PicassoBackgroundManagerTarget; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.models.Movie; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; @@ -46,50 +40,23 @@ import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.PresenterSelector; import android.support.v17.leanback.widget.Row; import android.support.v17.leanback.widget.RowPresenter; -import android.util.DisplayMetrics; -import android.util.Log; import com.google.gson.Gson; -import com.squareup.picasso.Picasso; -import com.squareup.picasso.Target; - -import java.net.URI; -import java.util.Timer; -import java.util.TimerTask; public class MainFragment extends BrowseFragment { - public static final String VIDEO_SURFACE_FRAGMENT_TAG = "VIDEO_SURFACE"; - private static final String TAG = "MainFragment"; - private static final int BACKGROUND_UPDATE_DELAY = 300; - private static final int DEFAULT_BACKGROUND_IMAGE = R.drawable.default_background; - private final Handler mHandler = new Handler(); private ArrayObjectAdapter mRowsAdapter; - private Target mBackgroundTarget; - private Timer mBackgroundTimer; - private URI mBackgroundURI; - private BackgroundManager mBackgroundManager; - private DisplayMetrics mMetrics; - @Override public void onActivityCreated(Bundle savedInstanceState) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onActivityCreated"); + @Override + public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - setupBackgroundManager(); setupUIElements(); setupRowAdapter(); setupEventListeners(); } - @Override public void onDestroy() { - super.onDestroy(); - if (null != mBackgroundTimer) { - if (Constants.LOCAL_LOGD) Log.d(TAG, "onDestroy: " + mBackgroundTimer.toString()); - mBackgroundTimer.cancel(); - } - } - private void setupRowAdapter() { mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); createRows(); @@ -114,18 +81,6 @@ public class MainFragment extends BrowseFragment { return new ListRow(listRowAdapter); } - private void setupBackgroundManager() { - mBackgroundManager = BackgroundManager.getInstance(getActivity()); - mBackgroundManager.setThemeDrawableResourceId(DEFAULT_BACKGROUND_IMAGE); - mBackgroundManager.attach(getActivity().getWindow()); - - mBackgroundTarget = new PicassoBackgroundManagerTarget(mBackgroundManager); - mMetrics = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); - getView().setBackgroundResource(R.drawable.bg_living_room_wide); - //updateBackgroundImage(R.drawable.bg_living_room_wide); - } - private void setupUIElements() { setTitle(getString(R.string.browse_title)); setBadgeDrawable(getResources().getDrawable(R.drawable.title_android_tv, null)); @@ -139,53 +94,24 @@ public class MainFragment extends BrowseFragment { setOnItemViewSelectedListener(new ItemViewSelectedListener()); } - protected void updateBackgroundImage(URI uri) { - // Deactivated until we decide whether to load a background image from an URL or resource. @hahnr - if (true) return; - Picasso.with(getActivity()).load(uri.toString()) - .resize(mMetrics.widthPixels, mMetrics.heightPixels).centerCrop() - .error(DEFAULT_BACKGROUND_IMAGE).into(mBackgroundTarget); - } - - protected void updateBackgroundImage(Drawable drawable) { - mBackgroundManager.setDrawable(drawable); - } - - protected void updateBackgroundImage(int resId) { - mBackgroundManager.setDrawable(getResources().getDrawable(resId, null)); - } - - private void startBackgroundTimer() { - if (null != mBackgroundTimer) { - mBackgroundTimer.cancel(); - } - mBackgroundTimer = new Timer(); - mBackgroundTimer.schedule(new UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY); - } - private final class ItemViewClickedListener implements OnItemViewClickedListener { - @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { + @Override + public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { Card card = (Card) item; int id = card.getId(); switch (id) { case 0: { - updateBackgroundImage(new ColorDrawable( - getResources().getColor(R.color.card_examples_background))); - Fragment fragment = new CardExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); + Intent intent = new Intent(getActivity().getBaseContext(), + CardExampleActivity.class); + startActivity(intent); break; } case 2: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_canyon, null)); - Fragment fragment = new GridExample(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); + Intent intent = new Intent(getActivity().getBaseContext(), + GridExampleActivity.class); + startActivity(intent); break; } case 3: { @@ -195,23 +121,15 @@ public class MainFragment extends BrowseFragment { break; } case 4: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_canyon, null)); - Fragment fragment = new VideoConsumptionExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, new VideoSurfaceFragment(), - VIDEO_SURFACE_FRAGMENT_TAG) - .add(R.id.fragmentContainer, fragment).addToBackStack(null) - .commit(); + Intent intent = new Intent(getActivity().getBaseContext(), + VideoExampleActivity.class); + startActivity(intent); break; } case 5: { - updateBackgroundImage( - getResources().getDrawable(R.drawable.background_sax, null)); - Fragment fragment = new MusicConsumptionExampleFragment(); - getFragmentManager().beginTransaction() - .replace(R.id.fragmentContainer, fragment) - .addToBackStack(null).commit(); + Intent intent = new Intent(getActivity().getBaseContext(), + MusicExampleActivity.class); + startActivity(intent); break; } case 6: { @@ -254,21 +172,9 @@ public class MainFragment extends BrowseFragment { private final class ItemViewSelectedListener implements OnItemViewSelectedListener { - @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { - } - } - - private class UpdateBackgroundTask extends TimerTask { - - @Override public void run() { - mHandler.post(new Runnable() { - @Override public void run() { - if (mBackgroundURI != null) { - updateBackgroundImage(mBackgroundURI); - } - } - }); + @Override + public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { } } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleActivity.java new file mode 100644 index 000000000..7b8225fe7 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleActivity.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.cards; + +import android.app.Activity; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.dialog.DialogExampleFragment; + +/** + * TODO: Javadoc + */ +public class CardExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_cards_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java new file mode 100644 index 000000000..a7b3f9771 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.cards; + +import android.os.Bundle; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.Card; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.SearchOrbView; +import android.view.View; +import android.widget.Toast; + +import com.google.gson.Gson; + +/** + * This fragment will be shown when the "Card Examples" card is selected at the home menu. It will + * display multiple card types. + */ +public class CardExampleFragment extends BrowseFragment { + + private ArrayObjectAdapter mRowsAdapter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setupUi(); + setupRowAdapter(); + } + + private void setupUi() { + setHeadersState(HEADERS_ENABLED); + setHeadersTransitionOnBackEnabled(true); + setSearchAffordanceColors( + new SearchOrbView.Colors(getResources().getColor(R.color.search_color), + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); + setBrandColor(getResources().getColor(R.color.fastlane_background)); + setTitle(getString(R.string.card_examples_title)); + setOnSearchClickedListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.implement_search), + Toast.LENGTH_LONG).show(); + } + }); + } + + private void setupRowAdapter() { + mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); + createRows(); + setAdapter(mRowsAdapter); + } + + private void createRows() { + String json = Utils + .inputStreamToString(getResources().openRawResource(R.raw.cards_example)); + CardRow[] rows = new Gson().fromJson(json, CardRow[].class); + for (CardRow row : rows) { + mRowsAdapter.add(createCardRow(row)); + } + } + + private ListRow createCardRow(final CardRow cardRow) { + // Build main row using the ImageCardViewPresenter. + PresenterSelector presenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); + for (Card card : cardRow.getCards()) { + listRowAdapter.add(card); + } + HeaderItem header = new HeaderItem(cardRow.getTitle()); + return new CardListRow(header, listRowAdapter, cardRow); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java index 9c541e237..7f9e77a30 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java @@ -148,7 +148,7 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem null); getView().setBackgroundColor(backgroundColor); } else { - getView().setBackgroundResource(R.drawable.background_canyon); + getView().setBackground(null); } } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java new file mode 100644 index 000000000..e8cf3eba3 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.grid; + +import android.os.Bundle; +import android.support.v17.leanback.app.VerticalGridFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.FocusHighlight; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.VerticalGridPresenter; + +import com.google.gson.Gson; + +/** + * An example how to use leanback's {@link VerticalGridFragment}. + */ +public class GridExample extends VerticalGridFragment { + + private static final int COLUMNS = 4; + private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_MEDIUM; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(getString(R.string.grid_example_title)); + setupRowAdapter(); + } + + private void setupRowAdapter() { + VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); + gridPresenter.setNumberOfColumns(COLUMNS); + setGridPresenter(gridPresenter); + + PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); + String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); + CardRow row = new Gson().fromJson(json, CardRow.class); + adapter.addAll(0, row.getCards()); + setAdapter(adapter); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleActivity.java new file mode 100644 index 000000000..e2d0887af --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleActivity.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.grid; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/** + * TODO: Javadoc + */ +public class GridExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_grid_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicExampleActivity.java new file mode 100644 index 000000000..3107ed615 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicExampleActivity.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/** + * TODO: Javadoc + */ +public class MusicExampleActivity extends Activity { + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_music_example); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java index 991a95f39..9a40635cf 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java @@ -37,12 +37,14 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp private ArrayObjectAdapter mRowsAdapter; private MediaPlayerGlue mGlue; - @Override public void onCreate(Bundle savedInstanceState) { + @Override + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGlue = new VideoMediaPlayerGlue(getActivity(), this) { - @Override protected void onRowChanged(PlaybackControlsRow row) { + @Override + protected void onRowChanged(PlaybackControlsRow row) { if (mRowsAdapter == null) return; mRowsAdapter.notifyArrayItemRangeChanged(0, 1); } @@ -55,10 +57,11 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp mGlue.setMediaSource(URL); Fragment videoSurfaceFragment = getFragmentManager() - .findFragmentByTag(MainFragment.VIDEO_SURFACE_FRAGMENT_TAG); + .findFragmentByTag(VideoExampleActivity.VIDEO_SURFACE_FRAGMENT_TAG); SurfaceView surface = (SurfaceView) videoSurfaceFragment.getView(); surface.getHolder().addCallback(new SurfaceHolder.Callback() { - @Override public void surfaceCreated(SurfaceHolder holder) { + @Override + public void surfaceCreated(SurfaceHolder holder) { mGlue.setDisplay(holder); } @@ -67,7 +70,8 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp // Nothing to do } - @Override public void surfaceDestroyed(SurfaceHolder holder) { + @Override + public void surfaceDestroyed(SurfaceHolder holder) { } }); @@ -75,12 +79,14 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp addPlaybackControlsRow(); } - @Override public void onStart() { + @Override + public void onStart() { super.onStart(); mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); } - @Override public void onStop() { + @Override + public void onStop() { super.onStop(); mGlue.enableProgressUpdating(false); mGlue.reset(); @@ -95,14 +101,16 @@ public class VideoConsumptionExampleFragment extends PlaybackOverlayFragment imp setOnItemViewClickedListener(this); } - @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, - RowPresenter.ViewHolder rowViewHolder, Row row) { + @Override + public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { if (!(item instanceof Action)) return; mGlue.onActionClicked((Action) item); } - @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData metaData) { + @Override + public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData metaData) { mGlue.startPlayback(); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoExampleActivity.java new file mode 100644 index 000000000..63eef8219 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoExampleActivity.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.media; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v17.leanback.supportleanbackshowcase.R; + +/** + * TODO: Javadoc + */ +public class VideoExampleActivity extends Activity { + + public static final String VIDEO_SURFACE_FRAGMENT_TAG = "VIDEO_SURFACE"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_video_example); + + + getFragmentManager().beginTransaction() + .replace(R.id.videoFragment, new VideoSurfaceFragment(), VIDEO_SURFACE_FRAGMENT_TAG) + .add(R.id.videoFragment, new VideoConsumptionExampleFragment()) + .commit(); + } +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java index 72766d1c2..b9bb77f6a 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java @@ -18,7 +18,6 @@ import android.app.Fragment; import android.content.Context; import android.os.Bundle; import android.support.v14.preference.PreferenceFragment; -import android.support.v17.leanback.supportleanbackshowcase.utils.Constants; import android.support.v17.leanback.supportleanbackshowcase.R; import android.support.v17.preference.LeanbackPreferenceFragment; import android.support.v17.preference.LeanbackSettingsFragment; @@ -26,13 +25,13 @@ import android.support.v7.preference.DialogPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; -import android.util.Log; +import android.widget.Toast; +import java.util.Arrays; import java.util.Stack; public class SettingsExampleFragment extends LeanbackSettingsFragment implements DialogPreference.TargetFragment { - public static final String TAG = "SettingsExampleFragment"; private final Stack fragments = new Stack(); @Override @@ -50,12 +49,6 @@ public class SettingsExampleFragment extends LeanbackSettingsFragment implements public boolean onPreferenceStartScreen(PreferenceFragment preferenceFragment, PreferenceScreen preferenceScreen) { PreferenceFragment frag = buildPreferenceFragment(R.xml.prefs, preferenceScreen.getKey()); - if ("prefs_wifi_screen_key".equals(preferenceScreen.getKey())) { - ListPreference pref = (ListPreference)preferenceScreen.findPreference("prefs_wifi_key"); - pref.setEntries(new String[] {"Wi-Fi Network 01"}); - pref.setEntryValues(new String[] {"01"}); - if (Constants.LOCAL_LOGD) Log.d(TAG, "pref: " + pref); - } startPreferenceFragment(frag); return true; } @@ -87,6 +80,18 @@ public class SettingsExampleFragment extends LeanbackSettingsFragment implements } } + @Override + public boolean onPreferenceTreeClick(Preference preference) { + final String[] keys = {"prefs_wifi_connect_wps", "prefs_date", "prefs_time", + "prefs_date_time_use_timezone", "app_banner_sample_app", "pref_force_stop", + "pref_uninstall", "pref_more_info"}; + if (Arrays.asList(keys).contains(preference.getKey())) { + Toast.makeText(getActivity(), "Implement your own action handler.", Toast.LENGTH_SHORT).show(); + return true; + } + return super.onPreferenceTreeClick(preference); + } + @Override public void onAttach(Context context) { fragments.push(this); diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_food.jpg b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_food.jpg new file mode 100644 index 000000000..cbe05f83b Binary files /dev/null and b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_food.jpg differ diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml new file mode 100644 index 000000000..cbcfe0539 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml index 1dd92d8c9..cb7d66954 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml @@ -16,6 +16,7 @@ --> + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml index 9d2eda6c7..e3c6889e2 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml @@ -21,5 +21,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:deviceIds="tv" + android:background="@drawable/bg_living_room_wide" tools:ignore="MergeRootFrame"> diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_music_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_music_example.xml new file mode 100644 index 000000000..30f150161 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_music_example.xml @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_video_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_video_example.xml new file mode 100644 index 000000000..89e4e6e51 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_video_example.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml index f4877e823..9933ba7e1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml @@ -33,4 +33,12 @@ This description becomes visible only on focus. This description becomes visible only on focus. + + Wi-Fi network 1 + Wi-Fi network 2 + Wi-Fi network 3 + Wi-Fi network 4 + Wi-Fi network 5 + Wi-Fi network 6 + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml index 490f442d1..6739eafd7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml @@ -42,6 +42,10 @@ invisible + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml index 8d5551592..086ae2341 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml @@ -23,11 +23,15 @@ true true true - @color/search_color + #00A2B8 @color/accent @style/PreferenceThemeOverlay.v14 + + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml b/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml index 71cd5320d..e69c4e2d5 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml @@ -1,5 +1,6 @@ - + + - - - - + - - - - + + + + + + + + -- cgit v1.2.3 From 742e2682a9c4b6c1d83b71623c453461328bf085 Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Thu, 6 Aug 2015 14:59:35 -0700 Subject: WIP: Added transitions to MainFragment. In order to show how to use transitions, they have been added to the MainFragment. Thus the transitions are used when an example gets opened. Change-Id: I9703c7832a2d2ef2a09ddb91e1676dfc1ac4f24a --- .../supportleanbackshowcase/app/MainFragment.java | 34 ++++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java index 643259def..1288a3797 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java @@ -32,6 +32,7 @@ import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; import android.support.v17.leanback.supportleanbackshowcase.models.Movie; import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ImageCardView; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; import android.support.v17.leanback.widget.OnItemViewClickedListener; @@ -40,6 +41,7 @@ import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.PresenterSelector; import android.support.v17.leanback.widget.Row; import android.support.v17.leanback.widget.RowPresenter; +import android.support.v4.app.ActivityOptionsCompat; import com.google.gson.Gson; @@ -99,44 +101,40 @@ public class MainFragment extends BrowseFragment { @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { + Intent intent = null; Card card = (Card) item; int id = card.getId(); switch (id) { case 0: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), CardExampleActivity.class); - startActivity(intent); break; } case 2: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), GridExampleActivity.class); - startActivity(intent); break; } case 3: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), DetailViewExampleActivity.class); - startActivity(intent); break; } case 4: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), VideoExampleActivity.class); - startActivity(intent); break; } case 5: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), MusicExampleActivity.class); - startActivity(intent); break; } case 6: { // Let's create a new Wizard for a given Movie. The movie can come from any sort // of data source. To simplify this example we decode it from a JSON source // which might be loaded from a server in a real world example. - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), WizardExampleActivity.class); // Prepare extras which contains the Movie and will be passed to the Activity @@ -149,24 +147,28 @@ public class MainFragment extends BrowseFragment { intent.putExtras(extras); // Finally, start the wizard Activity. - startActivity(intent); break; } case 7: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), SettingsExampleActivity.class); startActivity(intent); - break; + return; } case 8: { - Intent intent = new Intent(getActivity().getBaseContext(), + intent = new Intent(getActivity().getBaseContext(), DialogExampleActivity.class); - startActivity(intent); break; } default: break; } + if (intent != null) { + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), + ((ImageCardView) itemViewHolder.view).getMainImageView(), "transition") + .toBundle(); + startActivity(intent, bundle); + } } } -- cgit v1.2.3 From e6b72719a85a4731673d1d56f7b4f7463f18e249 Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Tue, 18 Aug 2015 11:46:53 -0700 Subject: Added Transitions and minor code clean up Added support for the DetailView Activity transition. The DetailView can now be started from the launcher or the Cards example. Added support for Browse entrance transition. Minor code clean up such as renaming GridExample fragment to GridExampleFragment and removing unused methods. Change-Id: Ib1c11af82be5b858960e243acd7f11ce8dbd06f7 --- .../app/src/main/AndroidManifest.xml | 4 +- .../supportleanbackshowcase/app/MainFragment.java | 3 +- .../app/cards/CardExampleFragment.java | 55 ++++++++++++++++++--- .../app/details/DetailViewExampleFragment.java | 29 ++++++++++- .../app/grid/GridExample.java | 57 ---------------------- .../app/grid/GridExampleFragment.java | 57 ++++++++++++++++++++++ .../app/wizard/WizardExample1stStepFragment.java | 2 + .../app/wizard/WizardExample2ndStepFragment.java | 3 ++ .../app/wizard/WizardExample4thStepFragment.java | 2 + .../cards/CharacterCardView.java | 1 + .../supportleanbackshowcase/utils/Utils.java | 37 -------------- .../src/main/res/layout/activity_cards_example.xml | 1 + .../main/res/layout/activity_detail_example.xml | 1 + .../src/main/res/layout/activity_grid_example.xml | 2 +- .../app/src/main/res/layout/character_card.xml | 1 + .../app/src/main/res/values/styles.xml | 2 +- .../app/src/main/res/values/themes.xml | 5 +- 17 files changed, 151 insertions(+), 111 deletions(-) delete mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java create mode 100644 samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index df351806c..756ef94e7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -41,10 +41,10 @@ android:theme="@style/Theme.Example.LeanbackDialog"> + android:theme="@style/Theme.Example.LeanbackDetails"> + android:theme="@style/Theme.Example.LeanbackBrowse"> diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java index 1288a3797..ab22928d8 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java @@ -164,8 +164,7 @@ public class MainFragment extends BrowseFragment { break; } if (intent != null) { - Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), - ((ImageCardView) itemViewHolder.view).getMainImageView(), "transition") + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity()) .toBundle(); startActivity(intent, bundle); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java index a7b3f9771..4b2a44557 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java @@ -14,21 +14,32 @@ package android.support.v17.leanback.supportleanbackshowcase.app.cards; +import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleFragment; import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ImageCardView; import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; import android.support.v17.leanback.widget.SearchOrbView; +import android.support.v4.app.ActivityOptionsCompat; import android.view.View; +import android.widget.ImageView; import android.widget.Toast; import com.google.gson.Gson; @@ -52,22 +63,50 @@ public class CardExampleFragment extends BrowseFragment { setHeadersTransitionOnBackEnabled(true); setSearchAffordanceColors( new SearchOrbView.Colors(getResources().getColor(R.color.search_color), - getResources().getColor(R.color.search_bright_color), - getResources().getColor(R.color.search_icon_color))); + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); setBrandColor(getResources().getColor(R.color.fastlane_background)); setTitle(getString(R.string.card_examples_title)); setOnSearchClickedListener(new View.OnClickListener() { - @Override public void onClick(View v) { + @Override + public void onClick(View v) { Toast.makeText(getActivity(), getString(R.string.implement_search), - Toast.LENGTH_LONG).show(); + Toast.LENGTH_LONG).show(); } }); + setOnItemViewClickedListener(new OnItemViewClickedListener() { + + @Override + public void onItemClicked(Presenter.ViewHolder viewHolder, Object item, RowPresenter.ViewHolder viewHolder1, Row row) { + if (!(item instanceof Card)) return; + if (!(viewHolder.view instanceof ImageCardView)) return; + + ImageView imageView = ((ImageCardView) viewHolder.view).getMainImageView(); + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), + imageView, DetailViewExampleFragment.TRANSITION_NAME).toBundle(); + Intent intent = new Intent(getActivity().getBaseContext(), + DetailViewExampleActivity.class); + Card card = (Card) item; + int imageResId = card.getLocalImageResourceId(getContext()); + intent.putExtra(DetailViewExampleFragment.EXTRA_CARD, imageResId); + startActivity(intent, bundle); + } + + }); + + prepareEntranceTransition(); } private void setupRowAdapter() { mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); - createRows(); setAdapter(mRowsAdapter); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + createRows(); + startEntranceTransition(); + } + }, 500); } private void createRows() { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java index 7f9e77a30..eed800ffd 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java @@ -14,7 +14,10 @@ package android.support.v17.leanback.supportleanbackshowcase.app.details; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.os.Bundle; +import android.os.Handler; import android.support.v17.leanback.app.DetailsFragment; import android.support.v17.leanback.supportleanbackshowcase.models.DetailedCard; import android.support.v17.leanback.supportleanbackshowcase.R; @@ -27,6 +30,7 @@ import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.ClassPresenterSelector; import android.support.v17.leanback.widget.DetailsOverviewRow; import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter; +import android.support.v17.leanback.widget.FullWidthDetailsOverviewSharedElementHelper; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; @@ -47,11 +51,14 @@ import com.google.gson.Gson; public class DetailViewExampleFragment extends DetailsFragment implements OnItemViewClickedListener, OnItemViewSelectedListener { + public static final String TRANSITION_NAME = "t_for_transition"; + public static final String EXTRA_CARD = "card"; + private ArrayObjectAdapter mRowsAdapter; @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); setupUi(); setupEventListeners(); } @@ -85,6 +92,13 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem return viewHolder; } }; + + FullWidthDetailsOverviewSharedElementHelper mHelper = new FullWidthDetailsOverviewSharedElementHelper(); + mHelper.setSharedElementEnterTransition(getActivity(), TRANSITION_NAME); + rowPresenter.setListener(mHelper); + rowPresenter.setParticipatingEntranceTransition(false); + prepareEntranceTransition(); + ListRowPresenter shadowDisabledRowPresenter = new ListRowPresenter(); shadowDisabledRowPresenter.setShadowEnabled(false); @@ -98,6 +112,11 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem // Setup action and detail row. DetailsOverviewRow detailsOverview = new DetailsOverviewRow(data); int imageResId = data.getLocalImageResourceId(getActivity()); + + Bundle extras = getActivity().getIntent().getExtras(); + if (extras != null && extras.containsKey(EXTRA_CARD)) { + imageResId = extras.getInt(EXTRA_CARD, imageResId); + } detailsOverview.setImageDrawable(getResources().getDrawable(imageResId, null)); ArrayObjectAdapter actionAdapter = new ArrayObjectAdapter(); actionAdapter.add(new Action(1, getString(R.string.action_buy) + data.getPrice())); @@ -120,6 +139,12 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem mRowsAdapter.add(new ListRow(header, listRowAdapter)); setAdapter(mRowsAdapter); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + startEntranceTransition(); + } + }, 500); } private void setupEventListeners() { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java deleted file mode 100644 index e8cf3eba3..000000000 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package android.support.v17.leanback.supportleanbackshowcase.app.grid; - -import android.os.Bundle; -import android.support.v17.leanback.app.VerticalGridFragment; -import android.support.v17.leanback.supportleanbackshowcase.R; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; -import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.FocusHighlight; -import android.support.v17.leanback.widget.PresenterSelector; -import android.support.v17.leanback.widget.VerticalGridPresenter; - -import com.google.gson.Gson; - -/** - * An example how to use leanback's {@link VerticalGridFragment}. - */ -public class GridExample extends VerticalGridFragment { - - private static final int COLUMNS = 4; - private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_MEDIUM; - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTitle(getString(R.string.grid_example_title)); - setupRowAdapter(); - } - - private void setupRowAdapter() { - VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); - gridPresenter.setNumberOfColumns(COLUMNS); - setGridPresenter(gridPresenter); - - PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); - String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); - CardRow row = new Gson().fromJson(json, CardRow.class); - adapter.addAll(0, row.getCards()); - setAdapter(adapter); - } - -} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java new file mode 100644 index 000000000..8002bf2c5 --- /dev/null +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.support.v17.leanback.supportleanbackshowcase.app.grid; + +import android.os.Bundle; +import android.support.v17.leanback.app.VerticalGridFragment; +import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.FocusHighlight; +import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.VerticalGridPresenter; + +import com.google.gson.Gson; + +/** + * An example how to use leanback's {@link VerticalGridFragment}. + */ +public class GridExampleFragment extends VerticalGridFragment { + + private static final int COLUMNS = 4; + private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_MEDIUM; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(getString(R.string.grid_example_title)); + setupRowAdapter(); + } + + private void setupRowAdapter() { + VerticalGridPresenter gridPresenter = new VerticalGridPresenter(ZOOM_FACTOR); + gridPresenter.setNumberOfColumns(COLUMNS); + setGridPresenter(gridPresenter); + + PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); + ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); + String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); + CardRow row = new Gson().fromJson(json, CardRow.class); + adapter.addAll(0, row.getCards()); + setAdapter(adapter); + } + +} diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java index 0b0f6929c..e7808b113 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java @@ -52,6 +52,7 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment GuidedAction action = new GuidedAction.Builder() .id(ACTION_ID_BUY_HD) .title(getString(R.string.wizard_example_rent_hd)) + .editable(false) .description(mMovie.getPriceHd() + " " + getString(R.string.wizard_example_watch_hd)) .build(); @@ -59,6 +60,7 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment action = new GuidedAction.Builder() .id(ACTION_ID_BUY_SD) .title(getString(R.string.wizard_example_rent_sd)) + .editable(false) .description(mMovie.getPriceSd() + " " + getString(R.string.wizard_example_watch_sd)) .build(); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java index 7f3a83a39..8bbf5a455 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java @@ -58,6 +58,7 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment getString(R.string.wizard_example_rental_period), mMovie.getBreadcrump(), null); return guidance; + } @Override @@ -68,12 +69,14 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment .id(ACTION_ID_CONFIRM) .title(getString(R.string.wizard_example_rent)) .description(rentHighDefinition ? mMovie.getPriceHd() : mMovie.getPriceSd()) + .editable(false) .build(); actions.add(action); action = new GuidedAction.Builder() .id(ACTION_ID_PAYMENT_METHOD) .title(getString(R.string.wizard_example_payment_method)) .description(getString(R.string.wizard_example_visa_balance)) + .editable(false) .build(); actions.add(action); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java index 450311c24..5601fdac7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java @@ -52,11 +52,13 @@ public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { GuidedAction action = new GuidedAction.Builder() .id(ACTION_ID_WATCH) + .editable(false) .title(getString(R.string.wizard_example_watch_now)) .build(); actions.add(action); action = new GuidedAction.Builder() .id(ACTION_ID_LATER) + .editable(false) .title(getString(R.string.wizard_example_later)) .build(); actions.add(action); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java index eeda4dae8..0486a4259 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java @@ -47,6 +47,7 @@ public class CharacterCardView extends BaseCardView { } }); setFocusable(true); + setBackground(null); } public void updateUi(Card card) { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java index 257aedbd0..4416cbe49 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java @@ -16,16 +16,10 @@ package android.support.v17.leanback.supportleanbackshowcase.utils; import android.content.ContentResolver; import android.content.Context; -import android.graphics.drawable.Drawable; import android.net.Uri; -import android.widget.ImageView; - -import com.squareup.picasso.Picasso; -import com.squareup.picasso.RequestCreator; import java.io.IOException; import java.io.InputStream; -import java.net.URI; /** * A collection of utility methods, all static. @@ -55,37 +49,6 @@ public class Utils { } } - /** - * The method uses {@link Picasso} to fetch an image from a given url, resize it (if required) - * and display it inside an {@link ImageView}. - * - * @param context Context which is used to create a {@link Picasso} instance. - * @param uri The {@link URI} to fetch the image from. - * @param target The {@link ImageView} which shall display the image. - * @param resizeWidthInDp The target width of the image. Pass -1 if you don't want - * to resize the image. - * @param resizeHeightInDp The target height of the image. Pass -1 if you don't - * want to resize the image. - * @param centerCrop Centers and scales an image to fit the requested bounds. - * @param errorDrawable A drawable which will be shown in case the image could not be fetched - * from the server. - * @see {@link Picasso#with(Context)} - * @see {@link RequestCreator#resize(int, int)} - * @see {@link RequestCreator#centerCrop()} - * @see {@link RequestCreator#error(Drawable)} - */ - public static void loadImageFromUri(Context context, URI uri, ImageView target, - int resizeWidthInDp, int resizeHeightInDp, - boolean centerCrop, Drawable errorDrawable) { - if (uri == null) return; - RequestCreator builder = Picasso.with(context).load(uri.toString()); - if (resizeHeightInDp != -1 && resizeWidthInDp != -1) - builder.resize(Utils.convertDpToPixel(context, resizeWidthInDp), - Utils.convertDpToPixel(context, resizeHeightInDp)); - if (centerCrop) builder.centerCrop(); - builder.error(errorDrawable).into(target); - } - public static Uri getResourceUri(Context context, int resID) { return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getResources().getResourcePackageName(resID) + '/' + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml index cbcfe0539..903c52fd3 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml @@ -17,6 +17,7 @@ \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml index 13f85845f..dee09a8e6 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml @@ -18,6 +18,7 @@ xmlns:lb="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + lb:cardBackground="@null" lb:layout_viewType="main"> + + @@ -48,7 +51,7 @@ @color/settings_background - -- cgit v1.2.3 From 5bf3eba9ddbd3e418c7c2a2a54f09aede1996afa Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Thu, 1 Oct 2015 12:57:28 -0700 Subject: Showcase: Update SDK to 23 and support lib to 23.0.1 Updated for new API addAsRoot() for GuidedStepFragment. Rmove the awkward setStep() call, we can find current GuidedStepFragment using standard API. Change-Id: I7ecb108a36ab5d0091c230dd5c5686e3a91f1857 --- samples/SupportLeanbackShowcase/app/build.gradle | 20 +++++++-------- .../app/dialog/DialogExampleActivity.java | 2 +- .../app/wizard/WizardExample1stStepFragment.java | 6 ----- .../app/wizard/WizardExample2ndStepFragment.java | 6 ----- .../app/wizard/WizardExample3rdStepFragment.java | 6 ----- .../app/wizard/WizardExample4thStepFragment.java | 6 ----- .../app/wizard/WizardExampleActivity.java | 29 +++------------------- 7 files changed, 14 insertions(+), 61 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/build.gradle b/samples/SupportLeanbackShowcase/app/build.gradle index d632d8f12..d593ef556 100644 --- a/samples/SupportLeanbackShowcase/app/build.gradle +++ b/samples/SupportLeanbackShowcase/app/build.gradle @@ -2,13 +2,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 'android-MNC' - buildToolsVersion "22.0.1" + compileSdkVersion 'android-23' + buildToolsVersion "23.0.1" defaultConfig { applicationId "android.support.v17.leanback.supportleanbackshowcase" minSdkVersion 17 - targetSdkVersion 'MNC' + targetSdkVersion '23' versionCode 1 versionName "1.0" } @@ -22,15 +22,15 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:recyclerview-v7:23.0.0-rc1' - compile 'com.android.support:leanback-v17:23.0.0-rc1' - compile 'com.android.support:appcompat-v7:23.0.0-rc1' + compile 'com.android.support:recyclerview-v7:23.0.1' + compile 'com.android.support:leanback-v17:23.0.1' + compile 'com.android.support:appcompat-v7:23.0.1' - compile 'com.android.support:preference-v7:23.0.0-rc1' - compile 'com.android.support:preference-leanback-v17:23.0.0-rc1' - compile 'com.android.support:preference-v14:23.0.0-rc1' + compile 'com.android.support:preference-v7:23.0.1' + compile 'com.android.support:preference-leanback-v17:23.0.1' + compile 'com.android.support:preference-v14:23.0.1' compile 'com.google.code.gson:gson:1.7.2' compile 'com.squareup.picasso:picasso:2.3.2' - compile 'com.android.support:palette-v7:23.0.0-rc1' + compile 'com.android.support:palette-v7:23.0.1' } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java index 763a18e37..55f75759a 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java @@ -30,6 +30,6 @@ public class DialogExampleActivity extends Activity { getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#21272A"))); GuidedStepFragment fragment = new DialogExampleFragment(); - GuidedStepFragment.add(getFragmentManager(), fragment); + GuidedStepFragment.addAsRoot(this, fragment, android.R.id.content); } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java index e7808b113..b40cc8257 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java @@ -32,12 +32,6 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment private static final int ACTION_ID_BUY_HD = 1; private static final int ACTION_ID_BUY_SD = ACTION_ID_BUY_HD + 1; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(1); - } - @NonNull @Override public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java index 8bbf5a455..3b369ace1 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java @@ -45,12 +45,6 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment return fragment; } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(2); - } - @NonNull @Override public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java index 0cc422150..37f662f0a 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java @@ -35,12 +35,6 @@ public class WizardExample3rdStepFragment extends WizardExampleBaseStepFragment private static final int ACTION_ID_PROCESSING = 1; private final Handler mFakeHttpHandler = new Handler(); - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(3); - } - @Override public void onStart() { super.onStart(); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java index 5601fdac7..be5e6459a 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java @@ -33,12 +33,6 @@ public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment private static final int ACTION_ID_WATCH = 1; private static final int ACTION_ID_LATER = ACTION_ID_WATCH + 1; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWizardActivity().setStep(4); - } - @NonNull @Override public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java index bde1a06fd..f5d293708 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java @@ -25,46 +25,23 @@ import android.support.v17.leanback.supportleanbackshowcase.R; */ public class WizardExampleActivity extends Activity { - // When the user 'bought' the product and presses back, we don't want to show the 'Processing..' - // screen again, instead we want to go back to the very first step or close the wizard. Thus, we - // have to save the current step of the wizard and make it accessible to it's children. - private int mStep = 0; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setBackgroundDrawableResource(R.drawable.wizard_background_blackned); - // Recover old step state. - if (savedInstanceState != null) { - mStep = savedInstanceState.getInt("step"); - } - GuidedStepFragment fragment = new WizardExample1stStepFragment(); fragment.setArguments(getIntent().getExtras()); // Delegate Movie to first step. - GuidedStepFragment.add(getFragmentManager(), fragment); - } - - public int getStep() { - return mStep; - } - - public void setStep(int step) { - mStep = step; + GuidedStepFragment.addAsRoot(this, fragment, android.R.id.content); } @Override public void onBackPressed() { - if (4 == getStep()) { + if (GuidedStepFragment.getCurrentGuidedStepFragment(getFragmentManager()) + instanceof WizardExample4thStepFragment) { // The user 'bought' the product. When he presses 'Back' the Wizard will be closed and // he will not be send back to 'Processing Payment...'-Screen. finish(); } else super.onBackPressed(); } - @Override - public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { - // Save current step persitently. - outPersistentState.putInt("step", mStep); - super.onSaveInstanceState(outState, outPersistentState); - } } -- cgit v1.2.3 From ab2a8a7dae6fae5bc97240c47a68d6a7b93221b1 Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Thu, 1 Oct 2015 14:32:05 -0700 Subject: Supportleanbackshowcase: Polishing Support staggered slide in/out transition for VerticalGrid. Move background from layout file to windowBackground in theme. Defining background on view conflicts with transitions. Change-Id: If823f492fd5bdd0b16c1d1e735f4214f925f3ae3 --- .../app/src/main/AndroidManifest.xml | 2 +- .../app/grid/GridExampleFragment.java | 25 +++++++++++++++++----- .../src/main/res/layout/activity_grid_example.xml | 1 - .../app/src/main/res/layout/activity_main.xml | 1 - .../app/src/main/res/values/themes.xml | 12 +++++------ 5 files changed, 26 insertions(+), 15 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index 756ef94e7..cc84e9cc7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -47,7 +47,7 @@ android:theme="@style/Theme.Example.LeanbackBrowse"> + android:theme="@style/Theme.Example.LeanbackVerticalGrid"> diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java index 8002bf2c5..6640b5180 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java @@ -15,6 +15,7 @@ package android.support.v17.leanback.supportleanbackshowcase.app.grid; import android.os.Bundle; +import android.os.Handler; import android.support.v17.leanback.app.VerticalGridFragment; import android.support.v17.leanback.supportleanbackshowcase.R; import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; @@ -35,6 +36,8 @@ public class GridExampleFragment extends VerticalGridFragment { private static final int COLUMNS = 4; private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_MEDIUM; + private ArrayObjectAdapter mAdapter; + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle(getString(R.string.grid_example_title)); @@ -47,11 +50,23 @@ public class GridExampleFragment extends VerticalGridFragment { setGridPresenter(gridPresenter); PresenterSelector cardPresenterSelector = new CardPresenterSelector(getActivity()); - ArrayObjectAdapter adapter = new ArrayObjectAdapter(cardPresenterSelector); - String json = Utils.inputStreamToString(getResources().openRawResource(R.raw.grid_example)); - CardRow row = new Gson().fromJson(json, CardRow.class); - adapter.addAll(0, row.getCards()); - setAdapter(adapter); + mAdapter = new ArrayObjectAdapter(cardPresenterSelector); + setAdapter(mAdapter); + + prepareEntranceTransition(); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + createRows(); + startEntranceTransition(); + } + }, 1000); } + private void createRows() { + String json = Utils.inputStreamToString(getResources() + .openRawResource(R.raw.grid_example)); + CardRow row = new Gson().fromJson(json, CardRow.class); + mAdapter.addAll(0, row.getCards()); + } } diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml index c8b0a3790..f3fcdeaac 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml @@ -16,7 +16,6 @@ --> diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml index 12343de7d..2f6822b69 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml @@ -16,25 +16,23 @@ + + -- cgit v1.2.3 From 6fe262dae987f9c11cbf5f839a31f10936e40495 Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Thu, 1 Oct 2015 14:54:19 -0700 Subject: Supportleanbackshowcase: Polishing 2 and transition performance fix Move background of browse/details/music from layout to windowBackground. Setting background on view will cause the whole RelativeLayout being faded in while transition move content inside the RelativeLayout. The RelativeLayout does not have a hardwarelayer, nor does it specify hasOverlappingRendering=false. This falls to the slowest rendering path. Change-Id: I78bacc965e641d7f960aae5cf212c29f6b1f0f11 --- samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml | 2 +- .../app/src/main/res/layout/activity_cards_example.xml | 2 -- .../app/src/main/res/layout/activity_detail_example.xml | 2 -- .../app/src/main/res/layout/activity_music_example.xml | 1 - .../SupportLeanbackShowcase/app/src/main/res/values/themes.xml | 9 ++++++++- 5 files changed, 9 insertions(+), 7 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index cc84e9cc7..087bbd3ab 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -53,7 +53,7 @@ android:theme="@style/Theme.Example.Leanback"> + android:theme="@style/Theme.Example.LeanbackMusic"> diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml index 903c52fd3..45b550567 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml @@ -16,8 +16,6 @@ --> + @drawable/background_canyon + + + + -- cgit v1.2.3 From c8ad1e5263382c7d048349c1d63fd888f3926477 Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Mon, 5 Oct 2015 13:44:29 -0700 Subject: Leanback Demo: demo of edit title Bug 24673827 Change-Id: I1e4d9378cc862d748055387a71129692bd4cf53b --- .../app/wizard/WizardExample2ndStepFragment.java | 25 ++++++++++++++++------ .../app/src/main/res/values/strings.xml | 6 ++++-- 2 files changed, 22 insertions(+), 9 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java index 3b369ace1..c1df8a131 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java @@ -17,6 +17,7 @@ package android.support.v17.leanback.supportleanbackshowcase.app.wizard; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.text.TextUtils; import android.support.annotation.NonNull; import android.support.v17.leanback.app.GuidedStepFragment; import android.support.v17.leanback.supportleanbackshowcase.R; @@ -69,19 +70,29 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment action = new GuidedAction.Builder() .id(ACTION_ID_PAYMENT_METHOD) .title(getString(R.string.wizard_example_payment_method)) - .description(getString(R.string.wizard_example_visa_balance)) - .editable(false) + .editTitle("") + .description(getString(R.string.wizard_example_input_credit)) + .editable(true) .build(); actions.add(action); } @Override - public void onGuidedActionClicked(GuidedAction action) { - if (ACTION_ID_PAYMENT_METHOD == action.getId()) { - Toast.makeText(getActivity(), - getString(R.string.wizard_example_toast_payment_method_clicked), - Toast.LENGTH_SHORT).show(); + public void onGuidedActionEdited(GuidedAction action) { + CharSequence editTitle = action.getEditTitle(); + if (TextUtils.isDigitsOnly(editTitle) && editTitle.length() == 16) { + action.setDescription(getString(R.string.wizard_example_visa, + editTitle.subSequence(editTitle.length() - 4, editTitle.length()))); + } else if (editTitle.length() == 0) { + action.setDescription(getString(R.string.wizard_example_input_credit)); } else { + action.setDescription(getString(R.string.wizard_example_input_credit_wrong)); + } + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (ACTION_ID_CONFIRM == action.getId()) { GuidedStepFragment fragment = new WizardExample3rdStepFragment(); fragment.setArguments(getArguments()); add(getFragmentManager(), fragment); diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml index 9a46e5496..a25b964c8 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml @@ -51,6 +51,8 @@ Watch now Later \'Watch now\' clicked. - Visa - 1234 Balance $60.00 - Just a second... + Input credit card number + Visa XXXX-XXXX-XXXX-%s + Error credit card number + sJust a second... \ No newline at end of file -- cgit v1.2.3 From 7d120188cade375a43257bf552c33c9cb50d0c5a Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Mon, 5 Oct 2015 18:15:17 -0700 Subject: SupportLeanbackShowcase: dont expand side info Transition animation isn't right. Browse fragment hasn't implemented the pre-layout for row children horizontal layout change. Change-Id: Ib4f55651c3f568ad9224c474036663f35935c4e3 --- .../cards/presenters/SideInfoCardPresenter.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java index dcd7b80e1..914adb0f7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java @@ -39,18 +39,10 @@ public class SideInfoCardPresenter extends AbstractCardPresenter { @Override protected BaseCardView onCreateView() { - final BaseCardView cardView = new BaseCardView(getContext()) { - - @Override - public void setActivated(boolean activated) { - super.setActivated(activated); - onActivateStateChanged(this, activated); - } - }; + final BaseCardView cardView = new BaseCardView(getContext()); cardView.setFocusable(true); cardView.setCardType(BaseCardView.CARD_TYPE_MAIN_ONLY); cardView.addView(LayoutInflater.from(getContext()).inflate(R.layout.side_info_card, null)); - onActivateStateChanged(cardView, cardView.isActivated()); return cardView; } @@ -79,7 +71,4 @@ public class SideInfoCardPresenter extends AbstractCardPresenter { extraText.setText(card.getExtraText()); } - public void onActivateStateChanged(final BaseCardView cardView, boolean activated) { - cardView.findViewById(R.id.info).setVisibility(activated ? View.VISIBLE : View.GONE); - } } -- cgit v1.2.3 From 0750ff8d6b237fb471e126bebab7d858a57cf195 Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Tue, 6 Oct 2015 13:46:42 -0700 Subject: SupportLeanbackShowcase: performance fix of ImageCardView resource Use Picasso to load Image in background thread instead of decoding Bitmap in UI thread. Change-Id: Ib798d167108f8445b3898cab72dc7dfabfe13c8a --- .../cards/presenters/ImageCardViewPresenter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java index 09a9b672f..813c1e78d 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java @@ -18,6 +18,7 @@ import android.content.Context; import android.support.v17.leanback.supportleanbackshowcase.R; import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.widget.ImageCardView; +import com.squareup.picasso.Picasso; /** * A very basic {@link ImageCardView} {@link android.support.v17.leanback.widget.Presenter}.You can @@ -52,7 +53,7 @@ public class ImageCardViewPresenter extends AbstractCardPresenter int resourceId = getContext().getResources() .getIdentifier(card.getLocalImageResourceName(), "drawable", getContext().getPackageName()); - cardView.getMainImageView().setImageResource(resourceId); + Picasso.with(getContext()).load(resourceId).into(cardView.getMainImageView()); } } -- cgit v1.2.3 From 2157e7f4ece543b3aca6a9befece9a21bbfcac09 Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Thu, 8 Oct 2015 11:42:49 -0700 Subject: SupportLeanbackShowcase: get rid of card view background overdraw Change-Id: I3a46d34df265eda2cf38bfca80d3786aa5a8a23b --- .../cards/CharacterCardView.java | 3 +- .../cards/TextCardView.java | 2 +- .../cards/presenters/SideInfoCardPresenter.java | 4 +- .../app/src/main/res/layout/side_info_card.xml | 88 +++++++++++----------- .../app/src/main/res/values/styles.xml | 21 +++++- 5 files changed, 66 insertions(+), 52 deletions(-) (limited to 'samples/SupportLeanbackShowcase/app') diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java index 0486a4259..962adb007 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java @@ -30,7 +30,7 @@ import android.widget.TextView; public class CharacterCardView extends BaseCardView { public CharacterCardView(Context context) { - super(context); + super(context, null, R.style.CharacterCardStyle); LayoutInflater.from(getContext()).inflate(R.layout.character_card, this); setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override @@ -47,7 +47,6 @@ public class CharacterCardView extends BaseCardView { } }); setFocusable(true); - setBackground(null); } public void updateUi(Card card) { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java index ed1dd4a80..830b47441 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java @@ -29,7 +29,7 @@ import android.widget.TextView; public class TextCardView extends BaseCardView { public TextCardView(Context context) { - super(context); + super(context, null, R.style.TextCardStyle); LayoutInflater.from(getContext()).inflate(R.layout.text_icon_card, this); setFocusable(true); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java index 914adb0f7..b9f44fc43 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java @@ -39,9 +39,9 @@ public class SideInfoCardPresenter extends AbstractCardPresenter { @Override protected BaseCardView onCreateView() { - final BaseCardView cardView = new BaseCardView(getContext()); + final BaseCardView cardView = new BaseCardView(getContext(), null, + R.style.SideInfoCardStyle); cardView.setFocusable(true); - cardView.setCardType(BaseCardView.CARD_TYPE_MAIN_ONLY); cardView.addView(LayoutInflater.from(getContext()).inflate(R.layout.side_info_card, null)); return cardView; } diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml index c9ec7cab1..725af09fb 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml @@ -14,55 +14,51 @@ See the License for the specific language governing permissions and limitations under the License. --> - + - - - + - + - + - + - - + - \ No newline at end of file + \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml index 752439db7..c9b047676 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml @@ -54,6 +54,7 @@ + + + + + + + + + @@ -85,6 +103,7 @@ @@ -94,6 +113,7 @@ @@ -155,7 +175,6 @@