summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-03-10 18:13:45 -0800
committerSteve Kondik <steve@cyngn.com>2016-03-10 18:13:45 -0800
commit0a521f6d93206567c14bbacdc13819bf4baf82d3 (patch)
tree2e11b47c9856368387b394b6831726f2526bf6dd
parent171957c0bdc547ae6013daddffc03c8ec3ac2e3e (diff)
parentadce814038b96c87ea66fc1e5bfd85ab28d80590 (diff)
downloadandroid_development-staging/cm-13.0+r22.tar.gz
android_development-staging/cm-13.0+r22.tar.bz2
android_development-staging/cm-13.0+r22.zip
Merge tag 'android-6.0.1_r22' of https://android.googlesource.com/platform/development into cm-13.0staging/cm-13.0+r22stable/cm-13.0-ZNH2KBstable/cm-13.0-ZNH2K
Android 6.0.1 release 22
-rw-r--r--apps/Development/Android.mk2
-rw-r--r--build/Android.mk4
-rw-r--r--build/sdk.atree16
-rw-r--r--samples/Support4Demos/AndroidManifest.xml12
-rw-r--r--samples/Support4Demos/res/color/tint_state_list.xml20
-rw-r--r--samples/Support4Demos/res/drawable-hdpi/ic_favorite.pngbin0 -> 875 bytes
-rw-r--r--samples/Support4Demos/res/drawable-mdpi/ic_favorite.pngbin0 -> 551 bytes
-rw-r--r--samples/Support4Demos/res/drawable-xhdpi/ic_favorite.pngbin0 -> 1162 bytes
-rw-r--r--samples/Support4Demos/res/drawable-xxhdpi/ic_favorite.pngbin0 -> 1779 bytes
-rw-r--r--samples/Support4Demos/res/drawable-xxxhdpi/ic_favorite.pngbin0 -> 2295 bytes
-rw-r--r--samples/Support4Demos/res/layout/drawable_compat.xml51
-rw-r--r--samples/Support4Demos/res/layout/drawer_layout.xml51
-rw-r--r--samples/Support4Demos/res/layout/view_pager_layout.xml30
-rw-r--r--samples/Support4Demos/res/values/strings.xml16
-rw-r--r--samples/Support4Demos/src/com/example/android/supportv4/graphics/DrawableCompatActivity.java84
-rw-r--r--samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java110
-rw-r--r--samples/Support7Demos/AndroidManifest.xml29
-rw-r--r--samples/Support7Demos/res/drawable-hdpi/drawer_shadow.9.png (renamed from samples/Support4Demos/res/drawable-hdpi/drawer_shadow.9.png)bin171 -> 171 bytes
-rwxr-xr-xsamples/Support7Demos/res/drawable-hdpi/ic_android.pngbin0 -> 358 bytes
-rw-r--r--samples/Support7Demos/res/drawable-mdpi/drawer_shadow.9.png (renamed from samples/Support4Demos/res/drawable-mdpi/drawer_shadow.9.png)bin158 -> 158 bytes
-rwxr-xr-xsamples/Support7Demos/res/drawable-mdpi/ic_android.pngbin0 -> 226 bytes
-rw-r--r--samples/Support7Demos/res/drawable-xhdpi/drawer_shadow.9.png (renamed from samples/Support4Demos/res/drawable-xhdpi/drawer_shadow.9.png)bin182 -> 182 bytes
-rw-r--r--samples/Support7Demos/res/layout/action_bar_drawer_layout.xml50
-rw-r--r--samples/Support7Demos/res/layout/animated_recycler_view.xml4
-rw-r--r--samples/Support7Demos/res/layout/drawer_layout.xml75
-rw-r--r--samples/Support7Demos/res/layout/sample_media_router.xml6
-rw-r--r--samples/Support7Demos/res/layout/selectable_item.xml20
-rw-r--r--samples/Support7Demos/res/values/colors.xml2
-rw-r--r--samples/Support7Demos/res/values/strings.xml31
-rw-r--r--samples/Support7Demos/res/values/styles.xml43
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarWithDrawerLayout.java191
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java75
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/MyMediaRouteControllerDialog.java44
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java7
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/Player.java33
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/RemotePlayer.java5
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaButtonReceiver.java3
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouteProvider.java34
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java18
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/media/SessionManager.java2
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java286
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java3
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/DrawerLayoutActivity.java (renamed from samples/Support4Demos/src/com/example/android/supportv4/widget/DrawerLayoutActivity.java)192
-rw-r--r--samples/SupportDesignDemos/Android.mk1
-rw-r--r--samples/SupportDesignDemos/AndroidManifest.xml27
-rw-r--r--samples/SupportDesignDemos/proguard.flags7
-rw-r--r--samples/SupportDesignDemos/res/layout/action_layout.xml23
-rw-r--r--samples/SupportDesignDemos/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml48
-rw-r--r--samples/SupportDesignDemos/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml49
-rw-r--r--samples/SupportDesignDemos/res/layout/design_bottom_sheet.xml72
-rw-r--r--samples/SupportDesignDemos/res/layout/design_tabs.xml41
-rw-r--r--samples/SupportDesignDemos/res/layout/design_tabs_viewpager.xml13
-rw-r--r--samples/SupportDesignDemos/res/layout/design_text_input.xml40
-rw-r--r--samples/SupportDesignDemos/res/menu/navigation.xml6
-rw-r--r--samples/SupportDesignDemos/res/values-w540dp/dimens.xml19
-rw-r--r--samples/SupportDesignDemos/res/values/dimens.xml19
-rw-r--r--samples/SupportDesignDemos/res/values/strings.xml6
-rw-r--r--samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarCollapseThenScrollWithSwipeRefresh.java27
-rw-r--r--samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarScrollTabsScrollSnap.java27
-rw-r--r--samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomSheetUsage.java54
-rw-r--r--samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java69
-rw-r--r--samples/SupportLeanbackDemos/AndroidManifest.xml38
-rwxr-xr-xsamples/SupportLeanbackDemos/generatev4.py320
-rw-r--r--samples/SupportLeanbackDemos/res/layout/browse.xml5
-rw-r--r--samples/SupportLeanbackDemos/res/layout/browse_support.xml37
-rw-r--r--samples/SupportLeanbackDemos/res/layout/details_support.xml25
-rw-r--r--samples/SupportLeanbackDemos/res/layout/guided_step_activity.xml22
-rw-r--r--samples/SupportLeanbackDemos/res/layout/legacy_details_support.xml25
-rw-r--r--samples/SupportLeanbackDemos/res/layout/playback_controls_support.xml36
-rw-r--r--samples/SupportLeanbackDemos/res/layout/rows_support.xml38
-rw-r--r--samples/SupportLeanbackDemos/res/layout/search_support.xml25
-rw-r--r--samples/SupportLeanbackDemos/res/layout/vertical_grid_support.xml25
-rw-r--r--samples/SupportLeanbackDemos/res/values/strings.xml27
-rw-r--r--samples/SupportLeanbackDemos/res/values/themes.xml2
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseErrorSupportActivity.java88
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java38
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportActivity.java40
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java162
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java5
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java11
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportActivity.java61
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java218
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/ErrorSupportFragment.java56
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java283
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java402
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java36
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java3
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java255
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java280
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java7
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java30
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java172
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportActivity.java60
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportFragment.java120
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchDetailsSupportActivity.java23
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportActivity.java67
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java104
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java24
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportActivity.java32
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportFragment.java114
-rw-r--r--samples/SupportLeanbackShowcase/.gitignore7
-rw-r--r--samples/SupportLeanbackShowcase/SupportLeanbackShowcase.iml19
-rw-r--r--samples/SupportLeanbackShowcase/app/.gitignore1
-rw-r--r--samples/SupportLeanbackShowcase/app/app.iml103
-rw-r--r--samples/SupportLeanbackShowcase/app/build.gradle36
-rw-r--r--samples/SupportLeanbackShowcase/app/proguard-rules.pro17
-rw-r--r--samples/SupportLeanbackShowcase/app/src/androidTest/java/android/support/v17/leanback/supportleanbackshowcase/ApplicationTest.java13
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml59
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainActivity.java39
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java181
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleActivity.java34
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java132
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleActivity.java32
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java179
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailsDescriptionPresenter.java62
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/ShadowRowPresenterSelector.java44
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleActivity.java35
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/dialog/DialogExampleFragment.java67
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleActivity.java30
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java72
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MediaPlayerGlue.java446
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicConsumptionExampleFragment.java155
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/MusicExampleActivity.java30
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/SongListRow.java20
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/TrackListHeader.java50
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java117
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoExampleActivity.java39
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoMediaPlayerGlue.java57
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoSurfaceFragment.java39
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleActivity.java31
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java107
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java70
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java101
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java98
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java69
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java47
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java47
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java69
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.java56
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java79
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java92
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java40
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java51
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.java60
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java74
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.java38
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java41
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Card.java129
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/CardRow.java44
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/DetailedCard.java71
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Movie.java50
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/Song.java116
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/models/SongList.java31
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/CardListRow.java45
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Constants.java17
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/PicassoBackgroundManagerTarget.java61
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/ResourceCache.java36
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java58
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-v21/song_row_background_focused.xml20
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_canyon.jpgbin0 -> 610277 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_food.jpgbin0 -> 233732 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_sax.jpgbin0 -> 224765 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_dummy_16_9_l.pngbin0 -> 3937 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_01.pngbin0 -> 389440 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_02.pngbin0 -> 286778 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_03.pngbin0 -> 126637 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_04.pngbin0 -> 302881 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_05.pngbin0 -> 303924 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_06.pngbin0 -> 368153 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_07.pngbin0 -> 219069 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_08.pngbin0 -> 269862 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_09.pngbin0 -> 277175 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_01.jpgbin0 -> 173059 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_02.jpgbin0 -> 188294 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_03.jpgbin0 -> 96252 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_04.jpgbin0 -> 84782 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_05.jpgbin0 -> 187373 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_06.jpgbin0 -> 131330 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_07.jpgbin0 -> 120184 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_08.jpgbin0 -> 79576 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_09.jpgbin0 -> 80383 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_10.jpgbin0 -> 129864 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_11.jpgbin0 -> 110962 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_12.jpgbin0 -> 137199 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_13.jpgbin0 -> 84534 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_action.pngbin0 -> 19388 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_animation.pngbin0 -> 20711 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_classics.pngbin0 -> 18841 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_comedy.pngbin0 -> 19503 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_crime.pngbin0 -> 19844 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_documentary.pngbin0 -> 20660 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_drama.pngbin0 -> 19306 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_01.pngbin0 -> 223879 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_02.pngbin0 -> 330472 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_03.pngbin0 -> 314348 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_04.pngbin0 -> 343150 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_05.pngbin0 -> 288062 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_06.pngbin0 -> 367936 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_07.pngbin0 -> 293103 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_08.pngbin0 -> 339101 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_01.pngbin0 -> 368998 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_02.pngbin0 -> 535491 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_03.pngbin0 -> 526847 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_04.pngbin0 -> 680355 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_05.pngbin0 -> 532167 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_06.pngbin0 -> 521465 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_07.pngbin0 -> 509352 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_08.pngbin0 -> 568748 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_09.pngbin0 -> 344469 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_10.pngbin0 -> 422496 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_11.pngbin0 -> 613934 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_12.pngbin0 -> 390241 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_13.pngbin0 -> 392126 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_14.pngbin0 -> 422442 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_angry_bird_w.pngbin0 -> 137211 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_badland_w.pngbin0 -> 285313 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_leos_fortune_w.pngbin0 -> 338385 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_minion_rush_w.pngbin0 -> 230633 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_monument_valley_w.pngbin0 -> 162442 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_cc.pngbin0 -> 1252 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_installed.pngbin0 -> 507 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_apps.pngbin0 -> 1436 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_more.pngbin0 -> 629 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_parental_control.pngbin0 -> 1453 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_settings.pngbin0 -> 1893 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_time.pngbin0 -> 2317 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_3_bar.pngbin0 -> 1806 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_4_bar.pngbin0 -> 1372 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_off.pngbin0 -> 1236 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_on_yellow.pngbin0 -> 1265 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/movie_poster_01.pngbin0 -> 371243 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_red.pngbin0 -> 2053 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_white.pngbin0 -> 2081 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_browse.pngbin0 -> 2939 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_cards.pngbin0 -> 1768 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_custom_01.pngbin0 -> 2189 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_detail.pngbin0 -> 1603 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_dialog.pngbin0 -> 1258 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_grid.pngbin0 -> 2509 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_music_consumption.pngbin0 -> 1771 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_settings.pngbin0 -> 1367 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_video_consumption.pngbin0 -> 2326 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_wizard.pngbin0 -> 1250 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/title_android_tv.pngbin0 -> 5641 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/app_icon_your_company.pngbin0 -> 12416 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room.jpgbin0 -> 136080 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room_wide.jpgbin0 -> 166393 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml26
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml26
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml26
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml23
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_01.pngbin0 -> 29995 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_02.pngbin0 -> 32856 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_03.pngbin0 -> 28412 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_04.pngbin0 -> 25692 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_05.pngbin0 -> 15358 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_06.pngbin0 -> 28374 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_07.pngbin0 -> 19390 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/drawable/face_08.pngbin0 -> 26494 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml23
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml19
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml22
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml24
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml20
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml20
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml21
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml21
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml26
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml25
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml26
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml25
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_music_example.xml26
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml25
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_video_example.xml27
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml52
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/detail_view_content.xml96
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml77
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/row_track_list_header.xml44
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml64
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml79
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml20
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_container.xml35
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/layout/wizard_progress_action_item.xml42
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/mipmap-hdpi/ic_launcher.pngbin0 -> 3418 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/mipmap-mdpi/ic_launcher.pngbin0 -> 2206 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/app_banner_sample_app.pngbin0 -> 3492 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/ic_launcher.pngbin0 -> 4842 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xxhdpi/ic_launcher.pngbin0 -> 7718 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/cards_example.json506
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/detail_example.json106
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/grid_example.json88
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/launcher_cards.json63
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/music_consumption_example.json76
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/music_example.json106
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_01.mp3bin0 -> 6950210 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_02.mp3bin0 -> 8017184 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_03.mp3bin0 -> 3320646 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_04.mp3bin0 -> 4153235 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_05.mp3bin0 -> 4516029 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_06.mp3bin0 -> 366592 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_07.mp3bin0 -> 6972648 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_08.mp3bin0 -> 5779145 bytes
-rwxr-xr-xsamples/SupportLeanbackShowcase/app/src/main/res/raw/track_09.mp3bin0 -> 5321271 bytes
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/raw/wizard_example.json6
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml44
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml44
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml46
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml58
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml186
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml62
-rw-r--r--samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml113
-rw-r--r--samples/SupportLeanbackShowcase/build.gradle20
-rw-r--r--samples/SupportLeanbackShowcase/gradle.properties18
-rw-r--r--samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xsamples/SupportLeanbackShowcase/gradlew164
-rw-r--r--samples/SupportLeanbackShowcase/gradlew.bat90
-rw-r--r--samples/SupportLeanbackShowcase/settings.gradle1
-rw-r--r--sdk/plat_tools_source.prop_template2
-rw-r--r--sdk/platform_source.prop_template4
-rw-r--r--sdk/support_source.prop_template2
-rw-r--r--tools/recovery_l10n/res/values-gu-rIN/strings.xml8
-rw-r--r--tools/recovery_l10n/res/values-pt-rBR/strings.xml8
-rw-r--r--tools/recovery_l10n/res/values-sq-rAL/strings.xml8
324 files changed, 11388 insertions, 783 deletions
diff --git a/apps/Development/Android.mk b/apps/Development/Android.mk
index 99133e85f..9dd2e1a34 100644
--- a/apps/Development/Android.mk
+++ b/apps/Development/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common org.apache.http.legacy
diff --git a/build/Android.mk b/build/Android.mk
index b6445a0d7..ae6ae1f42 100644
--- a/build/Android.mk
+++ b/build/Android.mk
@@ -111,13 +111,17 @@ ANDROID_SUPPORT_LIBRARIES := \
android-support-v7-gridlayout \
android-support-v7-mediarouter \
android-support-v7-palette \
+ android-support-v7-preference \
android-support-v7-recyclerview \
android-support-v13 \
+ android-support-v14-preference \
android-support-v17-leanback \
+ android-support-v17-preference-leanback \
android-support-multidex \
android-support-multidex-instrumentation \
android-support-design \
android-support-percent \
+ android-support-recommendation \
android-support-customtabs
$(foreach lib, $(ANDROID_SUPPORT_LIBRARIES), $(eval $(call _package_sdk_library,$(lib))))
diff --git a/build/sdk.atree b/build/sdk.atree
index ee1e25132..b302a5868 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -521,6 +521,22 @@ ${OUT_DIR}/target/common/obj/PACKAGING/android-support-percent_intermediates/and
frameworks/support/customtabs/AndroidManifest.xml extras/android/support/customtabs/AndroidManifest.xml
${OUT_DIR}/target/common/obj/PACKAGING/android-support-customtabs_intermediates/android-support-customtabs.jar extras/android/support/customtabs/libs/android-support-customtabs.jar
+
+frameworks/support/v7/preference/AndroidManifest.xml extras/android/support/v7/preference/AndroidManifest.xml
+frameworks/support/v7/preference/res extras/android/support/v7/preference/res
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-v7-preference_intermediates/android-support-v7-preference.jar extras/android/support/v7/preference/libs/android-support-v7-preference.jar
+
+frameworks/support/v14/preference/AndroidManifest.xml extras/android/support/v14/preference/AndroidManifest.xml
+frameworks/support/v14/preference/res extras/android/support/v14/preference/res
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-v14-preference_intermediates/android-support-v14-preference.jar extras/android/support/v14/preference/libs/android-support-v14-preference.jar
+
+frameworks/support/v17/preference-leanback/AndroidManifest.xml extras/android/support/v17/preference-leanback/AndroidManifest.xml
+frameworks/support/v17/preference-leanback/res extras/android/support/v17/preference-leanback/res
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-v17-preference-leanback_intermediates/android-support-v17-preference-leanback.jar extras/android/support/v17/preference-leanback/libs/android-support-v17-preference-leanback.jar
+
+frameworks/support/recommendation/AndroidManifest.xml extras/android/support/recommendation/AndroidManifest.xml
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-recommendation_intermediates/android-support-recommendation.jar extras/android/support/recommendation/libs/android-support-recommendation.jar
+
##############################################################################
# Tests Component
##############################################################################
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index e662cf4b9..da5dcaf24 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -297,8 +297,8 @@
</intent-filter>
</activity>
- <activity android:name=".widget.DrawerLayoutActivity"
- android:label="@string/drawer_layout_support">
+ <activity android:name=".view.ViewPagerActivity"
+ android:label="@string/view_pager_layout_support">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
@@ -367,6 +367,14 @@
</intent-filter>
</activity>
+ <activity android:name=".graphics.DrawableCompatActivity"
+ android:label="Graphics/DrawableCompat">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<!-- BEGIN_INCLUDE(file_provider_declaration) -->
<provider
android:name="android.support.v4.content.FileProvider"
diff --git a/samples/Support4Demos/res/color/tint_state_list.xml b/samples/Support4Demos/res/color/tint_state_list.xml
new file mode 100644
index 000000000..ea37c52a4
--- /dev/null
+++ b/samples/Support4Demos/res/color/tint_state_list.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="#0000FF" />
+ <item android:color="#FF0000" />
+</selector> \ No newline at end of file
diff --git a/samples/Support4Demos/res/drawable-hdpi/ic_favorite.png b/samples/Support4Demos/res/drawable-hdpi/ic_favorite.png
new file mode 100644
index 000000000..1de4e583d
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-hdpi/ic_favorite.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-mdpi/ic_favorite.png b/samples/Support4Demos/res/drawable-mdpi/ic_favorite.png
new file mode 100644
index 000000000..aa5d340db
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-mdpi/ic_favorite.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-xhdpi/ic_favorite.png b/samples/Support4Demos/res/drawable-xhdpi/ic_favorite.png
new file mode 100644
index 000000000..5868c34bf
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-xhdpi/ic_favorite.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-xxhdpi/ic_favorite.png b/samples/Support4Demos/res/drawable-xxhdpi/ic_favorite.png
new file mode 100644
index 000000000..02b46e3bd
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-xxhdpi/ic_favorite.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-xxxhdpi/ic_favorite.png b/samples/Support4Demos/res/drawable-xxxhdpi/ic_favorite.png
new file mode 100644
index 000000000..d7684c4cf
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-xxxhdpi/ic_favorite.png
Binary files differ
diff --git a/samples/Support4Demos/res/layout/drawable_compat.xml b/samples/Support4Demos/res/layout/drawable_compat.xml
new file mode 100644
index 000000000..dbf0413c9
--- /dev/null
+++ b/samples/Support4Demos/res/layout/drawable_compat.xml
@@ -0,0 +1,51 @@
+<!--
+ ~ Copyright 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ android:clickable="true"/>
+
+ <RadioGroup
+ android:id="@+id/drawable_compat_options"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <RadioButton android:id="@+id/drawable_compat_no_tint"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/drawable_compat_no_tint"/>
+
+ <RadioButton android:id="@+id/drawable_compat_color"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/drawable_compat_color_tint"/>
+
+ <RadioButton android:id="@+id/drawable_compat_state_list"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/drawable_compat_color_list_tint"/>
+
+ </RadioGroup>
+
+</LinearLayout>
diff --git a/samples/Support4Demos/res/layout/drawer_layout.xml b/samples/Support4Demos/res/layout/drawer_layout.xml
deleted file mode 100644
index 375c8027a..000000000
--- a/samples/Support4Demos/res/layout/drawer_layout.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<!--
- A DrawerLayout is indended to be used as the top-level content view
- using match_parent for both width and height to consume the full space available.
--->
-<android.support.v4.widget.DrawerLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <!-- As the main content view, the view below consumes the entire
- space available using match_parent in both dimensions. -->
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:scrollbarStyle="outsideOverlay">
- <TextView android:id="@+id/content_text"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/drawer_layout_summary"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
- </ScrollView>
- <!-- android:layout_gravity="start" tells DrawerLayout to treat
- this as a sliding drawer on the starting side, which is
- left for left-to-right locales. The drawer is given a fixed
- width in dp and extends the full height of the container. A
- solid background is used for contrast with the content view. -->
- <ListView android:id="@+id/start_drawer"
- android:layout_width="300dp"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:background="#ff333333"/>
-</android.support.v4.widget.DrawerLayout>
-
diff --git a/samples/Support4Demos/res/layout/view_pager_layout.xml b/samples/Support4Demos/res/layout/view_pager_layout.xml
new file mode 100644
index 000000000..de248dff1
--- /dev/null
+++ b/samples/Support4Demos/res/layout/view_pager_layout.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<android.support.v4.view.ViewPager
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v4.view.PagerTitleStrip
+ android:id="@+id/titles"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top" />
+
+</android.support.v4.view.ViewPager>
+
diff --git a/samples/Support4Demos/res/values/strings.xml b/samples/Support4Demos/res/values/strings.xml
index 0c388b2b8..1d9f129df 100644
--- a/samples/Support4Demos/res/values/strings.xml
+++ b/samples/Support4Demos/res/values/strings.xml
@@ -156,18 +156,7 @@
<string name="sample_transport_controller_activity">Media/TransportController</string>
- <string name="drawer_layout_support">Widget/Drawer layout</string>
-
- <string name="drawer_layout_summary">This activity illustrates the use of sliding drawers. The drawer may be pulled out from the starting edge, which is left on left-to-right locales, with an edge swipe. If this demo is running on Ice Cream Sandwich or newer you may tap the icon at the starting side of the action bar to open the drawer as well.</string>
-
- <!-- Title of the navigation drawer, used by accessibility to announce state changes. -->
- <string name="drawer_title">Navigation</string>
-
- <!-- Description of the icon that opens the navigation drawer, used by accessibility. -->
- <string name="drawer_open">Open navigation drawer</string>
-
- <!-- Description of the icon that closes the navigation drawer, used by accessibility. -->
- <string name="drawer_close">Close navigation drawer</string>
+ <string name="view_pager_layout_support">View/View pager</string>
<string name="sliding_pane_layout_support">Widget/Sliding pane layout</string>
@@ -191,4 +180,7 @@
<string name="regular">regular</string>
<string name="round">round</string>
+ <string name="drawable_compat_no_tint">Not tint</string>
+ <string name="drawable_compat_color_tint">Color tint</string>
+ <string name="drawable_compat_color_list_tint">Color state list</string>
</resources>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/graphics/DrawableCompatActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/graphics/DrawableCompatActivity.java
new file mode 100644
index 000000000..f6790679b
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/graphics/DrawableCompatActivity.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 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 com.example.android.supportv4.graphics;
+
+import com.example.android.supportv4.R;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.widget.ImageView;
+import android.widget.RadioGroup;
+
+/**
+ * Demonstrates use of a {@link DrawableCompat}'s ability to become circular.
+ */
+public class DrawableCompatActivity extends Activity {
+
+ private static final int IMAGE_RES = R.drawable.ic_favorite;
+
+ private ImageView mImageView;
+ private Drawable mDrawable;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.drawable_compat);
+
+ mImageView = (ImageView) findViewById(R.id.image);
+
+ Drawable d = ContextCompat.getDrawable(this, IMAGE_RES);
+ mDrawable = DrawableCompat.wrap(d.mutate());
+
+ mImageView.setImageDrawable(mDrawable);
+
+ RadioGroup rg = (RadioGroup) findViewById(R.id.drawable_compat_options);
+ rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(RadioGroup radioGroup, int id) {
+ switch (id) {
+ case R.id.drawable_compat_no_tint:
+ clearTint();
+ break;
+ case R.id.drawable_compat_color:
+ setColorTint();
+ break;
+ case R.id.drawable_compat_state_list:
+ setColorStateListTint();
+ break;
+ }
+ }
+ });
+ }
+
+ private void clearTint() {
+ DrawableCompat.setTintList(mDrawable, null);
+ }
+
+ private void setColorTint() {
+ DrawableCompat.setTint(mDrawable, Color.MAGENTA);
+ }
+
+ private void setColorStateListTint() {
+ DrawableCompat.setTintList(mDrawable,
+ ContextCompat.getColorStateList(this, R.color.tint_state_list));
+ }
+
+}
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java
new file mode 100644
index 000000000..51503635e
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java
@@ -0,0 +1,110 @@
+/*
+ * 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 com.example.android.supportv4.view;
+
+import com.example.android.supportv4.R;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.PagerTitleStrip;
+import android.support.v4.view.ViewPager;
+import android.util.Pair;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+public class ViewPagerActivity extends Activity {
+ private ViewPager mPager;
+ private PagerTitleStrip mTitles;
+ private ColorPagerAdapter mAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.view_pager_layout);
+
+ mAdapter = new ColorPagerAdapter();
+ mAdapter.add("Red", Color.RED);
+ mAdapter.add("Green", Color.GREEN);
+ mAdapter.add("Blue", Color.BLUE);
+
+ mPager = (ViewPager) findViewById(R.id.pager);
+ mPager.setAdapter(mAdapter);
+
+ mTitles = (PagerTitleStrip) findViewById(R.id.titles);
+ }
+
+ private static class ColorPagerAdapter extends PagerAdapter {
+ private ArrayList<Pair<String, Integer>> mEntries = new ArrayList<>();
+
+ public void add(String title, int color) {
+ mEntries.add(new Pair(title, color));
+ }
+
+ @Override
+ public int getCount() {
+ return mEntries.size();
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ final View view = new View(container.getContext());
+ view.setBackgroundColor(mEntries.get(position).second);
+
+ // Unlike ListView adapters, the ViewPager adapter is responsible
+ // for adding the view to the container.
+ container.addView(view);
+
+ return new ViewHolder(view, position);
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ // The adapter is also responsible for removing the view.
+ container.removeView(((ViewHolder) object).view);
+ }
+
+ @Override
+ public int getItemPosition(Object object) {
+ return ((ViewHolder) object).position;
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return ((ViewHolder) object).view == view;
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return mEntries.get(position).first;
+ }
+
+ private static class ViewHolder {
+ final View view;
+ final int position;
+
+ public ViewHolder(View view, int position) {
+ this.view = view;
+ this.position = position;
+ }
+ }
+ }
+}
diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index 288b124e8..e1a0f98ae 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -60,8 +60,9 @@
<!-- MediaRouter Support Samples -->
<activity android:name=".media.SampleMediaRouterActivity"
+ android:configChanges="orientation|screenSize"
android:label="@string/sample_media_router_activity_dark"
- android:theme="@style/Theme.AppCompat">
+ android:theme="@style/Theme.SampleMediaRouter">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.example.android.supportv7.SAMPLE_CODE" />
@@ -69,8 +70,9 @@
</activity>
<activity android:name=".media.SampleMediaRouterActivity$Light"
+ android:configChanges="orientation|screenSize"
android:label="@string/sample_media_router_activity_light"
- android:theme="@style/Theme.AppCompat.Light">
+ android:theme="@style/Theme.SampleMediaRouter.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.example.android.supportv7.SAMPLE_CODE" />
@@ -78,8 +80,9 @@
</activity>
<activity android:name=".media.SampleMediaRouterActivity$LightWithDarkActionBar"
+ android:configChanges="orientation|screenSize"
android:label="@string/sample_media_router_activity_light_with_dark_action_bar"
- android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
+ android:theme="@style/Theme.SampleMediaRouter.Light.DarkActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.example.android.supportv7.SAMPLE_CODE" />
@@ -194,16 +197,6 @@
</intent-filter>
</activity>
- <activity android:name=".app.ActionBarWithDrawerLayout"
- android:label="@string/action_bar_with_navigation_drawer"
- android:theme="@style/Theme.AppCompat"
- >
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
- </intent-filter>
- </activity>
-
<activity android:name=".app.ActionBarPreferences"
android:label="@string/action_bar_preferences"
android:theme="@style/Theme.AppCompat">
@@ -430,6 +423,16 @@
<category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
</intent-filter>
</activity>
+
+ <!-- DrawerLayout demo activity -->
+ <activity android:name=".widget.DrawerLayoutActivity"
+ android:label="@string/drawer_layout_activity"
+ android:theme="@style/Theme.SampleDrawerLayout">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
+ </intent-filter>
+ </activity>
</application>
diff --git a/samples/Support4Demos/res/drawable-hdpi/drawer_shadow.9.png b/samples/Support7Demos/res/drawable-hdpi/drawer_shadow.9.png
index 224cc4ff4..224cc4ff4 100644
--- a/samples/Support4Demos/res/drawable-hdpi/drawer_shadow.9.png
+++ b/samples/Support7Demos/res/drawable-hdpi/drawer_shadow.9.png
Binary files differ
diff --git a/samples/Support7Demos/res/drawable-hdpi/ic_android.png b/samples/Support7Demos/res/drawable-hdpi/ic_android.png
new file mode 100755
index 000000000..94b8fb1fa
--- /dev/null
+++ b/samples/Support7Demos/res/drawable-hdpi/ic_android.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-mdpi/drawer_shadow.9.png b/samples/Support7Demos/res/drawable-mdpi/drawer_shadow.9.png
index 3797f99c0..3797f99c0 100644
--- a/samples/Support4Demos/res/drawable-mdpi/drawer_shadow.9.png
+++ b/samples/Support7Demos/res/drawable-mdpi/drawer_shadow.9.png
Binary files differ
diff --git a/samples/Support7Demos/res/drawable-mdpi/ic_android.png b/samples/Support7Demos/res/drawable-mdpi/ic_android.png
new file mode 100755
index 000000000..afc43dbdd
--- /dev/null
+++ b/samples/Support7Demos/res/drawable-mdpi/ic_android.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-xhdpi/drawer_shadow.9.png b/samples/Support7Demos/res/drawable-xhdpi/drawer_shadow.9.png
index fa3d853e9..fa3d853e9 100644
--- a/samples/Support4Demos/res/drawable-xhdpi/drawer_shadow.9.png
+++ b/samples/Support7Demos/res/drawable-xhdpi/drawer_shadow.9.png
Binary files differ
diff --git a/samples/Support7Demos/res/layout/action_bar_drawer_layout.xml b/samples/Support7Demos/res/layout/action_bar_drawer_layout.xml
deleted file mode 100644
index a68fdb40d..000000000
--- a/samples/Support7Demos/res/layout/action_bar_drawer_layout.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!--
- A DrawerLayout is indended to be used as the top-level content view
- using match_parent for both width and height to consume the full space available.
--->
-<android.support.v4.widget.DrawerLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <!-- As the main content view, the view below consumes the entire
- space available using match_parent in both dimensions. -->
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:scrollbarStyle="outsideOverlay">
- <TextView android:id="@+id/content_text"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/drawer_layout_summary"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
- </ScrollView>
- <!-- android:layout_gravity="start" tells DrawerLayout to treat
- this as a sliding drawer on the starting side, which is
- left for left-to-right locales. The drawer is given a fixed
- width in dp and extends the full height of the container. A
- solid background is used for contrast with the content view. -->
- <ListView android:id="@+id/start_drawer"
- android:layout_width="300dp"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:background="#ff333333"/>
-</android.support.v4.widget.DrawerLayout>
diff --git a/samples/Support7Demos/res/layout/animated_recycler_view.xml b/samples/Support7Demos/res/layout/animated_recycler_view.xml
index 29a23e26a..e5ff03760 100644
--- a/samples/Support7Demos/res/layout/animated_recycler_view.xml
+++ b/samples/Support7Demos/res/layout/animated_recycler_view.xml
@@ -26,9 +26,9 @@
android:layout_height="wrap_content"/>
<CheckBox
- android:id="@+id/enableChangeAnimations"
+ android:id="@+id/enableInPlaceChange"
android:checked="false"
- android:text="@string/enableChangeAnimations"
+ android:text="@string/enableInPlaceChange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
diff --git a/samples/Support7Demos/res/layout/drawer_layout.xml b/samples/Support7Demos/res/layout/drawer_layout.xml
new file mode 100644
index 000000000..c110af75f
--- /dev/null
+++ b/samples/Support7Demos/res/layout/drawer_layout.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!--
+ A DrawerLayout is indended to be used as the top-level content view
+ using match_parent for both width and height to consume the full space available.
+-->
+<android.support.v4.widget.DrawerLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/drawer_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
+ <!-- As the main content view, the view below consumes the entire
+ space available using match_parent in both dimensions. Note that
+ this child does not specify android:layout_gravity attribute. -->
+ <FrameLayout
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- This will be set as the support action bar of the activity at runtime.
+ It needs to be a dynamic runtime call for correct vertical layering of
+ the drawer and the toolbar. -->
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <!-- Note layout_marginTop attribute with action bar height as the value.
+ This "pushes" down the main content so that it doesn't overlap with
+ the toolbar. -->
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="?attr/actionBarSize"
+ android:scrollbarStyle="outsideOverlay">
+ <TextView
+ android:id="@+id/content_text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/drawer_layout_summary"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:padding="16dp"/>
+ </ScrollView>
+ </FrameLayout>
+
+ <!-- android:layout_gravity="start" tells DrawerLayout to treat
+ this as a sliding drawer on the starting side, which is
+ left for left-to-right locales. The drawer is given a fixed
+ width in dp and extends the full height of the container. A
+ solid background is used for contrast with the content view.
+ android:fitsSystemWindows="true" tells the system to have
+ DrawerLayout span the full height of the screen, including the
+ system status bar on Lollipop+ versions of the plaform. -->
+ <ListView
+ android:id="@+id/start_drawer"
+ android:layout_width="300dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="start"
+ android:background="#ff333333"
+ android:fitsSystemWindows="true"/>
+</android.support.v4.widget.DrawerLayout>
+
diff --git a/samples/Support7Demos/res/layout/sample_media_router.xml b/samples/Support7Demos/res/layout/sample_media_router.xml
index e2f7008df..618a8e40f 100644
--- a/samples/Support7Demos/res/layout/sample_media_router.xml
+++ b/samples/Support7Demos/res/layout/sample_media_router.xml
@@ -76,6 +76,12 @@
</TabHost>
<!-- Control buttons for the currently selected route. -->
+ <CheckBox android:id="@+id/custom_control_view_checkbox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/use_default_media_control"
+ android:checked="true"
+ android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/samples/Support7Demos/res/layout/selectable_item.xml b/samples/Support7Demos/res/layout/selectable_item.xml
index 3cab6fb0c..90aa080e0 100644
--- a/samples/Support7Demos/res/layout/selectable_item.xml
+++ b/samples/Support7Demos/res/layout/selectable_item.xml
@@ -5,27 +5,13 @@
android:onClick="itemClicked"
android:layout_width="match_parent"
android:layout_height="match_parent">
-
<CheckBox
android:id="@+id/selected"
android:onClick="checkboxClicked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
-
- <LinearLayout
- android:orientation="vertical"
+ <TextView
+ android:id="@+id/text"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView
- android:id="@+id/text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- <TextView
- android:id="@+id/expandedText"
- android:visibility="gone"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- </LinearLayout>
-
+ android:layout_height="wrap_content"/>
</LinearLayout> \ No newline at end of file
diff --git a/samples/Support7Demos/res/values/colors.xml b/samples/Support7Demos/res/values/colors.xml
index c8c67a0a2..8667546b0 100644
--- a/samples/Support7Demos/res/values/colors.xml
+++ b/samples/Support7Demos/res/values/colors.xml
@@ -21,4 +21,6 @@
<color name="card_classic">#BAB7A9</color>
<color name="card_sunbrite">#F9D6AC</color>
<color name="card_tropical">#56C4E8</color>
+
+ <color name="drawer_sample_metal_blue">#FF505080</color>
</resources>
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index accf739d1..5479a0346 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -27,6 +27,9 @@
<string name="media_route_menu_title">Play on...</string>
<string name="sample_media_route_settings_activity">Sample route settings</string>
+ <string name="use_default_media_control">Use default media control</string>
+ <string name="my_media_control_text">My Media Control</string>
+
<string name="library_tab_text">Library</string>
<string name="playlist_tab_text">Playlist</string>
<string name="info_tab_text">Route Info</string>
@@ -36,6 +39,8 @@
<string name="variable_volume_basic_route_name">Variable Volume (Basic) Remote Playback Route</string>
<string name="variable_volume_queuing_route_name">Variable Volume (Queuing) Remote Playback Route</string>
<string name="variable_volume_session_route_name">Variable Volume (Session) Remote Playback Route</string>
+ <string name="variable_volume_route_group_name">Variable Volume Route Group</string>
+ <string name="mixed_volume_route_group_name">Mixed Volume Route Group</string>
<string name="sample_route_description">Sample route from Support7Demos</string>
<!-- GridLayout -->
@@ -99,24 +104,6 @@
<string name="action_bar_fragment_has_options_menu">Set has options menu to true</string>
<string name="action_bar_fragment_menu_visibility">Set menu visibility to true</string>
- <!-- actionbar w/ drawer layout -->
- <string name="drawer_layout_support">Widget/Drawer layout</string>
-
- <string name="drawer_layout_summary">This activity illustrates the use of sliding drawers. The
- drawer may be pulled out from the starting edge, which is left on left-to-right locales,
- with an edge swipe. If this demo is running on Ice Cream Sandwich or newer you may tap the
- icon at the starting side of the action bar to open the drawer as well.
- </string>
-
- <!-- Title of the navigation drawer, used by accessibility to announce state changes. -->
- <string name="drawer_title">Navigation</string>
-
- <!-- Description of the icon that opens the navigation drawer, used by accessibility. -->
- <string name="drawer_open">Open navigation drawer</string>
-
- <!-- Description of the icon that closes the navigation drawer, used by accessibility. -->
- <string name="drawer_close">Close navigation drawer</string>
-
<string name="sliding_pane_layout_support">Widget/Sliding pane layout</string>
<string name="sliding_pane_layout_summary">This activity illustrates the use of sliding panes.
@@ -155,7 +142,7 @@
<string name="checkbox_stack_from_end">Stack From End</string>
<string name="enableAnimations">Animate</string>
<string name="enablePredictiveAnimations">Predictive</string>
- <string name="enableChangeAnimations">Change Anims</string>
+ <string name="enableInPlaceChange">In Place Change</string>
<string name="add_item">Add</string>
<string name="delete_item">Del</string>
<string name="add_delete_item">A+D</string>
@@ -195,4 +182,10 @@
<string name="swipe">swipe me</string>
<string name="swiping">swiping</string>
<string name="vertical">vertical</string>
+
+ <string name="drawer_layout_activity">Drawer layout</string>
+ <string name="drawer_layout_summary">This activity illustrates the use of sliding drawers. The drawer may be pulled out from the starting edge, which is left on left-to-right locales, with an edge swipe. You can tap the hamburger (three horizontal lines) icon at the starting side of the action bar to open the drawer as well.</string>
+ <string name="drawer_title">Navigation</string>
+ <string name="drawer_open">Open navigation drawer</string>
+ <string name="drawer_close">Close navigation drawer</string>
</resources>
diff --git a/samples/Support7Demos/res/values/styles.xml b/samples/Support7Demos/res/values/styles.xml
index 26a9f70de..250b4bf9c 100644
--- a/samples/Support7Demos/res/values/styles.xml
+++ b/samples/Support7Demos/res/values/styles.xml
@@ -29,8 +29,49 @@
<item name="colorAccent">#ffff00</item>
</style>
+ <style name="Theme.SampleMediaRouter" parent="Theme.AppCompat">
+ <item name="colorPrimary">#fff44336</item>
+ <item name="colorPrimaryDark">#d32f2f</item>
+ <item name="alertDialogTheme">@style/Theme.SampleMediaRouter.Dialog.Alert</item>
+ </style>
+
+ <style name="Theme.SampleMediaRouter.Light" parent="Theme.AppCompat.Light">
+ <item name="colorPrimary">#ffff9800</item>
+ <item name="colorPrimaryDark">#f57c00</item>
+ <item name="alertDialogTheme">@style/Theme.SampleMediaRouter.Light.Dialog.Alert</item>
+ </style>
+
+ <style name="Theme.SampleMediaRouter.Light.DarkActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
+ <item name="colorPrimary">#ff2196f3</item>
+ <item name="colorPrimaryDark">#1976d2</item>
+ <item name="alertDialogTheme">@style/Theme.SampleMediaRouter.Light.DarkActionBar.Dialog.Alert</item>
+ </style>
+
+ <style name="Theme.SampleMediaRouter.Dialog.Alert" parent="Theme.AppCompat.Dialog.Alert">
+ <item name="colorPrimary">#fff44336</item>
+ <item name="colorPrimaryDark">#d32f2f</item>
+ </style>
+
+ <style name="Theme.SampleMediaRouter.Light.Dialog.Alert" parent="Theme.AppCompat.Light.Dialog.Alert">
+ <item name="colorPrimary">#ffff9800</item>
+ <item name="colorPrimaryDark">#f57c00</item>
+ </style>
+
+ <style name="Theme.SampleMediaRouter.Light.DarkActionBar.Dialog.Alert" parent="Theme.AppCompat.Light.Dialog.Alert">
+ <item name="colorPrimary">#ff2196f3</item>
+ <item name="colorPrimaryDark">#1976d2</item>
+ </style>
+
<style name="SortedListItem" parent="@android:style/TextAppearance.Medium">
<item name="android:minHeight">35dp</item>
</style>
-</resources> \ No newline at end of file
+ <style name="Theme.SampleDrawerLayout" parent="Theme.AppCompat.NoActionBar">
+ <!-- Tell SystemUI that our activity window will draw the background for the status bar. -->
+ <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+ <!-- Set the status bar to be translucent black. -->
+ <item name="android:statusBarColor">#30000000</item>
+ <item name="windowActionModeOverlay">true</item>
+ <item name="android:windowContentOverlay">@null</item>
+ </style>
+</resources>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarWithDrawerLayout.java b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarWithDrawerLayout.java
deleted file mode 100644
index a45edc986..000000000
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarWithDrawerLayout.java
+++ /dev/null
@@ -1,191 +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 com.example.android.supportv7.app;
-
-import com.example.android.supportv7.R;
-import com.example.android.supportv7.Shakespeare;
-
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarDrawerToggle;
-import android.support.v7.app.AppCompatActivity;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class ActionBarWithDrawerLayout extends AppCompatActivity {
- private DrawerLayout mDrawerLayout;
- private ListView mDrawer;
- private TextView mContent;
-
- private ActionBarHelper mActionBar;
-
- private ActionBarDrawerToggle mDrawerToggle;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.action_bar_drawer_layout);
- mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
- mDrawer = (ListView) findViewById(R.id.start_drawer);
- mContent = (TextView) findViewById(R.id.content_text);
-
- mDrawerLayout.setDrawerListener(new DemoDrawerListener());
-
- // The drawer title must be set in order to announce state changes when
- // accessibility is turned on. This is typically a simple description,
- // e.g. "Navigation".
- mDrawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.drawer_title));
-
- mDrawer.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
- Shakespeare.TITLES));
- mDrawer.setOnItemClickListener(new DrawerItemClickListener());
-
- mActionBar = createActionBarHelper();
- mActionBar.init();
-
- // ActionBarDrawerToggle provides convenient helpers for tying together the
- // prescribed interactions between a top-level sliding drawer and the action bar.
- mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
- R.string.drawer_open, R.string.drawer_close);
- }
-
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
-
- // Sync the toggle state after onRestoreInstanceState has occurred.
- mDrawerToggle.syncState();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- /*
- * The action bar home/up action should open or close the drawer.
- * mDrawerToggle will take care of this.
- */
- if (mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- mDrawerToggle.onConfigurationChanged(newConfig);
- }
-
- /**
- * This list item click listener implements very simple view switching by changing
- * the primary content text. The drawer is closed when a selection is made.
- */
- private class DrawerItemClickListener implements ListView.OnItemClickListener {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- mContent.setText(Shakespeare.DIALOGUE[position]);
- mActionBar.setTitle(Shakespeare.TITLES[position]);
- mDrawerLayout.closeDrawer(mDrawer);
- }
- }
-
- /**
- * A drawer listener can be used to respond to drawer events such as becoming
- * fully opened or closed. You should always prefer to perform expensive operations
- * such as drastic relayout when no animation is currently in progress, either before
- * or after the drawer animates.
- *
- * When using ActionBarDrawerToggle, all DrawerLayout listener methods should be forwarded
- * if the ActionBarDrawerToggle is not used as the DrawerLayout listener directly.
- */
- private class DemoDrawerListener implements DrawerLayout.DrawerListener {
- @Override
- public void onDrawerOpened(View drawerView) {
- mDrawerToggle.onDrawerOpened(drawerView);
- mActionBar.onDrawerOpened();
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- mDrawerToggle.onDrawerClosed(drawerView);
- mActionBar.onDrawerClosed();
- }
-
- @Override
- public void onDrawerSlide(View drawerView, float slideOffset) {
- mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
- }
-
- @Override
- public void onDrawerStateChanged(int newState) {
- mDrawerToggle.onDrawerStateChanged(newState);
- }
- }
-
- /**
- * Create a compatible helper that will manipulate the action bar if available.
- */
- private ActionBarHelper createActionBarHelper() {
- return new ActionBarHelper();
- }
-
- /**
- * Action bar helper for use on ICS and newer devices.
- */
- private class ActionBarHelper {
- private final ActionBar mActionBar;
- private CharSequence mDrawerTitle;
- private CharSequence mTitle;
-
- ActionBarHelper() {
- mActionBar = getSupportActionBar();
- }
-
- public void init() {
- mActionBar.setDisplayHomeAsUpEnabled(true);
- mActionBar.setDisplayShowHomeEnabled(false);
- mTitle = mDrawerTitle = getTitle();
- }
-
- /**
- * When the drawer is closed we restore the action bar state reflecting
- * the specific contents in view.
- */
- public void onDrawerClosed() {
- mActionBar.setTitle(mTitle);
- }
-
- /**
- * When the drawer is open we set the action bar to a generic title.
- * The action bar should only contain data relevant at the top level of
- * the nav hierarchy represented by the drawer, as the rest of your content
- * will be dimmed down and non-interactive.
- */
- public void onDrawerOpened() {
- mActionBar.setTitle(mDrawerTitle);
- }
-
- public void setTitle(CharSequence title) {
- mTitle = title;
- }
- }
-}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java b/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java
index b3c14c26b..b62f76e93 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java
@@ -20,15 +20,12 @@ import android.app.Activity;
import android.app.Presentation;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
-import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
-import android.support.v4.media.session.MediaSessionCompat;
import android.support.v7.media.MediaRouter.RouteInfo;
import android.support.v7.media.MediaItemStatus;
import android.util.Log;
@@ -59,6 +56,7 @@ public abstract class LocalPlayer extends Player implements
private final Context mContext;
private final Handler mHandler = new Handler();
+ private final Handler mUpdateSurfaceHandler = new Handler(mHandler.getLooper());
private MediaPlayer mMediaPlayer;
private int mState = STATE_IDLE;
private int mSeekToPos;
@@ -104,11 +102,6 @@ public abstract class LocalPlayer extends Player implements
}
}
- @Override
- public MediaSessionCompat getMediaSession() {
- return mMediaSession;
- }
-
// Player
@Override
public void play(final PlaylistItem item) {
@@ -145,7 +138,8 @@ public abstract class LocalPlayer extends Player implements
if (mState == STATE_PLAYING || mState == STATE_PAUSED) {
mMediaPlayer.seekTo(pos);
mSeekToPos = pos;
- } else if (mState == STATE_IDLE || mState == STATE_PLAY_PENDING) {
+ } else if (mState == STATE_IDLE || mState == STATE_PREPARING_FOR_PLAY
+ || mState == STATE_PREPARING_FOR_PAUSE) {
// Seek before onPrepared() arrives,
// need to performed delayed seek in onPrepared()
mSeekToPos = pos;
@@ -175,6 +169,8 @@ public abstract class LocalPlayer extends Player implements
if (mState == STATE_PLAYING) {
mMediaPlayer.pause();
mState = STATE_PAUSED;
+ } else if (mState == STATE_PREPARING_FOR_PLAY) {
+ mState = STATE_PREPARING_FOR_PAUSE;
}
}
@@ -186,8 +182,8 @@ public abstract class LocalPlayer extends Player implements
if (mState == STATE_READY || mState == STATE_PAUSED) {
mMediaPlayer.start();
mState = STATE_PLAYING;
- } else if (mState == STATE_IDLE){
- mState = STATE_PLAY_PENDING;
+ } else if (mState == STATE_IDLE || mState == STATE_PREPARING_FOR_PAUSE) {
+ mState = STATE_PREPARING_FOR_PLAY;
}
}
@@ -224,8 +220,10 @@ public abstract class LocalPlayer extends Player implements
if (mState == STATE_IDLE) {
mState = STATE_READY;
updateVideoRect();
- } else if (mState == STATE_PLAY_PENDING) {
- mState = STATE_PLAYING;
+ } else if (mState == STATE_PREPARING_FOR_PLAY
+ || mState == STATE_PREPARING_FOR_PAUSE) {
+ int prevState = mState;
+ mState = mState == STATE_PREPARING_FOR_PLAY ? STATE_PLAYING : STATE_PAUSED;
updateVideoRect();
if (mSeekToPos > 0) {
if (DEBUG) {
@@ -233,7 +231,9 @@ public abstract class LocalPlayer extends Player implements
}
mMediaPlayer.seekTo(mSeekToPos);
}
- mMediaPlayer.start();
+ if (prevState == STATE_PREPARING_FOR_PLAY) {
+ mMediaPlayer.start();
+ }
}
if (mCallback != null) {
mCallback.onPlaylistChanged();
@@ -294,6 +294,7 @@ public abstract class LocalPlayer extends Player implements
protected MediaPlayer getMediaPlayer() { return mMediaPlayer; }
protected int getVideoWidth() { return mVideoWidth; }
protected int getVideoHeight() { return mVideoHeight; }
+ protected int getState() { return mState; }
protected void setSurface(Surface surface) {
mSurface = surface;
mSurfaceHolder = null;
@@ -313,23 +314,29 @@ public abstract class LocalPlayer extends Player implements
}
protected void updateSurface() {
- if (mMediaPlayer == null) {
- // just return if media player is already gone
- return;
- }
- if (mSurface != null) {
- // The setSurface API does not exist until V14+.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- ICSMediaPlayer.setSurface(mMediaPlayer, mSurface);
- } else {
- throw new UnsupportedOperationException("MediaPlayer does not support "
- + "setSurface() on this version of the platform.");
+ mUpdateSurfaceHandler.removeCallbacksAndMessages(null);
+ mUpdateSurfaceHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mMediaPlayer == null) {
+ // just return if media player is already gone
+ return;
+ }
+ if (mSurface != null) {
+ // The setSurface API does not exist until V14+.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ ICSMediaPlayer.setSurface(mMediaPlayer, mSurface);
+ } else {
+ throw new UnsupportedOperationException("MediaPlayer does not support "
+ + "setSurface() on this version of the platform.");
+ }
+ } else if (mSurfaceHolder != null) {
+ mMediaPlayer.setDisplay(mSurfaceHolder);
+ } else {
+ mMediaPlayer.setDisplay(null);
+ }
}
- } else if (mSurfaceHolder != null) {
- mMediaPlayer.setDisplay(mSurfaceHolder);
- } else {
- mMediaPlayer.setDisplay(null);
- }
+ });
}
protected abstract void updateSize();
@@ -351,7 +358,8 @@ public abstract class LocalPlayer extends Player implements
}
private void updateVideoRect() {
- if (mState != STATE_IDLE && mState != STATE_PLAY_PENDING) {
+ if (mState != STATE_IDLE && mState != STATE_PREPARING_FOR_PLAY
+ && mState != STATE_PREPARING_FOR_PAUSE) {
int width = mMediaPlayer.getVideoWidth();
int height = mMediaPlayer.getVideoHeight();
if (width > 0 && height > 0) {
@@ -632,7 +640,10 @@ public abstract class LocalPlayer extends Player implements
@Override
public Bitmap getSnapshot() {
- return mOverlay.getSnapshot();
+ if (getState() == STATE_PLAYING || getState() == STATE_PAUSED) {
+ return mOverlay.getSnapshot();
+ }
+ return null;
}
}
}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/MyMediaRouteControllerDialog.java b/samples/Support7Demos/src/com/example/android/supportv7/media/MyMediaRouteControllerDialog.java
new file mode 100644
index 000000000..326467174
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/MyMediaRouteControllerDialog.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 com.example.android.supportv7.media;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v7.app.MediaRouteControllerDialog;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+import com.example.android.supportv7.R;
+
+/**
+ * An example MediaRouteControllerDialog for demonstrating
+ * {@link android.support.v7.app.MediaRouteControllerDialog#onCreateMediaControlView}.
+ */
+public class MyMediaRouteControllerDialog extends MediaRouteControllerDialog {
+ public MyMediaRouteControllerDialog(Context context) {
+ super(context);
+ }
+
+ @Override
+ public View onCreateMediaControlView(Bundle savedInstanceState) {
+ TextView view = new TextView(getContext());
+ view.setText(R.string.my_media_control_text);
+ view.setBackgroundColor(Color.GRAY);
+ return view;
+ }
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java b/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java
index 80cc77d9a..1d4aaa12d 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java
@@ -19,7 +19,6 @@ import com.example.android.supportv7.R;
import android.content.Context;
import android.graphics.Bitmap;
-import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.hardware.display.DisplayManager;
import android.os.Build;
@@ -95,9 +94,9 @@ public abstract class OverlayDisplayWindow {
// Watches for significant changes in the overlay display window lifecycle.
public interface OverlayWindowListener {
- public void onWindowCreated(Surface surface);
- public void onWindowCreated(SurfaceHolder surfaceHolder);
- public void onWindowDestroyed();
+ void onWindowCreated(Surface surface);
+ void onWindowCreated(SurfaceHolder surfaceHolder);
+ void onWindowDestroyed();
}
/**
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java b/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java
index fcab57dd9..a5d58971e 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java
@@ -16,10 +16,7 @@
package com.example.android.supportv7.media;
-import android.app.PendingIntent;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
@@ -32,17 +29,22 @@ import android.util.Log;
* Abstraction of common playback operations of media items, such as play,
* seek, etc. Used by PlaybackManager as a backend to handle actual playback
* of media items.
+ *
+ * TODO: Introduce prepare() method and refactor subclasses accordingly.
*/
public abstract class Player {
private static final String TAG = "SampleMediaRoutePlayer";
protected static final int STATE_IDLE = 0;
- protected static final int STATE_PLAY_PENDING = 1;
- protected static final int STATE_READY = 2;
- protected static final int STATE_PLAYING = 3;
- protected static final int STATE_PAUSED = 4;
+ protected static final int STATE_PREPARING_FOR_PLAY = 1;
+ protected static final int STATE_PREPARING_FOR_PAUSE = 2;
+ protected static final int STATE_READY = 3;
+ protected static final int STATE_PLAYING = 4;
+ protected static final int STATE_PAUSED = 5;
private static final long PLAYBACK_ACTIONS = PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_PLAY;
+ private static final PlaybackStateCompat INIT_PLAYBACK_STATE = new PlaybackStateCompat.Builder()
+ .setState(PlaybackStateCompat.STATE_NONE, 0, .0f).build();
protected Callback mCallback;
protected MediaSessionCompat mMediaSession;
@@ -88,13 +90,18 @@ public abstract class Player {
} else {
player = new LocalPlayer.OverlayPlayer(context);
}
- player.initMediaSession(session);
+ player.setMediaSession(session);
+ player.initMediaSession();
player.connect(route);
return player;
}
- public MediaSessionCompat getMediaSession() {
- return mMediaSession;
+ protected void initMediaSession() {
+ if (mMediaSession == null) {
+ return;
+ }
+ mMediaSession.setMetadata(null);
+ mMediaSession.setPlaybackState(INIT_PLAYBACK_STATE);
}
protected void updateMetadata() {
@@ -138,16 +145,14 @@ public abstract class Player {
}
}
- private void initMediaSession(MediaSessionCompat session) {
+ private void setMediaSession(MediaSessionCompat session) {
mMediaSession = session;
- updateMetadata();
}
-
public interface Callback {
void onError();
void onCompletion();
void onPlaylistChanged();
void onPlaylistReady();
}
-} \ No newline at end of file
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/RemotePlayer.java b/samples/Support7Demos/src/com/example/android/supportv7/media/RemotePlayer.java
index d47c26069..6ad4f75db 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/RemotePlayer.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/RemotePlayer.java
@@ -19,10 +19,8 @@ package com.example.android.supportv7.media;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
-import android.net.Uri;
import android.os.Bundle;
import android.support.v7.media.MediaItemStatus;
-import android.support.v7.media.MediaControlIntent;
import android.support.v7.media.MediaRouter.ControlRequestCallback;
import android.support.v7.media.MediaRouter.RouteInfo;
import android.support.v7.media.MediaSessionStatus;
@@ -140,7 +138,6 @@ public class RemotePlayer extends Player {
}
if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
pause();
- publishState(STATE_PAUSED);
} else {
publishState(STATE_PLAYING);
}
@@ -385,6 +382,8 @@ public class RemotePlayer extends Player {
}
if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
pause();
+ } else if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING) {
+ publishState(STATE_PLAYING);
}
if (mEnqueuePending) {
mEnqueuePending = false;
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaButtonReceiver.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaButtonReceiver.java
index c2eec8ec5..d35644680 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaButtonReceiver.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaButtonReceiver.java
@@ -16,12 +16,9 @@
package com.example.android.supportv7.media;
-import com.example.android.supportv7.R;
-
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
-import android.util.Log;
import android.view.KeyEvent;
/**
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouteProvider.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouteProvider.java
index 15cf19b7d..4208f5894 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouteProvider.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouteProvider.java
@@ -16,31 +16,26 @@
package com.example.android.supportv7.media;
-import com.example.android.supportv7.R;
-
+import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.content.IntentSender;
import android.content.res.Resources;
-import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaRouter;
import android.net.Uri;
import android.os.Bundle;
-import android.app.PendingIntent;
import android.support.v7.media.MediaControlIntent;
-import android.support.v7.media.MediaItemStatus;
+import android.support.v7.media.MediaRouteDescriptor;
import android.support.v7.media.MediaRouteProvider;
-import android.support.v7.media.MediaRouter.ControlRequestCallback;
import android.support.v7.media.MediaRouteProviderDescriptor;
-import android.support.v7.media.MediaRouteDescriptor;
+import android.support.v7.media.MediaRouter.ControlRequestCallback;
import android.support.v7.media.MediaSessionStatus;
import android.util.Log;
-import android.view.Gravity;
-import android.view.Surface;
-import android.view.SurfaceHolder;
+
+import com.example.android.supportv7.R;
import java.util.ArrayList;
@@ -56,6 +51,7 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
private static final String VARIABLE_VOLUME_BASIC_ROUTE_ID = "variable_basic";
private static final String VARIABLE_VOLUME_QUEUING_ROUTE_ID = "variable_queuing";
private static final String VARIABLE_VOLUME_SESSION_ROUTE_ID = "variable_session";
+
private static final int VOLUME_MAX = 10;
/**
@@ -135,18 +131,16 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
f6.addAction(MediaControlIntent.ACTION_GET_SESSION_STATUS);
f6.addAction(MediaControlIntent.ACTION_END_SESSION);
- CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
+ CONTROL_FILTERS_BASIC = new ArrayList<>();
CONTROL_FILTERS_BASIC.add(f1);
CONTROL_FILTERS_BASIC.add(f2);
CONTROL_FILTERS_BASIC.add(f3);
- CONTROL_FILTERS_QUEUING =
- new ArrayList<IntentFilter>(CONTROL_FILTERS_BASIC);
+ CONTROL_FILTERS_QUEUING = new ArrayList<>(CONTROL_FILTERS_BASIC);
CONTROL_FILTERS_QUEUING.add(f4);
CONTROL_FILTERS_QUEUING.add(f5);
- CONTROL_FILTERS_SESSION =
- new ArrayList<IntentFilter>(CONTROL_FILTERS_QUEUING);
+ CONTROL_FILTERS_SESSION = new ArrayList<>(CONTROL_FILTERS_QUEUING);
CONTROL_FILTERS_SESSION.add(f6);
}
@@ -159,7 +153,6 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
}
private int mVolume = 5;
- private int mEnqueueCount;
public SampleMediaRouteProvider(Context context) {
super(context);
@@ -218,6 +211,8 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
.setCanDisconnect(true)
.build();
+ Uri iconUri = Uri.parse("android.resource://com.example.android.supportv7/"
+ + R.drawable.ic_android);
MediaRouteDescriptor routeDescriptor4 = new MediaRouteDescriptor.Builder(
VARIABLE_VOLUME_SESSION_ROUTE_ID,
r.getString(R.string.variable_volume_session_route_name))
@@ -228,10 +223,10 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
.setVolumeMax(VOLUME_MAX)
.setVolume(mVolume)
+ .setIconUri(iconUri)
.build();
- MediaRouteProviderDescriptor providerDescriptor =
- new MediaRouteProviderDescriptor.Builder()
+ MediaRouteProviderDescriptor providerDescriptor = new MediaRouteProviderDescriptor.Builder()
.addRoute(routeDescriptor1)
.addRoute(routeDescriptor2)
.addRoute(routeDescriptor3)
@@ -412,7 +407,6 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
callback.onError("Failed to open " + uri.toString(), null);
}
}
- mEnqueueCount +=1;
return true;
}
@@ -620,4 +614,4 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
}
}
}
-} \ No newline at end of file
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
index 0a64c55fb..a40992302 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
@@ -56,6 +56,7 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
@@ -79,6 +80,7 @@ import java.io.File;
public class SampleMediaRouterActivity extends AppCompatActivity {
private static final String TAG = "SampleMediaRouterActivity";
private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
+ private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false;
private MediaRouter mMediaRouter;
private MediaRouteSelector mSelector;
@@ -87,6 +89,7 @@ public class SampleMediaRouterActivity extends AppCompatActivity {
private TextView mInfoTextView;
private ListView mLibraryView;
private ListView mPlayListView;
+ private CheckBox mUseDefaultControlCheckBox;
private ImageButton mPauseResumeButton;
private ImageButton mStopButton;
private SeekBar mSeekBar;
@@ -308,6 +311,10 @@ public class SampleMediaRouterActivity extends AppCompatActivity {
mInfoTextView = (TextView) findViewById(R.id.info);
+ mUseDefaultControlCheckBox = (CheckBox) findViewById(R.id.custom_control_view_checkbox);
+ if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) {
+ mUseDefaultControlCheckBox.setVisibility(View.VISIBLE);
+ }
mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button);
mPauseResumeButton.setOnClickListener(new OnClickListener() {
@Override
@@ -518,7 +525,7 @@ public class SampleMediaRouterActivity extends AppCompatActivity {
mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() {
@Override
public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
- return new ControllerDialogFragment(mPlayer);
+ return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox);
}
});
@@ -734,20 +741,23 @@ public class SampleMediaRouterActivity extends AppCompatActivity {
public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment {
private MediaRouteControllerDialog mControllerDialog;
private Player mPlayer;
+ private CheckBox mUseDefaultControlCheckBox;
public ControllerDialogFragment() {
super();
}
- public ControllerDialogFragment(Player player) {
+ public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) {
mPlayer = player;
+ this.mUseDefaultControlCheckBox = customControlViewCheckBox;
}
@Override
public MediaRouteControllerDialog onCreateControllerDialog(
Context context, Bundle savedInstanceState) {
- mControllerDialog = super.onCreateControllerDialog(context,
- savedInstanceState);
+ mControllerDialog = this.mUseDefaultControlCheckBox.isChecked()
+ ? super.onCreateControllerDialog(context, savedInstanceState)
+ : new MyMediaRouteControllerDialog(context);
mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SessionManager.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SessionManager.java
index 1c00192de..6fab2eb6b 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SessionManager.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SessionManager.java
@@ -349,6 +349,8 @@ public class SessionManager implements Player.Callback {
if (mCallback != null) {
mCallback.onItemChanged(item);
}
+ } else {
+ mPlayer.initMediaSession();
}
updateStatus();
}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
index af5c6532d..6714f6d02 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
@@ -15,13 +15,20 @@
*/
package com.example.android.supportv7.widget;
-import android.support.v4.util.ArrayMap;
-import android.widget.CompoundButton;
import com.example.android.supportv7.R;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
+import android.os.Build;
import android.os.Bundle;
+import android.support.v4.util.ArrayMap;
import android.support.v4.view.MenuItemCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.ViewPropertyAnimatorListener;
+import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.TypedValue;
@@ -30,10 +37,10 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.TextView;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
public class AnimatedRecyclerView extends Activity {
@@ -49,6 +56,7 @@ public class AnimatedRecyclerView extends Activity {
boolean mAnimationsEnabled = true;
boolean mPredictiveAnimationsEnabled = true;
RecyclerView.ItemAnimator mCachedAnimator = null;
+ boolean mEnableInPlaceChange = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -57,7 +65,9 @@ public class AnimatedRecyclerView extends Activity {
ViewGroup container = (ViewGroup) findViewById(R.id.container);
mRecyclerView = new RecyclerView(this);
- mCachedAnimator = mRecyclerView.getItemAnimator();
+ mCachedAnimator = createAnimator();
+ mCachedAnimator.setChangeDuration(2000);
+ mRecyclerView.setItemAnimator(mCachedAnimator);
mRecyclerView.setLayoutManager(new MyLayoutManager(this));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
@@ -91,14 +101,241 @@ public class AnimatedRecyclerView extends Activity {
}
});
- CheckBox enableChangeAnimations =
- (CheckBox) findViewById(R.id.enableChangeAnimations);
- enableChangeAnimations.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ CheckBox enableInPlaceChange = (CheckBox) findViewById(R.id.enableInPlaceChange);
+ enableInPlaceChange.setChecked(mEnableInPlaceChange);
+ enableInPlaceChange.setOnCheckedChangeListener(
+ new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ mEnableInPlaceChange = isChecked;
+ }
+ });
+ }
+
+ private RecyclerView.ItemAnimator createAnimator() {
+ return new DefaultItemAnimator() {
+ List<ItemChangeAnimator> mPendingChangeAnimations = new ArrayList<>();
+ ArrayMap<RecyclerView.ViewHolder, ItemChangeAnimator> mRunningAnimations
+ = new ArrayMap<>();
+ ArrayMap<MyViewHolder, Long> mPendingSettleList = new ArrayMap<>();
+
@Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- mCachedAnimator.setSupportsChangeAnimations(isChecked);
+ public void runPendingAnimations() {
+ super.runPendingAnimations();
+ for (ItemChangeAnimator anim : mPendingChangeAnimations) {
+ anim.start();
+ mRunningAnimations.put(anim.mViewHolder, anim);
+ }
+ mPendingChangeAnimations.clear();
+ for (int i = mPendingSettleList.size() - 1; i >=0; i--) {
+ final MyViewHolder vh = mPendingSettleList.keyAt(i);
+ final long duration = mPendingSettleList.valueAt(i);
+ ViewCompat.animate(vh.textView).translationX(0f).alpha(1f)
+ .setDuration(duration).setListener(
+ new ViewPropertyAnimatorListener() {
+ @Override
+ public void onAnimationStart(View view) {
+ dispatchAnimationStarted(vh);
+ }
+
+ @Override
+ public void onAnimationEnd(View view) {
+ ViewCompat.setTranslationX(vh.textView, 0f);
+ ViewCompat.setAlpha(vh.textView, 1f);
+ dispatchAnimationFinished(vh);
+ }
+
+ @Override
+ public void onAnimationCancel(View view) {
+
+ }
+ }).start();
+ }
+ mPendingSettleList.clear();
}
- });
+
+ @Override
+ public ItemHolderInfo recordPreLayoutInformation(RecyclerView.State state,
+ RecyclerView.ViewHolder viewHolder,
+ @AdapterChanges int changeFlags, List<Object> payloads) {
+ MyItemInfo info = (MyItemInfo) super
+ .recordPreLayoutInformation(state, viewHolder, changeFlags, payloads);
+ info.text = ((MyViewHolder) viewHolder).textView.getText();
+ return info;
+ }
+
+ @Override
+ public ItemHolderInfo recordPostLayoutInformation(RecyclerView.State state,
+ RecyclerView.ViewHolder viewHolder) {
+ MyItemInfo info = (MyItemInfo) super.recordPostLayoutInformation(state, viewHolder);
+ info.text = ((MyViewHolder) viewHolder).textView.getText();
+ return info;
+ }
+
+
+ @Override
+ public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder) {
+ return mEnableInPlaceChange;
+ }
+
+ @Override
+ public void endAnimation(RecyclerView.ViewHolder item) {
+ super.endAnimation(item);
+ for (int i = mPendingChangeAnimations.size() - 1; i >= 0; i--) {
+ ItemChangeAnimator anim = mPendingChangeAnimations.get(i);
+ if (anim.mViewHolder == item) {
+ mPendingChangeAnimations.remove(i);
+ anim.setFraction(1f);
+ dispatchChangeFinished(item, true);
+ }
+ }
+ for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
+ ItemChangeAnimator animator = mRunningAnimations.get(item);
+ if (animator != null) {
+ animator.end();
+ mRunningAnimations.removeAt(i);
+ }
+ }
+ for (int i = mPendingSettleList.size() - 1; i >= 0; i--) {
+ final MyViewHolder vh = mPendingSettleList.keyAt(i);
+ if (vh == item) {
+ mPendingSettleList.removeAt(i);
+ dispatchChangeFinished(item, true);
+ }
+ }
+ }
+
+ @Override
+ public boolean animateChange(RecyclerView.ViewHolder oldHolder,
+ RecyclerView.ViewHolder newHolder, ItemHolderInfo preInfo,
+ ItemHolderInfo postInfo) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1
+ || oldHolder != newHolder) {
+ return super.animateChange(oldHolder, newHolder, preInfo, postInfo);
+ }
+ return animateChangeApiHoneycombMr1(oldHolder, newHolder, preInfo, postInfo);
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+ private boolean animateChangeApiHoneycombMr1(RecyclerView.ViewHolder oldHolder,
+ RecyclerView.ViewHolder newHolder,
+ ItemHolderInfo preInfo, ItemHolderInfo postInfo) {
+ endAnimation(oldHolder);
+ MyItemInfo pre = (MyItemInfo) preInfo;
+ MyItemInfo post = (MyItemInfo) postInfo;
+ MyViewHolder vh = (MyViewHolder) oldHolder;
+
+ CharSequence finalText = post.text;
+
+ if (pre.text.equals(post.text)) {
+ // same content. Just translate back to 0
+ final long duration = (long) (getChangeDuration()
+ * (ViewCompat.getTranslationX(vh.textView) / vh.textView.getWidth()));
+ mPendingSettleList.put(vh, duration);
+ // we set it here because previous endAnimation would set it to other value.
+ vh.textView.setText(finalText);
+ } else {
+ // different content, get out and come back.
+ vh.textView.setText(pre.text);
+ final ItemChangeAnimator anim = new ItemChangeAnimator(vh, finalText,
+ getChangeDuration()) {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ setFraction(1f);
+ dispatchChangeFinished(mViewHolder, true);
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ dispatchChangeStarting(mViewHolder, true);
+ }
+ };
+ mPendingChangeAnimations.add(anim);
+ }
+ return true;
+ }
+
+ @Override
+ public ItemHolderInfo obtainHolderInfo() {
+ return new MyItemInfo();
+ }
+ };
+ }
+
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+ abstract private static class ItemChangeAnimator implements
+ ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
+ CharSequence mFinalText;
+ ValueAnimator mValueAnimator;
+ MyViewHolder mViewHolder;
+ final float mMaxX;
+ final float mStartRatio;
+ public ItemChangeAnimator(MyViewHolder viewHolder, CharSequence finalText, long duration) {
+ mViewHolder = viewHolder;
+ mMaxX = mViewHolder.itemView.getWidth();
+ mStartRatio = ViewCompat.getTranslationX(mViewHolder.textView) / mMaxX;
+ mFinalText = finalText;
+ mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
+ mValueAnimator.addUpdateListener(this);
+ mValueAnimator.addListener(this);
+ mValueAnimator.setDuration(duration);
+ mValueAnimator.setTarget(mViewHolder.itemView);
+ }
+
+ void setFraction(float fraction) {
+ fraction = mStartRatio + (1f - mStartRatio) * fraction;
+ if (fraction < .5f) {
+ ViewCompat.setTranslationX(mViewHolder.textView, fraction * mMaxX);
+ ViewCompat.setAlpha(mViewHolder.textView, 1f - fraction);
+ } else {
+ ViewCompat.setTranslationX(mViewHolder.textView, (1f - fraction) * mMaxX);
+ ViewCompat.setAlpha(mViewHolder.textView, fraction);
+ maybeSetFinalText();
+ }
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ setFraction(valueAnimator.getAnimatedFraction());
+ }
+
+ public void start() {
+ mValueAnimator.start();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ maybeSetFinalText();
+ ViewCompat.setAlpha(mViewHolder.textView, 1f);
+ }
+
+ public void maybeSetFinalText() {
+ if (mFinalText != null) {
+ mViewHolder.textView.setText(mFinalText);
+ mFinalText = null;
+ }
+ }
+
+ public void end() {
+ mValueAnimator.cancel();
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+ }
+
+ private static class MyItemInfo extends DefaultItemAnimator.ItemHolderInfo {
+ CharSequence text;
}
@Override
@@ -114,6 +351,7 @@ public class AnimatedRecyclerView extends Activity {
return super.onOptionsItemSelected(item);
}
+ @SuppressWarnings("unused")
public void checkboxClicked(View view) {
ViewGroup parent = (ViewGroup) view.getParent();
boolean selected = ((CheckBox) view).isChecked();
@@ -121,6 +359,7 @@ public class AnimatedRecyclerView extends Activity {
mAdapter.selectItem(holder, selected);
}
+ @SuppressWarnings("unused")
public void itemClicked(View view) {
ViewGroup parent = (ViewGroup) view;
MyViewHolder holder = (MyViewHolder) mRecyclerView.getChildViewHolder(parent);
@@ -462,20 +701,19 @@ public class AnimatedRecyclerView extends Activity {
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
String itemText = mData.get(position);
- ((MyViewHolder) holder).textView.setText(itemText);
- ((MyViewHolder) holder).expandedText.setText("More text for the expanded version");
+ MyViewHolder myViewHolder = (MyViewHolder) holder;
+ myViewHolder.boundText = itemText;
+ myViewHolder.textView.setText(itemText);
boolean selected = false;
if (mSelected.get(itemText) != null) {
selected = mSelected.get(itemText);
}
- ((MyViewHolder) holder).checkBox.setChecked(selected);
+ myViewHolder.checkBox.setChecked(selected);
Boolean expanded = mExpanded.get(itemText);
- if (expanded != null && expanded) {
- ((MyViewHolder) holder).expandedText.setVisibility(View.VISIBLE);
- ((MyViewHolder) holder).textView.setVisibility(View.GONE);
+ if (Boolean.TRUE.equals(expanded)) {
+ myViewHolder.textView.setText("More text for the expanded version");
} else {
- ((MyViewHolder) holder).expandedText.setVisibility(View.GONE);
- ((MyViewHolder) holder).textView.setVisibility(View.VISIBLE);
+ myViewHolder.textView.setText(itemText);
}
}
@@ -484,28 +722,22 @@ public class AnimatedRecyclerView extends Activity {
return mData.size();
}
- public void selectItem(String itemText, boolean selected) {
- mSelected.put(itemText, selected);
- }
-
public void selectItem(MyViewHolder holder, boolean selected) {
- mSelected.put((String) holder.textView.getText().toString(), selected);
+ mSelected.put(holder.boundText, selected);
}
public void toggleExpanded(MyViewHolder holder) {
- String text = (String) holder.textView.getText();
- mExpanded.put(text, !mExpanded.get(text));
+ mExpanded.put(holder.boundText, !mExpanded.get(holder.boundText));
}
}
static class MyViewHolder extends RecyclerView.ViewHolder {
- public TextView expandedText;
public TextView textView;
public CheckBox checkBox;
+ public String boundText;
public MyViewHolder(View v) {
super(v);
- expandedText = (TextView) v.findViewById(R.id.expandedText);
textView = (TextView) v.findViewById(R.id.text);
checkBox = (CheckBox) v.findViewById(R.id.selected);
}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
index 782da523b..002a5745f 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
@@ -25,6 +25,7 @@ import com.example.android.supportv7.widget.util.ConfigViewHolder;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
+import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -69,7 +70,7 @@ abstract public class BaseLayoutManagerActivity<T extends RecyclerView.LayoutMan
mLayoutManager = createLayoutManager();
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(createAdapter());
- mRecyclerView.getItemAnimator().setSupportsChangeAnimations(true);
+ ((DefaultItemAnimator)mRecyclerView.getItemAnimator()).setSupportsChangeAnimations(true);
onRecyclerViewInit(mRecyclerView);
}
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/widget/DrawerLayoutActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/DrawerLayoutActivity.java
index b8735b4bf..8cdf927c2 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/widget/DrawerLayoutActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/DrawerLayoutActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * 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.
@@ -14,30 +14,30 @@
* limitations under the License.
*/
+package com.example.android.supportv7.widget;
-package com.example.android.supportv4.widget;
-
-import android.app.ActionBar;
-import android.app.Activity;
import android.content.res.Configuration;
-import android.os.Build;
import android.os.Bundle;
-import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
-import android.view.Gravity;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
-import com.example.android.supportv4.R;
-import com.example.android.supportv4.Shakespeare;
+import com.example.android.supportv7.R;
+import com.example.android.supportv7.Shakespeare;
/**
- * This example illustrates a common usage of the DrawerLayout widget
- * in the Android support library.
+ * This example illustrates a common usage of the DrawerLayout widget combined with Toolbar
+ * in the Android support library that respect the
+ * <a href="https://www.google.com/design/spec/patterns/navigation-drawer.html">Material design
+ * guidelines</a> for the drawer component.
+ *
*
* <p>A DrawerLayout should be positioned at the top of your view hierarchy, placing it
* below the action bar but above your content views. The primary content should match_parent
@@ -66,15 +66,18 @@ import com.example.android.supportv4.Shakespeare;
* established by the Action Bar that navigation should be to the left and actions to the right.
* An action should be an operation performed on the current contents of the window,
* for example enabling or disabling a data overlay on top of the current content.</p>
+ *
+ * <p>When the drawer is open, it is above the application toolbar. On Lollipop versions of the
+ * platform and above the drawer spans the full height of the screen, including behind the system
+ * status bar.</p>
*/
-public class DrawerLayoutActivity extends Activity {
+public class DrawerLayoutActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawer;
private TextView mContent;
- private ActionBarHelper mActionBar;
-
private ActionBarDrawerToggle mDrawerToggle;
+ private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -86,7 +89,6 @@ public class DrawerLayoutActivity extends Activity {
mDrawer = (ListView) findViewById(R.id.start_drawer);
mContent = (TextView) findViewById(R.id.content_text);
- mDrawerLayout.setDrawerListener(new DemoDrawerListener());
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// The drawer title must be set in order to announce state changes when
@@ -98,13 +100,48 @@ public class DrawerLayoutActivity extends Activity {
Shakespeare.TITLES));
mDrawer.setOnItemClickListener(new DrawerItemClickListener());
- mActionBar = createActionBarHelper();
- mActionBar.init();
+ // Find the toolbar in our layout and set it as the support action bar on the activity.
+ // This is required to have the drawer slide "over" the toolbar.
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+ mToolbar.setTitle(R.string.drawer_title);
+ setSupportActionBar(mToolbar);
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayShowHomeEnabled(false);
// ActionBarDrawerToggle provides convenient helpers for tying together the
// prescribed interactions between a top-level sliding drawer and the action bar.
+ // Note that, as the Javadocs of ActionBarDrawerToggle constructors say, we are
+ // *not* using a constructor that gets a Toolbar since we're setting our toolbar
+ // dynamically at runtime. Furthermore, as the drawer is sliding over the toolbar,
+ // we are suppressing the morphing animation from hamburger to back arrow by
+ // calling super.onDrawerSlide with slideOffset=0.0f. In case your app only has
+ // top-level pages and doesn't need back arrow visuals at all, you can set up
+ // your activity theme to have attribute named "drawerArrowStyle" that points
+ // to an extension of Widget.AppCompat.DrawerArrowToggle that has its "spinBars"
+ // attribute set to false.
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
- R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
+ R.string.drawer_open, R.string.drawer_close) {
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ super.onDrawerSlide(drawerView, 0.0f);
+ }
+
+ @Override
+ public void onDrawerSlide(View drawerView, float slideOffset) {
+ super.onDrawerSlide(drawerView, 0.0f);
+ }
+ };
+
+ mDrawerLayout.setDrawerListener(mDrawerToggle);
+
+ // Configure the background color fill of the system status bar (on supported platform
+ // versions) and the toolbar itself. We're using the same color, and android:statusBar
+ // from the theme makes the status bar slightly darker.
+ final int metalBlueColor = getResources().getColor(R.color.drawer_sample_metal_blue);
+ mDrawerLayout.setStatusBarBackgroundColor(metalBlueColor);
+ mToolbar.setBackgroundColor(metalBlueColor);
}
@Override
@@ -119,7 +156,7 @@ public class DrawerLayoutActivity extends Activity {
public boolean onOptionsItemSelected(MenuItem item) {
/*
* The action bar home/up action should open or close the drawer.
- * mDrawerToggle will take care of this.
+ * The drawer toggle will take care of this.
*/
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
@@ -128,6 +165,18 @@ public class DrawerLayoutActivity extends Activity {
}
@Override
+ public void onBackPressed() {
+ // Is the drawer open?
+ if (mDrawerLayout.isDrawerOpen(mDrawer)) {
+ // Close the drawer and return.
+ mDrawerLayout.closeDrawer(mDrawer);
+ return;
+ }
+
+ super.onBackPressed();
+ }
+
+ @Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
@@ -141,109 +190,8 @@ public class DrawerLayoutActivity extends Activity {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mContent.setText(Shakespeare.DIALOGUE[position]);
- mActionBar.setTitle(Shakespeare.TITLES[position]);
+ mToolbar.setTitle(Shakespeare.TITLES[position]);
mDrawerLayout.closeDrawer(mDrawer);
}
}
-
- /**
- * A drawer listener can be used to respond to drawer events such as becoming
- * fully opened or closed. You should always prefer to perform expensive operations
- * such as drastic relayout when no animation is currently in progress, either before
- * or after the drawer animates.
- *
- * When using ActionBarDrawerToggle, all DrawerLayout listener methods should be forwarded
- * if the ActionBarDrawerToggle is not used as the DrawerLayout listener directly.
- */
- private class DemoDrawerListener implements DrawerLayout.DrawerListener {
- @Override
- public void onDrawerOpened(View drawerView) {
- mDrawerToggle.onDrawerOpened(drawerView);
- mActionBar.onDrawerOpened();
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- mDrawerToggle.onDrawerClosed(drawerView);
- mActionBar.onDrawerClosed();
- }
-
- @Override
- public void onDrawerSlide(View drawerView, float slideOffset) {
- mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
- }
-
- @Override
- public void onDrawerStateChanged(int newState) {
- mDrawerToggle.onDrawerStateChanged(newState);
- }
- }
-
- /**
- * Create a compatible helper that will manipulate the action bar if available.
- */
- private ActionBarHelper createActionBarHelper() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- return new ActionBarHelperICS();
- } else {
- return new ActionBarHelper();
- }
- }
-
- /**
- * Stub action bar helper; this does nothing.
- */
- private class ActionBarHelper {
- public void init() {}
- public void onDrawerClosed() {}
- public void onDrawerOpened() {}
- public void setTitle(CharSequence title) {}
- }
-
- /**
- * Action bar helper for use on ICS and newer devices.
- */
- private class ActionBarHelperICS extends ActionBarHelper {
- private final ActionBar mActionBar;
- private CharSequence mDrawerTitle;
- private CharSequence mTitle;
-
- ActionBarHelperICS() {
- mActionBar = getActionBar();
- }
-
- @Override
- public void init() {
- mActionBar.setDisplayHomeAsUpEnabled(true);
- mActionBar.setHomeButtonEnabled(true);
- mTitle = mDrawerTitle = getTitle();
- }
-
- /**
- * When the drawer is closed we restore the action bar state reflecting
- * the specific contents in view.
- */
- @Override
- public void onDrawerClosed() {
- super.onDrawerClosed();
- mActionBar.setTitle(mTitle);
- }
-
- /**
- * When the drawer is open we set the action bar to a generic title.
- * The action bar should only contain data relevant at the top level of
- * the nav hierarchy represented by the drawer, as the rest of your content
- * will be dimmed down and non-interactive.
- */
- @Override
- public void onDrawerOpened() {
- super.onDrawerOpened();
- mActionBar.setTitle(mDrawerTitle);
- }
-
- @Override
- public void setTitle(CharSequence title) {
- mTitle = title;
- }
- }
}
diff --git a/samples/SupportDesignDemos/Android.mk b/samples/SupportDesignDemos/Android.mk
index f70b6e138..96068ee6f 100644
--- a/samples/SupportDesignDemos/Android.mk
+++ b/samples/SupportDesignDemos/Android.mk
@@ -37,4 +37,5 @@ LOCAL_AAPT_FLAGS := \
--extra-packages android.support.v7.appcompat \
--extra-packages android.support.v7.recyclerview \
--extra-packages android.support.design
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
diff --git a/samples/SupportDesignDemos/AndroidManifest.xml b/samples/SupportDesignDemos/AndroidManifest.xml
index a837458da..3a4dbdf04 100644
--- a/samples/SupportDesignDemos/AndroidManifest.xml
+++ b/samples/SupportDesignDemos/AndroidManifest.xml
@@ -109,6 +109,15 @@
</intent-filter>
</activity>
+ <activity android:name=".widget.AppBarLayoutToolbarScrollTabsScrollSnap"
+ android:label="@string/design_appbar_toolbar_scroll_tabs_scroll_snap"
+ android:theme="@style/Theme.Design">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.support.design.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".widget.AppBarLayoutToolbarScrollTabsPin"
android:label="@string/design_appbar_toolbar_scroll_tabs_pin"
android:theme="@style/Theme.Design">
@@ -154,6 +163,15 @@
</intent-filter>
</activity>
+ <activity android:name=".widget.AppBarLayoutToolbarCollapseThenScrollWithSwipeRefresh"
+ android:label="@string/design_appbar_collapsing_toolbar_scroll_with_swiperefresh"
+ android:theme="@style/Theme.Design">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.support.design.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".widget.AppBarLayoutToolbarCollapseWithImage"
android:label="@string/design_appbar_collapsing_toolbar_with_image"
android:theme="@style/Theme.Design">
@@ -181,5 +199,14 @@
</intent-filter>
</activity>
+ <activity android:name=".widget.BottomSheetUsage"
+ android:label="@string/design_bottomsheet"
+ android:theme="@style/Theme.Design">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.support.design.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
</application>
</manifest>
diff --git a/samples/SupportDesignDemos/proguard.flags b/samples/SupportDesignDemos/proguard.flags
new file mode 100644
index 000000000..9ebd7374d
--- /dev/null
+++ b/samples/SupportDesignDemos/proguard.flags
@@ -0,0 +1,7 @@
+-keep public class * extends android.support.design.widget.CoordinatorLayout$Behavior {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keep public class * extends android.support.v7.widget.LinearLayoutManager {
+ public <init>(android.content.Context, android.util.AttributeSet, int, int);
+}
diff --git a/samples/SupportDesignDemos/res/layout/action_layout.xml b/samples/SupportDesignDemos/res/layout/action_layout.xml
new file mode 100644
index 000000000..a266d5104
--- /dev/null
+++ b/samples/SupportDesignDemos/res/layout/action_layout.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<android.support.v7.widget.SwitchCompat
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/toggle"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"/>
diff --git a/samples/SupportDesignDemos/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml b/samples/SupportDesignDemos/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml
new file mode 100644
index 000000000..d0572afac
--- /dev/null
+++ b/samples/SupportDesignDemos/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/col"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.design.widget.AppBarLayout
+ android:id="@+id/app_bar"
+ android:layout_height="192dp"
+ android:layout_width="match_parent"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
+
+ <android.support.design.widget.CollapsingToolbarLayout
+ android:id="@+id/collapsing_app_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_width="match_parent"
+ app:layout_collapseMode="pin"/>
+
+ </android.support.design.widget.CollapsingToolbarLayout>
+
+ </android.support.design.widget.AppBarLayout>
+
+ <include layout="@layout/include_appbar_recyclerview_swiperefresh"/>
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/samples/SupportDesignDemos/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml b/samples/SupportDesignDemos/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml
new file mode 100644
index 000000000..b559ca370
--- /dev/null
+++ b/samples/SupportDesignDemos/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/col"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.design.widget.AppBarLayout
+ android:id="@+id/app_bar"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_width="match_parent"
+ app:layout_scrollFlags="scroll|enterAlways|snap"/>
+
+ <android.support.design.widget.TabLayout
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_scrollFlags="scroll|enterAlways|snap"
+ app:tabMode="scrollable"/>
+
+ </android.support.design.widget.AppBarLayout>
+
+ <include layout="@layout/include_appbar_scrollview"/>
+
+</android.support.design.widget.CoordinatorLayout>
+
diff --git a/samples/SupportDesignDemos/res/layout/design_bottom_sheet.xml b/samples/SupportDesignDemos/res/layout/design_bottom_sheet.xml
new file mode 100644
index 000000000..56197eaec
--- /dev/null
+++ b/samples/SupportDesignDemos/res/layout/design_bottom_sheet.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<android.support.design.widget.CoordinatorLayout
+ android:id="@+id/coordinator"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res/com.example.android.support.design"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <!--
+ This is the bottom sheet. You can use any View as a bottom sheet by marking it with
+ app:layout_behavior as BottomSheetBehavior.
+ -->
+ <LinearLayout
+ android:id="@+id/bottom_sheet"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="@dimen/bottom_sheet_horizontal_margin"
+ android:layout_marginRight="@dimen/bottom_sheet_horizontal_margin"
+ android:background="?android:attr/windowBackground"
+ android:elevation="16dp"
+ android:minHeight="128dp"
+ android:orientation="vertical"
+ app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
+ app:behavior_peekHeight="128dp">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/bottom_sheet"
+ android:paddingTop="8dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingBottom="8dp"
+ style="@style/TextAppearance.AppCompat.Title"/>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+
+ <android.support.v4.widget.NestedScrollView
+ android:id="@+id/scroll"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/dialogue"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ style="@style/TextAppearance.AppCompat.Body1"/>
+
+ </android.support.v4.widget.NestedScrollView>
+
+ </LinearLayout>
+
+</android.support.design.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/samples/SupportDesignDemos/res/layout/design_tabs.xml b/samples/SupportDesignDemos/res/layout/design_tabs.xml
deleted file mode 100644
index b52d80833..000000000
--- a/samples/SupportDesignDemos/res/layout/design_tabs.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <android.support.v7.widget.Toolbar
- android:id="@+id/toolbar"
- android:layout_height="?attr/actionBarSize"
- android:layout_width="match_parent"
- android:background="?attr/colorPrimary"
- android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
- app:contentInsetStart="72dp"
- app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
-
- <android.support.design.widget.TabLayout
- android:id="@+id/tabs"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:background="?attr/colorPrimary"
- android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
- app:tabContentStart="72dp"/>
-
-</LinearLayout>
diff --git a/samples/SupportDesignDemos/res/layout/design_tabs_viewpager.xml b/samples/SupportDesignDemos/res/layout/design_tabs_viewpager.xml
index b249155ed..11ddca639 100644
--- a/samples/SupportDesignDemos/res/layout/design_tabs_viewpager.xml
+++ b/samples/SupportDesignDemos/res/layout/design_tabs_viewpager.xml
@@ -54,13 +54,22 @@
android:id="@+id/btn_add_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/add_tab"/>
+ android:text="@string/add_tab"
+ android:onClick="addTab"/>
<Button
android:id="@+id/btn_remove_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/remove_tab"/>
+ android:text="@string/remove_tab"
+ android:onClick="removeTab"/>
+
+ <Button
+ android:id="@+id/btn_select_first_tab"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/select_first_tab"
+ android:onClick="selectFirstTab"/>
</LinearLayout>
diff --git a/samples/SupportDesignDemos/res/layout/design_text_input.xml b/samples/SupportDesignDemos/res/layout/design_text_input.xml
index 4561df125..32260746f 100644
--- a/samples/SupportDesignDemos/res/layout/design_text_input.xml
+++ b/samples/SupportDesignDemos/res/layout/design_text_input.xml
@@ -36,6 +36,24 @@
</android.support.design.widget.TextInputLayout>
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/show_error"
+ android:onClick="showError"/>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/clear_error"
+ android:onClick="clearError"/>
+
+ </LinearLayout>
+
<android.support.design.widget.TextInputLayout
android:id="@+id/input_email"
android:layout_width="match_parent"
@@ -51,16 +69,20 @@
</android.support.design.widget.TextInputLayout>
- <Button
- android:layout_width="wrap_content"
+ <android.support.design.widget.TextInputLayout
+ android:id="@+id/input_description"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/show_error"
- android:onClick="showError"/>
+ android:layout_marginTop="8dp"
+ app:counterEnabled="true"
+ app:counterMaxLength="30">
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/clear_error"
- android:onClick="clearError"/>
+ <EditText
+ android:id="@+id/edit_description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/form_description"/>
+
+ </android.support.design.widget.TextInputLayout>
</LinearLayout> \ No newline at end of file
diff --git a/samples/SupportDesignDemos/res/menu/navigation.xml b/samples/SupportDesignDemos/res/menu/navigation.xml
index b399ef3a9..6425b1893 100644
--- a/samples/SupportDesignDemos/res/menu/navigation.xml
+++ b/samples/SupportDesignDemos/res/menu/navigation.xml
@@ -14,7 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- Main items -->
<group android:checkableBehavior="single">
@@ -30,7 +31,8 @@
<item
android:id="@+id/navigation_item_3"
android:icon="@drawable/ic_android"
- android:title="@string/navigation_item_3"/>
+ android:title="@string/navigation_item_3"
+ app:actionLayout="@layout/action_layout"/>
<item
android:id="@+id/navigation_item_disabled"
android:icon="@drawable/ic_android"
diff --git a/samples/SupportDesignDemos/res/values-w540dp/dimens.xml b/samples/SupportDesignDemos/res/values-w540dp/dimens.xml
new file mode 100644
index 000000000..26fecbf04
--- /dev/null
+++ b/samples/SupportDesignDemos/res/values-w540dp/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <dimen name="bottom_sheet_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/samples/SupportDesignDemos/res/values/dimens.xml b/samples/SupportDesignDemos/res/values/dimens.xml
new file mode 100644
index 000000000..ac8777cfe
--- /dev/null
+++ b/samples/SupportDesignDemos/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <dimen name="bottom_sheet_horizontal_margin">0dp</dimen>
+</resources>
diff --git a/samples/SupportDesignDemos/res/values/strings.xml b/samples/SupportDesignDemos/res/values/strings.xml
index 16b17172a..c3a981a02 100644
--- a/samples/SupportDesignDemos/res/values/strings.xml
+++ b/samples/SupportDesignDemos/res/values/strings.xml
@@ -21,6 +21,7 @@
<string name="design_navigation">NavigationView/Usage</string>
<string name="design_tabs_basic">TabLayout/Usage</string>
<string name="design_text_input">Text Input</string>
+ <string name="design_bottomsheet">BottomSheet/Usage</string>
<string name="fab_size_normal">Normal size</string>
<string name="fab_size_mini">Mini size</string>
@@ -48,9 +49,11 @@
<string name="add_tab">Add tab</string>
<string name="remove_tab">Remove tab</string>
+ <string name="select_first_tab">Select tab #0</string>
<string name="form_username">Username</string>
<string name="form_email">Email address</string>
+ <string name="form_description">Description</string>
<string name="show_error">Show error</string>
<string name="clear_error">Clear error</string>
@@ -64,11 +67,13 @@
<string name="snackbar_show_long_long_action">Show (long message + long action)</string>
<string name="design_appbar_toolbar_scroll_tabs_scroll">AppBar/Toolbar Scroll + Tabs Scroll</string>
+ <string name="design_appbar_toolbar_scroll_tabs_scroll_snap">AppBar/Toolbar Scroll + Tabs Scroll + Snap</string>
<string name="design_appbar_toolbar_scroll_tabs_pin">AppBar/Toolbar Scroll + Tabs Pin</string>
<string name="design_appbar_toolbar_scroll_tabs_pin_with_swiperefresh">AppBar/Toolbar Scroll + Tabs Pin + Swipe Refresh</string>
<string name="design_appbar_collapsing_toolbar_pin">AppBar/Collapsing Toolbar (pinned)</string>
<string name="design_appbar_collapsing_toolbar_pin_fab">AppBar/Collapsing Toolbar (pinned with FAB)</string>
<string name="design_appbar_collapsing_toolbar_scroll">AppBar/Collapsing Toolbar (scroll off)</string>
+ <string name="design_appbar_collapsing_toolbar_scroll_with_swiperefresh">AppBar/Collapsing Toolbar (scroll off) + Swipe Refresh</string>
<string name="design_appbar_collapsing_toolbar_with_image">AppBar/Collapsing Toolbar + Parallax Image</string>
<string name="design_appbar_collapsing_toolbar_with_image_insets">AppBar/Collapsing Toolbar + Parallax Image + Insets</string>
<string name="design_appbar_parallax_overlap">AppBar/Parallax Overlapping content</string>
@@ -77,5 +82,6 @@
<string name="menu_search">Search</string>
<string name="menu_settings">Settings</string>
+ <string name="bottom_sheet">Bottom sheet</string>
</resources>
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarCollapseThenScrollWithSwipeRefresh.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarCollapseThenScrollWithSwipeRefresh.java
new file mode 100644
index 000000000..bed269b87
--- /dev/null
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarCollapseThenScrollWithSwipeRefresh.java
@@ -0,0 +1,27 @@
+/*
+ * 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 com.example.android.support.design.widget;
+
+import com.example.android.support.design.R;
+
+public class AppBarLayoutToolbarCollapseThenScrollWithSwipeRefresh extends AppBarLayoutUsageBase {
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.design_appbar_toolbar_collapse_scroll_with_swiperefresh;
+ }
+}
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarScrollTabsScrollSnap.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarScrollTabsScrollSnap.java
new file mode 100644
index 000000000..710a80abb
--- /dev/null
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/AppBarLayoutToolbarScrollTabsScrollSnap.java
@@ -0,0 +1,27 @@
+/*
+ * 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 com.example.android.support.design.widget;
+
+import com.example.android.support.design.R;
+
+public class AppBarLayoutToolbarScrollTabsScrollSnap extends AppBarLayoutUsageBase {
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.design_appbar_toolbar_scroll_tabs_scroll_snap;
+ }
+}
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomSheetUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomSheetUsage.java
new file mode 100644
index 000000000..21f6ffe62
--- /dev/null
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomSheetUsage.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 com.example.android.support.design.widget;
+
+import com.example.android.support.design.R;
+import com.example.android.support.design.Shakespeare;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.BottomSheetBehavior;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * This demonstrates basic usage of {@link BottomSheetBehavior}.
+ */
+public class BottomSheetUsage extends AppCompatActivity {
+
+ private BottomSheetBehavior<LinearLayout> mBehavior;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.design_bottom_sheet);
+ ((TextView) findViewById(R.id.dialogue)).setText(TextUtils.concat(Shakespeare.DIALOGUE));
+ mBehavior = BottomSheetBehavior.from((LinearLayout) findViewById(R.id.bottom_sheet));
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mBehavior != null && mBehavior.getState() != BottomSheetBehavior.STATE_COLLAPSED) {
+ mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+}
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java
index ef776e0c6..26b61083f 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java
@@ -21,8 +21,6 @@ import com.example.android.support.design.R;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
-import android.support.design.widget.TabLayout.TabLayoutOnPageChangeListener;
-import android.support.design.widget.TabLayout.ViewPagerOnTabSelectedListener;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
@@ -46,6 +44,8 @@ public class TabLayoutUsage extends AppCompatActivity {
private ViewPager mViewPager;
private CheesePagerAdapter mPagerAdapter;
+ private final Random mRandom = new Random();
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -57,41 +57,29 @@ public class TabLayoutUsage extends AppCompatActivity {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mTabLayout = (TabLayout) findViewById(R.id.tabs);
-
mViewPager = (ViewPager) findViewById(R.id.tabs_viewpager);
+
mPagerAdapter = new CheesePagerAdapter();
mViewPager.setAdapter(mPagerAdapter);
- mViewPager.setOnPageChangeListener(new TabLayoutOnPageChangeListener(mTabLayout));
- mTabLayout.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(mViewPager));
- setupButtons();
+ mTabLayout.setupWithViewPager(mViewPager);
+
setupRadioGroup();
}
- private void setupButtons() {
- findViewById(R.id.btn_add_tab).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- addRandomTab();
- }
- });
+ public void addTab(View view) {
+ String cheese = Cheeses.sCheeseStrings[mRandom.nextInt(Cheeses.sCheeseStrings.length)];
+ mPagerAdapter.addTab(cheese);
+ }
- findViewById(R.id.btn_remove_tab).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mTabLayout.getTabCount() >= 1) {
- mTabLayout.removeTabAt(mTabLayout.getTabCount() - 1);
- mPagerAdapter.removeTab();
- }
- }
- });
+ public void selectFirstTab(View view) {
+ if (mTabLayout.getTabCount() > 0) {
+ mViewPager.setCurrentItem(0);
+ }
}
- private void addRandomTab() {
- Random r = new Random();
- String cheese = Cheeses.sCheeseStrings[r.nextInt(Cheeses.sCheeseStrings.length)];
- mTabLayout.addTab(mTabLayout.newTab().setText(cheese));
- mPagerAdapter.addTab(cheese);
+ public void removeTab(View view) {
+ mPagerAdapter.removeTab();
}
private void setupRadioGroup() {
@@ -147,7 +135,6 @@ public class TabLayoutUsage extends AppCompatActivity {
}
private static class CheesePagerAdapter extends PagerAdapter {
-
private final ArrayList<CharSequence> mCheeses = new ArrayList<>();
public void addTab(String title) {
@@ -168,21 +155,31 @@ public class TabLayoutUsage extends AppCompatActivity {
}
@Override
+ public int getItemPosition(Object object) {
+ final Item item = (Item) object;
+ final int index = mCheeses.indexOf(item.cheese);
+ return index >= 0 ? index : POSITION_NONE;
+ }
+
+ @Override
public Object instantiateItem(ViewGroup container, int position) {
- TextView tv = new TextView(container.getContext());
+ final TextView tv = new TextView(container.getContext());
tv.setText(getPageTitle(position));
tv.setGravity(Gravity.CENTER);
tv.setTextAppearance(tv.getContext(), R.style.TextAppearance_AppCompat_Title);
-
container.addView(tv, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
- return tv;
+ Item item = new Item();
+ item.cheese = mCheeses.get(position);
+ item.view = tv;
+ return item;
}
@Override
public boolean isViewFromObject(View view, Object object) {
- return view == object;
+ final Item item = (Item) object;
+ return item.view == view;
}
@Override
@@ -192,7 +189,13 @@ public class TabLayoutUsage extends AppCompatActivity {
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View) object);
+ final Item item = (Item) object;
+ container.removeView(item.view);
+ }
+
+ private static class Item {
+ TextView view;
+ CharSequence cheese;
}
}
diff --git a/samples/SupportLeanbackDemos/AndroidManifest.xml b/samples/SupportLeanbackDemos/AndroidManifest.xml
index 837a123a0..daaf5bf20 100644
--- a/samples/SupportLeanbackDemos/AndroidManifest.xml
+++ b/samples/SupportLeanbackDemos/AndroidManifest.xml
@@ -25,6 +25,10 @@
android:theme="@style/Theme.Example.Leanback.Browse"
android:exported="true" />
+ <activity android:name="BrowseSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.Browse"
+ android:exported="true" />
+
<activity android:name="BrowseAnimationActivity"
android:exported="true" >
</activity>
@@ -33,24 +37,52 @@
android:theme="@style/Theme.Example.Leanback.Details"
android:exported="true" />
+ <activity android:name="DetailsSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.Details"
+ android:exported="true" />
+
<activity android:name="SearchDetailsActivity"
android:theme="@style/Theme.Example.Leanback.SearchDetails"
android:exported="true" />
+ <activity android:name="SearchDetailsSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.SearchDetails"
+ android:exported="true" />
+
<activity android:name="RowsActivity"
android:theme="@style/Theme.Example.Leanback.Rows"
android:exported="true" />
+ <activity android:name="RowsSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.Rows"
+ android:exported="true" />
+
<activity android:name="PlaybackOverlayActivity"
android:exported="true" />
+ <activity android:name="PlaybackOverlaySupportActivity"
+ android:exported="true" />
+
<activity android:name="VerticalGridActivity"
+ android:theme="@style/Theme.Example.Leanback.VerticalGrid"
+ android:exported="true" />
+
+ <activity android:name="VerticalGridSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.VerticalGrid"
android:exported="true" />
<activity android:name="SearchActivity"
android:exported="true" />
+ <activity android:name="SearchSupportActivity"
+ android:exported="true" />
+
<activity android:name="BrowseErrorActivity"
+ android:theme="@style/Theme.Example.Leanback.Browse"
+ android:exported="true" />
+
+ <activity android:name="BrowseErrorSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.Browse"
android:exported="true" />
<activity android:name="HorizontalGridTestActivity"
@@ -58,6 +90,12 @@
<activity android:name="GuidedStepActivity"
android:theme="@style/Theme.Example.Leanback.GuidedStep"
+ android:windowSoftInputMode="adjustResize"
+ android:exported="true" />
+
+ <activity android:name="GuidedStepSupportActivity"
+ android:theme="@style/Theme.Example.Leanback.GuidedStep"
+ android:windowSoftInputMode="adjustResize"
android:exported="true" />
<activity android:name="DetailsPresenterSelectionActivity"
diff --git a/samples/SupportLeanbackDemos/generatev4.py b/samples/SupportLeanbackDemos/generatev4.py
new file mode 100755
index 000000000..4e32d5703
--- /dev/null
+++ b/samples/SupportLeanbackDemos/generatev4.py
@@ -0,0 +1,320 @@
+#!/usr/bin/python
+
+# 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.
+
+import os
+import sys
+
+def write_java_head(tofile, name):
+ tofile.write("/* This file is auto-generated from {}.java. DO NOT MODIFY. */\n\n".format(name))
+
+def replace_xml_head(line, name):
+ return line.replace('<?xml version="1.0" encoding="utf-8"?>', '<?xml version="1.0" encoding="utf-8"?>\n<!-- This file is auto-generated from {}.xml. DO NOT MODIFY. -->\n'.format(name))
+
+file = open('src/com/example/android/leanback/GuidedStepActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/GuidedStepSupportActivity.java', 'w')
+write_java_head(outfile, "GuidedStepActivity")
+for line in file:
+ line = line.replace('android.app.Fragment', 'android.support.v4.app.Fragment')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('GuidedStepFragment', 'GuidedStepSupportFragment')
+ line = line.replace('GuidedStepActivity', 'GuidedStepSupportActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/BrowseFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/BrowseSupportFragment.java', 'w')
+write_java_head(outfile, "BrowseFragment")
+for line in file:
+ line = line.replace('android.app.Fragment', 'android.support.v4.app.Fragment')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('BrowseFragment', 'BrowseSupportFragment')
+ line = line.replace('GuidedStepFragment', 'GuidedStepSupportFragment')
+ line = line.replace('GuidedStepActivity', 'GuidedStepSupportActivity')
+ line = line.replace('BrowseActivity', 'BrowseSupportActivity')
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ line = line.replace('SearchActivity', 'SearchSupportActivity')
+ line = line.replace('RowsActivity', 'RowsSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/BrowseActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/BrowseSupportActivity.java', 'w')
+write_java_head(outfile, "BrowseActivity")
+for line in file:
+ line = line.replace('BrowseActivity', 'BrowseSupportActivity')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.browse', 'R.layout.browse_support')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('res/layout/browse.xml', 'r')
+outfile = open('res/layout/browse_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "browse")
+ line = line.replace('com.example.android.leanback.BrowseFragment', 'com.example.android.leanback.BrowseSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+
+file = open('src/com/example/android/leanback/DetailsFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/DetailsSupportFragment.java', 'w')
+write_java_head(outfile, "DetailsFragment")
+for line in file:
+ line = line.replace('android.app.Fragment', 'android.support.v4.app.Fragment')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('DetailsFragment', 'DetailsSupportFragment')
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ line = line.replace('PlaybackOverlayActivity', 'PlaybackOverlaySupportActivity')
+ line = line.replace('SearchActivity', 'SearchSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/NewDetailsFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/NewDetailsSupportFragment.java', 'w')
+write_java_head(outfile, "NewDetailsFragment")
+for line in file:
+ line = line.replace('android.app.Fragment', 'android.support.v4.app.Fragment')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('DetailsFragment', 'DetailsSupportFragment')
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ line = line.replace('PlaybackOverlayActivity', 'PlaybackOverlaySupportActivity')
+ line = line.replace('SearchActivity', 'SearchSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/DetailsActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/DetailsSupportActivity.java', 'w')
+write_java_head(outfile, "DetailsActivity")
+for line in file:
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.details', 'R.layout.details_support')
+ line = line.replace('R.layout.legacy_details', 'R.layout.legacy_details_support')
+ line = line.replace('getFragmentManager()', 'getSupportFragmentManager()')
+ line = line.replace('DetailsFragment', 'DetailsSupportFragment')
+ line = line.replace('NewDetailsFragment', 'NewDetailsSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('res/layout/details.xml', 'r')
+outfile = open('res/layout/details_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "details")
+ line = line.replace('com.example.android.leanback.NewDetailsFragment', 'com.example.android.leanback.NewDetailsSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+
+file = open('res/layout/legacy_details.xml', 'r')
+outfile = open('res/layout/legacy_details_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "legacy_details")
+ line = line.replace('com.example.android.leanback.DetailsFragment', 'com.example.android.leanback.DetailsSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+
+file = open('src/com/example/android/leanback/SearchDetailsActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/SearchDetailsSupportActivity.java', 'w')
+write_java_head(outfile, "SearchDetailsActivity")
+for line in file:
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+
+file = open('src/com/example/android/leanback/SearchFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/SearchSupportFragment.java', 'w')
+write_java_head(outfile, "SearchFragment")
+for line in file:
+ line = line.replace('SearchFragment', 'SearchSupportFragment')
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/SearchActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/SearchSupportActivity.java', 'w')
+write_java_head(outfile, "SearchActivity")
+for line in file:
+ line = line.replace('SearchActivity', 'SearchSupportActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.search', 'R.layout.search_support')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('getFragmentManager()', 'getSupportFragmentManager()')
+ line = line.replace('SearchFragment', 'SearchSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('res/layout/search.xml', 'r')
+outfile = open('res/layout/search_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "search")
+ line = line.replace('com.example.android.leanback.SearchFragment', 'com.example.android.leanback.SearchSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/VerticalGridFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/VerticalGridSupportFragment.java', 'w')
+outfile.write("/* This file is auto-generated from VerticalGridFragment. DO NOT MODIFY. */\n\n")
+for line in file:
+ line = line.replace('VerticalGridFragment', 'VerticalGridSupportFragment')
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ line = line.replace('SearchActivity', 'SearchSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/VerticalGridActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/VerticalGridSupportActivity.java', 'w')
+write_java_head(outfile, "VerticalGridActivity")
+for line in file:
+ line = line.replace('VerticalGridActivity', 'VerticalGridSupportActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.vertical_grid', 'R.layout.vertical_grid_support')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('getFragmentManager()', 'getSupportFragmentManager()')
+ line = line.replace('VerticalGridFragment', 'VerticalGridSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('res/layout/vertical_grid.xml', 'r')
+outfile = open('res/layout/vertical_grid_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "vertical_grid")
+ line = line.replace('com.example.android.leanback.VerticalGridFragment', 'com.example.android.leanback.VerticalGridSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+
+file = open('src/com/example/android/leanback/ErrorFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/ErrorSupportFragment.java', 'w')
+write_java_head(outfile, "ErrorFragment")
+for line in file:
+ line = line.replace('ErrorFragment', 'ErrorSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/BrowseErrorActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/BrowseErrorSupportActivity.java', 'w')
+write_java_head(outfile, "BrowseErrorActivity")
+for line in file:
+ line = line.replace('BrowseErrorActivity', 'BrowseErrorSupportActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.browse', 'R.layout.browse_support')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('getFragmentManager()', 'getSupportFragmentManager()')
+ line = line.replace('ErrorFragment', 'ErrorSupportFragment')
+ line = line.replace('SpinnerFragment', 'SpinnerSupportFragment')
+ line = line.replace('android.app.Fragment', 'android.support.v4.app.Fragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/RowsFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/RowsSupportFragment.java', 'w')
+write_java_head(outfile, "RowsFragment")
+for line in file:
+ line = line.replace('RowsFragment', 'RowsSupportFragment')
+ line = line.replace('DetailsActivity', 'DetailsSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/RowsActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/RowsSupportActivity.java', 'w')
+write_java_head(outfile, "RowsActivity")
+for line in file:
+ line = line.replace('RowsActivity', 'RowsSupportActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.rows', 'R.layout.rows_support')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ line = line.replace('RowsFragment', 'RowsSupportFragment')
+ line = line.replace('getFragmentManager()', 'getSupportFragmentManager()')
+ line = line.replace('SearchActivity', 'SearchSupportActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('res/layout/rows.xml', 'r')
+outfile = open('res/layout/rows_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "rows")
+ line = line.replace('com.example.android.leanback.RowsFragment', 'com.example.android.leanback.RowsSupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+
+file = open('src/com/example/android/leanback/PlaybackOverlayFragment.java', 'r')
+outfile = open('src/com/example/android/leanback/PlaybackOverlaySupportFragment.java', 'w')
+write_java_head(outfile, "PlaybackOverlayFragment")
+for line in file:
+ line = line.replace('PlaybackOverlayFragment', 'PlaybackOverlaySupportFragment')
+ line = line.replace('PlaybackControlHelper', 'PlaybackControlSupportHelper')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/PlaybackControlHelper.java', 'r')
+outfile = open('src/com/example/android/leanback/PlaybackControlSupportHelper.java', 'w')
+write_java_head(outfile, "PlaybackControlHelper")
+for line in file:
+ line = line.replace('PlaybackControlHelper', 'PlaybackControlSupportHelper')
+ line = line.replace('PlaybackControlGlue', 'PlaybackControlSupportGlue')
+ line = line.replace('PlaybackOverlayFragment', 'PlaybackOverlaySupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('src/com/example/android/leanback/PlaybackOverlayActivity.java', 'r')
+outfile = open('src/com/example/android/leanback/PlaybackOverlaySupportActivity.java', 'w')
+write_java_head(outfile, "PlaybackOverlayActivity")
+for line in file:
+ line = line.replace('PlaybackOverlayActivity', 'PlaybackOverlaySupportActivity')
+ line = line.replace('extends Activity', 'extends FragmentActivity')
+ line = line.replace('R.layout.playback_controls', 'R.layout.playback_controls_support')
+ line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
+ outfile.write(line)
+file.close()
+outfile.close()
+
+file = open('res/layout/playback_controls.xml', 'r')
+outfile = open('res/layout/playback_controls_support.xml', 'w')
+for line in file:
+ line = replace_xml_head(line, "playback_controls")
+ line = line.replace('com.example.android.leanback.PlaybackOverlayFragment', 'com.example.android.leanback.PlaybackOverlaySupportFragment')
+ outfile.write(line)
+file.close()
+outfile.close()
diff --git a/samples/SupportLeanbackDemos/res/layout/browse.xml b/samples/SupportLeanbackDemos/res/layout/browse.xml
index 367337aca..ca196912c 100644
--- a/samples/SupportLeanbackDemos/res/layout/browse.xml
+++ b/samples/SupportLeanbackDemos/res/layout/browse.xml
@@ -27,4 +27,9 @@
android:layout_height="match_parent"
/>
+ <!-- container for hosting GuidedStepFragment -->
+ <FrameLayout android:id="@+id/lb_guidedstep_host"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
</FrameLayout>
diff --git a/samples/SupportLeanbackDemos/res/layout/browse_support.xml b/samples/SupportLeanbackDemos/res/layout/browse_support.xml
new file mode 100644
index 000000000..23058ad9f
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/browse_support.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from browse.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <fragment
+ android:name="com.example.android.leanback.BrowseSupportFragment"
+ android:id="@+id/main_browse_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+ <!-- container for hosting GuidedStepFragment -->
+ <FrameLayout android:id="@+id/lb_guidedstep_host"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</FrameLayout>
diff --git a/samples/SupportLeanbackDemos/res/layout/details_support.xml b/samples/SupportLeanbackDemos/res/layout/details_support.xml
new file mode 100644
index 000000000..103dc2594
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/details_support.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from details.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="com.example.android.leanback.NewDetailsSupportFragment"
+ android:id="@+id/details_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+/>
diff --git a/samples/SupportLeanbackDemos/res/layout/guided_step_activity.xml b/samples/SupportLeanbackDemos/res/layout/guided_step_activity.xml
new file mode 100644
index 000000000..a1de2135c
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/guided_step_activity.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<!-- container for hosting GuidedStepFragment -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/lb_guidedstep_host"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
diff --git a/samples/SupportLeanbackDemos/res/layout/legacy_details_support.xml b/samples/SupportLeanbackDemos/res/layout/legacy_details_support.xml
new file mode 100644
index 000000000..8146f9b1e
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/legacy_details_support.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from legacy_details.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="com.example.android.leanback.DetailsSupportFragment"
+ android:id="@+id/details_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+/>
diff --git a/samples/SupportLeanbackDemos/res/layout/playback_controls_support.xml b/samples/SupportLeanbackDemos/res/layout/playback_controls_support.xml
new file mode 100644
index 000000000..4eb293fbb
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/playback_controls_support.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from playback_controls.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <ImageView
+ android:id="@+id/media_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/bg" />
+
+ <fragment
+ android:id="@+id/playback_controls_fragment"
+ android:name="com.example.android.leanback.PlaybackOverlaySupportFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/samples/SupportLeanbackDemos/res/layout/rows_support.xml b/samples/SupportLeanbackDemos/res/layout/rows_support.xml
new file mode 100644
index 000000000..266829729
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/rows_support.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from rows.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<android.support.v17.leanback.widget.BrowseFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/rows_frame"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <fragment
+ android:name="com.example.android.leanback.RowsSupportFragment"
+ android:id="@+id/main_rows_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+ <android.support.v17.leanback.widget.TitleView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+</android.support.v17.leanback.widget.BrowseFrameLayout>
diff --git a/samples/SupportLeanbackDemos/res/layout/search_support.xml b/samples/SupportLeanbackDemos/res/layout/search_support.xml
new file mode 100644
index 000000000..1d113cb3b
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/search_support.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from search.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="com.example.android.leanback.SearchSupportFragment"
+ android:id="@+id/search_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ /> \ No newline at end of file
diff --git a/samples/SupportLeanbackDemos/res/layout/vertical_grid_support.xml b/samples/SupportLeanbackDemos/res/layout/vertical_grid_support.xml
new file mode 100644
index 000000000..3975ecc4c
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/vertical_grid_support.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is auto-generated from vertical_grid.xml. DO NOT MODIFY. -->
+
+<!--
+ 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="com.example.android.leanback.VerticalGridSupportFragment"
+ android:id="@+id/vertical_grid_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+/>
diff --git a/samples/SupportLeanbackDemos/res/values/strings.xml b/samples/SupportLeanbackDemos/res/values/strings.xml
index 125b0df64..101fd2b08 100644
--- a/samples/SupportLeanbackDemos/res/values/strings.xml
+++ b/samples/SupportLeanbackDemos/res/values/strings.xml
@@ -21,22 +21,38 @@
<string name="main_title">Activities</string>
<string name="browse">Browse</string>
<string name="browse_description">BrowseFragment test</string>
+ <string name="browse_support">Browse(support version)</string>
+ <string name="browse_support_description">BrowseSupportFragment test</string>
<string name="search">Search</string>
<string name="search_description">SearchFragment test</string>
+ <string name="search_support">Search(support version)</string>
+ <string name="search_support_description">SearchSupportFragment test</string>
<string name="details">Details</string>
<string name="details_description">DetailsFragment test</string>
+ <string name="details_support">Details(support version)</string>
+ <string name="details_support_description">DetailsSupportFragment test</string>
<string name="search_details">Search Details</string>
<string name="search_details_description">Search style DetailsFragment test</string>
+ <string name="search_details_support">Search Details(support version)</string>
+ <string name="search_details_support_description">Search style DetailsSupportFragment test</string>
<string name="playback">Playback</string>
- <string name="playback_description">PlaybackOverlay test</string>
+ <string name="playback_description">PlaybackOverlayFragment test</string>
+ <string name="playback_support">Playback(support version)</string>
+ <string name="playback_support_description">PlaybackOverlaySupportFragment test</string>
<string name="hgrid">Horizontal Grid</string>
<string name="hgrid_description">HorizontalGridView test</string>
<string name="vgrid">Vertical Grid</string>
- <string name="vgrid_description">VerticalGridView test</string>
+ <string name="vgrid_description">VerticalGridFragment test</string>
+ <string name="vgrid_support">Vertical Grid(support version)</string>
+ <string name="vgrid_support_description">VerticalGridSupportFragment test</string>
<string name="guidedstep">Guided Step</string>
<string name="guidedstep_description">GuidedStepFragment test</string>
+ <string name="guidedstepsupport">Guided Step(support version)</string>
+ <string name="guidedstepsupport_description">GuidedStepSupportFragment test</string>
<string name="browseerror">Browse Error</string>
<string name="browseerror_description">BrowseError test</string>
+ <string name="browseerror_support">Browse ErrorFragment(support version)</string>
+ <string name="browseerror_support_description">Browse ErrorSupportFragment test</string>
<string name="detail_presenter_options">Choose Presenter for Details</string>
<string name="detail_presenter_options_description">Choose Presenter for Details</string>
<string name="legacydetails_off">Use New DetailsPresenter</string>
@@ -47,9 +63,12 @@
<string name="guidedstep_first_description">First step of guided sequence</string>
<string name="guidedstep_first_breadcrumb">Guided Steps</string>
<string name="guidedstep_second_title">Second</string>
- <string name="guidedstep_second_description">Showcasing different action configurations</string>
+ <string name="guidedstep_second_description">Showcasing editable actions</string>
<string name="guidedstep_second_breadcrumb">Guided Steps</string>
<string name="guidedstep_third_title">Third</string>
- <string name="guidedstep_third_description">Third step of guided sequence</string>
+ <string name="guidedstep_third_description">Showcasing different action configurations</string>
<string name="guidedstep_third_breadcrumb">Guided Steps</string>
+ <string name="guidedstep_fourth_title">Fourth</string>
+ <string name="guidedstep_fourth_description">Fourth step of guided sequence</string>
+ <string name="guidedstep_fourth_breadcrumb">Guided Steps</string>
</resources>
diff --git a/samples/SupportLeanbackDemos/res/values/themes.xml b/samples/SupportLeanbackDemos/res/values/themes.xml
index 696d82c4b..1fdf46bf5 100644
--- a/samples/SupportLeanbackDemos/res/values/themes.xml
+++ b/samples/SupportLeanbackDemos/res/values/themes.xml
@@ -23,6 +23,8 @@
</style>
<style name="Theme.Example.Leanback.Details" parent="Theme.Leanback.Details">
</style>
+ <style name="Theme.Example.Leanback.VerticalGrid" parent="Theme.Leanback.VerticalGrid">
+ </style>
<style name="Theme.Example.Leanback.Rows" parent="Theme.Leanback">
<item name="browseTitleTextStyle">@style/Widget.Example.Leanback.Title.Text</item>
<item name="rowsVerticalGridStyle">@style/Widget.Example.Leanback.Rows.VerticalGridView</item>
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseErrorSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseErrorSupportActivity.java
new file mode 100644
index 000000000..f1e7b1e1b
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseErrorSupportActivity.java
@@ -0,0 +1,88 @@
+/* This file is auto-generated from BrowseErrorActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.Fragment;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ProgressBar;
+
+public class BrowseErrorSupportActivity extends FragmentActivity
+{
+ private ErrorSupportFragment mErrorSupportFragment;
+ private SpinnerSupportFragment mSpinnerSupportFragment;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.browse_support);
+
+ testError();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ BackgroundHelper.attach(this);
+ }
+
+ @Override
+ public void onStop() {
+ BackgroundHelper.release(this);
+ super.onStop();
+ }
+
+ private void testError() {
+ mErrorSupportFragment = new ErrorSupportFragment();
+ getSupportFragmentManager().beginTransaction().add(R.id.main_frame, mErrorSupportFragment).commit();
+
+ mSpinnerSupportFragment = new SpinnerSupportFragment();
+ getSupportFragmentManager().beginTransaction().add(R.id.main_frame, mSpinnerSupportFragment).commit();
+
+ Handler handler = new Handler();
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (getSupportFragmentManager().isDestroyed()) {
+ return;
+ }
+ getSupportFragmentManager().beginTransaction().remove(mSpinnerSupportFragment).commit();
+ mErrorSupportFragment.setErrorContent(getResources());
+ }
+ }, 3000);
+ }
+
+ static public class SpinnerSupportFragment extends Fragment {
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ ProgressBar progressBar = new ProgressBar(container.getContext());
+ if (container instanceof FrameLayout) {
+ FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(100, 100, Gravity.CENTER);
+ progressBar.setLayoutParams(layoutParams);
+ }
+ return progressBar;
+ }
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
index 0a509511d..6797dbe0c 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
@@ -17,6 +17,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ActivityOptionsCompat;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ImageCardView;
@@ -42,6 +43,10 @@ public class BrowseFragment extends android.support.v17.leanback.app.BrowseFragm
private ArrayObjectAdapter mRowsAdapter;
private BackgroundHelper mBackgroundHelper = new BackgroundHelper();
+ // For good performance, it's important to use a single instance of
+ // a card presenter for all rows using that presenter.
+ final static CardPresenter sCardPresenter = new CardPresenter();
+
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
@@ -77,17 +82,18 @@ public class BrowseFragment extends android.support.v17.leanback.app.BrowseFragm
}
});
if (TEST_ENTRANCE_TRANSITION) {
- // don't run entrance transition if Activity is restored.
+ // don't run entrance transition if fragment is restored.
if (savedInstanceState == null) {
prepareEntranceTransition();
}
- // simulate delay loading data
- new Handler().postDelayed(new Runnable() {
- public void run() {
- startEntranceTransition();
- }
- }, 2000);
}
+ // simulates in a real world use case data being loaded two seconds later
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ loadData();
+ startEntranceTransition();
+ }
+ }, 2000);
}
private void setupRows() {
@@ -100,25 +106,24 @@ public class BrowseFragment extends android.support.v17.leanback.app.BrowseFragm
mRowsAdapter = new ArrayObjectAdapter(lrp);
- // For good performance, it's important to use a single instance of
- // a card presenter for all rows using that presenter.
- final CardPresenter cardPresenter = new CardPresenter();
+ setAdapter(mRowsAdapter);
+ }
+ private void loadData() {
for (int i = 0; i < NUM_ROWS; ++i) {
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(sCardPresenter);
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
listRowAdapter.add(new PhotoItem("This is a test", "Only a test", R.drawable.gallery_photo_2));
listRowAdapter.add(new PhotoItem("Android TV", "by Google", R.drawable.gallery_photo_3));
listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_5));
- listRowAdapter.add(new PhotoItem("This is a test", "Only a test", R.drawable.gallery_photo_6));
+ listRowAdapter.add(new PhotoItem("This is a test", "Open GuidedStepFragment", R.drawable.gallery_photo_6));
listRowAdapter.add(new PhotoItem("Android TV", "open RowsActivity", R.drawable.gallery_photo_7));
listRowAdapter.add(new PhotoItem("Leanback", "open BrowseActivity", R.drawable.gallery_photo_8));
HeaderItem header = new HeaderItem(i, "Row " + i);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
- setAdapter(mRowsAdapter);
}
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@@ -128,7 +133,12 @@ public class BrowseFragment extends android.support.v17.leanback.app.BrowseFragm
Intent intent;
Bundle bundle;
- if ( ((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_8) {
+ if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_6) {
+ GuidedStepFragment.add(getFragmentManager(),
+ new GuidedStepActivity.FirstStepFragment(),
+ R.id.lb_guidedstep_host);
+ return;
+ } else if ( ((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_8) {
intent = new Intent(getActivity(), BrowseActivity.class);
bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
.toBundle();
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportActivity.java
new file mode 100644
index 000000000..0bafcc289
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportActivity.java
@@ -0,0 +1,40 @@
+/* This file is auto-generated from BrowseActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.os.Bundle;
+
+public class BrowseSupportActivity extends FragmentActivity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.browse_support);
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ BackgroundHelper.attach(this);
+ }
+
+ @Override
+ public void onStop() {
+ BackgroundHelper.release(this);
+ super.onStop();
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java
new file mode 100644
index 000000000..29851b335
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java
@@ -0,0 +1,162 @@
+/* This file is auto-generated from BrowseFragment.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.ActivityOptionsCompat;
+import android.support.v17.leanback.app.GuidedStepSupportFragment;
+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.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.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class BrowseSupportFragment extends android.support.v17.leanback.app.BrowseSupportFragment {
+ private static final String TAG = "leanback.BrowseSupportFragment";
+
+ private static final boolean TEST_ENTRANCE_TRANSITION = true;
+ private static final int NUM_ROWS = 10;
+ // Row heights default to wrap content
+ private static final boolean USE_FIXED_ROW_HEIGHT = false;
+
+ private ArrayObjectAdapter mRowsAdapter;
+ private BackgroundHelper mBackgroundHelper = new BackgroundHelper();
+
+ // For good performance, it's important to use a single instance of
+ // a card presenter for all rows using that presenter.
+ final static CardPresenter sCardPresenter = new CardPresenter();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ic_title));
+ setTitle("Leanback Sample App");
+ setHeadersState(HEADERS_ENABLED);
+
+ setOnSearchClickedListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(getActivity(), SearchSupportActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ setupRows();
+ setOnItemViewClickedListener(new ItemViewClickedListener());
+ setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+
+ if (isShowingHeaders()) {
+ mBackgroundHelper.setBackground(getActivity(), null);
+ }
+ else if (item instanceof PhotoItem) {
+ mBackgroundHelper.setBackground(
+ getActivity(), ((PhotoItem) item).getImageResourceId());
+ }
+ }
+ });
+ if (TEST_ENTRANCE_TRANSITION) {
+ // don't run entrance transition if fragment is restored.
+ if (savedInstanceState == null) {
+ prepareEntranceTransition();
+ }
+ }
+ // simulates in a real world use case data being loaded two seconds later
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ loadData();
+ startEntranceTransition();
+ }
+ }, 2000);
+ }
+
+ private void setupRows() {
+ ListRowPresenter lrp = new ListRowPresenter();
+
+ if (USE_FIXED_ROW_HEIGHT) {
+ lrp.setRowHeight(CardPresenter.getRowHeight(getActivity()));
+ lrp.setExpandedRowHeight(CardPresenter.getExpandedRowHeight(getActivity()));
+ }
+
+ mRowsAdapter = new ArrayObjectAdapter(lrp);
+
+ setAdapter(mRowsAdapter);
+ }
+
+ private void loadData() {
+ for (int i = 0; i < NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(sCardPresenter);
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ listRowAdapter.add(new PhotoItem("This is a test", "Only a test", R.drawable.gallery_photo_2));
+ listRowAdapter.add(new PhotoItem("Android TV", "by Google", R.drawable.gallery_photo_3));
+ listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_5));
+ listRowAdapter.add(new PhotoItem("This is a test", "Open GuidedStepSupportFragment", R.drawable.gallery_photo_6));
+ listRowAdapter.add(new PhotoItem("Android TV", "open RowsSupportActivity", R.drawable.gallery_photo_7));
+ listRowAdapter.add(new PhotoItem("Leanback", "open BrowseSupportActivity", R.drawable.gallery_photo_8));
+ HeaderItem header = new HeaderItem(i, "Row " + i);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+
+ }
+
+ private final class ItemViewClickedListener implements OnItemViewClickedListener {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+
+ Intent intent;
+ Bundle bundle;
+ if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_6) {
+ GuidedStepSupportFragment.add(getFragmentManager(),
+ new GuidedStepSupportActivity.FirstStepFragment(),
+ R.id.lb_guidedstep_host);
+ return;
+ } else if ( ((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_8) {
+ intent = new Intent(getActivity(), BrowseSupportActivity.class);
+ bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
+ .toBundle();
+ } else if ( ((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_7) {
+ intent = new Intent(getActivity(), RowsSupportActivity.class);
+ bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
+ .toBundle();
+ } else {
+ intent = new Intent(getActivity(), DetailsSupportActivity.class);
+ intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);
+ bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
+ getActivity(),
+ ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
+ }
+ getActivity().startActivity(intent, bundle);
+ }
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java
index f199e9d14..1ec104178 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java
@@ -21,10 +21,9 @@ public class DetailsActivity extends Activity
public static final String EXTRA_ITEM = "item";
public static final String SHARED_ELEMENT_NAME = "hero";
- public static boolean USE_LEGACY_PRESENTER = false;
-
private boolean useLegacyFragment() {
- return (USE_LEGACY_PRESENTER && !(this instanceof SearchDetailsActivity));
+ return (DetailsPresenterSelectionActivity.USE_LEGACY_PRESENTER
+ && !(this instanceof SearchDetailsActivity));
}
/** Called when the activity is first created. */
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java
index ac0b67154..9fe7fd359 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java
@@ -40,6 +40,7 @@ public class DetailsPresenterSelectionActivity extends Activity {
private static final long ACTION_ID_SWITCH_LEGACY_ON = 10000;
private static final long ACTION_ID_SWITCH_LEGACY_OFF = 10001;
+ public static boolean USE_LEGACY_PRESENTER = false;
private static final String[] OPTION_NAMES = { "Use new details presenter", "Use legacy details presenter" };
private static final String[] OPTION_DESCRIPTIONS = { "Use new details presenter",
@@ -49,7 +50,7 @@ public class DetailsPresenterSelectionActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- GuidedStepFragment.add(getFragmentManager(), new SetupFragment());
+ GuidedStepFragment.addAsRoot(this, new SetupFragment(), android.R.id.content);
}
private static void addAction(List<GuidedAction> actions, long id, String title, String desc) {
@@ -97,11 +98,11 @@ public class DetailsPresenterSelectionActivity extends Activity {
for (int i = 0; i < OPTION_NAMES.length; i++) {
boolean checked = false;
if (OPTION_IDS[i] == ACTION_ID_SWITCH_LEGACY_ON) {
- if (DetailsActivity.USE_LEGACY_PRESENTER) {
+ if (USE_LEGACY_PRESENTER) {
checked = true;
}
} else if (OPTION_IDS[i] == ACTION_ID_SWITCH_LEGACY_OFF) {
- if (!DetailsActivity.USE_LEGACY_PRESENTER) {
+ if (!USE_LEGACY_PRESENTER) {
checked = true;
}
}
@@ -113,9 +114,9 @@ public class DetailsPresenterSelectionActivity extends Activity {
@Override
public void onGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_ID_SWITCH_LEGACY_ON) {
- DetailsActivity.USE_LEGACY_PRESENTER = action.isChecked();
+ USE_LEGACY_PRESENTER = action.isChecked();
} else if (action.getId() == ACTION_ID_SWITCH_LEGACY_OFF) {
- DetailsActivity.USE_LEGACY_PRESENTER = !action.isChecked();
+ USE_LEGACY_PRESENTER = !action.isChecked();
}
getActivity().finish();
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportActivity.java
new file mode 100644
index 000000000..40c21097a
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportActivity.java
@@ -0,0 +1,61 @@
+/* This file is auto-generated from DetailsActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.os.Bundle;
+
+public class DetailsSupportActivity extends FragmentActivity
+{
+ public static final String EXTRA_ITEM = "item";
+ public static final String SHARED_ELEMENT_NAME = "hero";
+
+ private boolean useLegacyFragment() {
+ return (DetailsPresenterSelectionActivity.USE_LEGACY_PRESENTER
+ && !(this instanceof SearchDetailsSupportActivity));
+ }
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(useLegacyFragment() ? R.layout.legacy_details_support : R.layout.details_support);
+ if (savedInstanceState == null) {
+ // Only pass object to fragment when activity is first time created,
+ // later object is modified and persisted with fragment state.
+ if (useLegacyFragment()) {
+ ((DetailsSupportFragment)getSupportFragmentManager().findFragmentById(R.id.details_fragment))
+ .setItem((PhotoItem) getIntent().getParcelableExtra(EXTRA_ITEM));
+ } else {
+ ((NewDetailsSupportFragment)getSupportFragmentManager().findFragmentById(R.id.details_fragment))
+ .setItem((PhotoItem) getIntent().getParcelableExtra(EXTRA_ITEM));
+ }
+ }
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ BackgroundHelper.attach(this);
+ }
+
+ @Override
+ public void onStop() {
+ BackgroundHelper.release(this);
+ super.onStop();
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
new file mode 100644
index 000000000..143a37d51
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
@@ -0,0 +1,218 @@
+/* This file is auto-generated from DetailsFragment.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.ActivityOptionsCompat;
+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.DetailsOverviewRowPresenter;
+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.ListRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+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.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+public class DetailsSupportFragment extends android.support.v17.leanback.app.DetailsSupportFragment {
+ private static final String TAG = "leanback.DetailsSupportFragment";
+ private static final String ITEM = "item";
+
+ private static final int NUM_ROWS = 3;
+ private ArrayObjectAdapter mRowsAdapter;
+ private PhotoItem mPhotoItem;
+ final CardPresenter cardPresenter = new CardPresenter();
+ private BackgroundHelper mBackgroundHelper = new BackgroundHelper();
+
+ private static final int ACTION_PLAY = 1;
+ private static final int ACTION_RENT = 2;
+ private static final int ACTION_BUY = 3;
+
+ private static final boolean TEST_SHARED_ELEMENT_TRANSITION = true;
+ private static final boolean TEST_ENTRANCE_TRANSITION = true;
+
+ private static final long TIME_TO_LOAD_OVERVIEW_ROW_MS = 1000;
+ private static final long TIME_TO_LOAD_RELATED_ROWS_MS = 2000;
+
+ private Action mActionPlay;
+ private Action mActionRent;
+ private Action mActionBuy;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ic_title));
+ setTitle("Leanback Sample App");
+ setOnSearchClickedListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(getActivity(), SearchSupportActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ mActionPlay = new Action(ACTION_PLAY, "Play");
+ mActionRent = new Action(ACTION_RENT, "Rent", "$3.99",
+ getResources().getDrawable(R.drawable.ic_action_a));
+ mActionBuy = new Action(ACTION_BUY, "Buy $9.99");
+
+ ClassPresenterSelector ps = new ClassPresenterSelector();
+ DetailsOverviewRowPresenter dorPresenter =
+ new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
+ dorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
+ DetailsOverviewRow dor = (DetailsOverviewRow) mRowsAdapter.get(0);
+ if (action.getId() == ACTION_BUY) {
+ // on the UI thread, we can modify actions adapter directly
+ SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
+ dor.getActionsAdapter();
+ actions.set(ACTION_PLAY, mActionPlay);
+ actions.clear(ACTION_RENT);
+ actions.clear(ACTION_BUY);
+ dor.setItem(mPhotoItem.getTitle() + "(Owned)");
+ dor.setImageDrawable(getResources().getDrawable(R.drawable.details_img_16x9));
+ } else if (action.getId() == ACTION_RENT) {
+ // on the UI thread, we can modify actions adapter directly
+ SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
+ dor.getActionsAdapter();
+ actions.set(ACTION_PLAY, mActionPlay);
+ actions.clear(ACTION_RENT);
+ dor.setItem(mPhotoItem.getTitle() + "(Rented)");
+ } else if (action.getId() == ACTION_PLAY) {
+ Intent intent = new Intent(getActivity(), PlaybackOverlaySupportActivity.class);
+ getActivity().startActivity(intent);
+ }
+ }
+ });
+
+ ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter);
+ ps.addClassPresenter(ListRow.class, new ListRowPresenter());
+
+ mRowsAdapter = new ArrayObjectAdapter(ps);
+
+ PhotoItem item = (PhotoItem) (savedInstanceState != null ?
+ savedInstanceState.getParcelable(ITEM) : null);
+ if (item != null) {
+ setItem(item);
+ }
+
+ setOnItemViewClickedListener(new OnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemClicked: " + item + " row " + row);
+ if (item instanceof PhotoItem){
+ Intent intent = new Intent(getActivity(), DetailsSupportActivity.class);
+ intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);
+
+ Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
+ getActivity(),
+ ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
+ getActivity().startActivity(intent, bundle);
+ }
+ }
+ });
+ setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ }
+ });
+
+ if (TEST_SHARED_ELEMENT_TRANSITION) {
+ dorPresenter.setSharedElementEnterTransition(getActivity(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME);
+ }
+ if (TEST_ENTRANCE_TRANSITION) {
+ // don't run entrance transition if Activity is restored.
+ if (savedInstanceState == null) {
+ prepareEntranceTransition();
+ }
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putParcelable(ITEM, mPhotoItem);
+ }
+
+ public void setItem(PhotoItem photoItem) {
+ mPhotoItem = photoItem;
+
+ mRowsAdapter.clear();
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ Resources res = getActivity().getResources();
+ DetailsOverviewRow dor = new DetailsOverviewRow(mPhotoItem.getTitle());
+ dor.setImageDrawable(res.getDrawable(mPhotoItem.getImageResourceId()));
+ SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter();
+ adapter.set(ACTION_RENT, mActionRent);
+ adapter.set(ACTION_BUY, mActionBuy);
+ dor.setActionsAdapter(adapter);
+ mRowsAdapter.add(0, dor);
+ setSelectedPosition(0, false);
+ }
+ }, TIME_TO_LOAD_OVERVIEW_ROW_MS);
+
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ for (int i = 0; i < NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
+ listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3));
+ listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
+ HeaderItem header = new HeaderItem(i, "Row " + i);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+ if (TEST_ENTRANCE_TRANSITION) {
+ startEntranceTransition();
+ }
+ }
+ }, TIME_TO_LOAD_RELATED_ROWS_MS);
+ setAdapter(mRowsAdapter);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (mPhotoItem != null) {
+ mBackgroundHelper.setBackground(
+ getActivity(), mPhotoItem.getImageResourceId());
+ }
+ }
+
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/ErrorSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/ErrorSupportFragment.java
new file mode 100644
index 000000000..ea3e17c2e
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/ErrorSupportFragment.java
@@ -0,0 +1,56 @@
+/* This file is auto-generated from ErrorFragment.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+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.ListRowPresenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.SearchOrbView;
+import android.util.Log;
+import android.view.View;
+
+public class ErrorSupportFragment extends android.support.v17.leanback.app.ErrorSupportFragment {
+ private static final String TAG = "leanback.ErrorSupportFragment";
+ private static final boolean TRANSLUCENT = true;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ setTitle("Leanback Sample App");
+ }
+
+ void setErrorContent(Resources resources) {
+ setImageDrawable(resources.getDrawable(R.drawable.lb_ic_sad_cloud));
+ setMessage("An error occurred.");
+ setDefaultBackground(TRANSLUCENT);
+
+ setButtonText("Dismiss");
+ setButtonClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ Log.i(TAG, "button clicked");
+ getFragmentManager().beginTransaction().remove(ErrorSupportFragment.this).commit();
+ }
+ });
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java
index 1f9e96c8c..734ec347f 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java
@@ -20,36 +20,68 @@ import android.app.Activity;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.inputmethod.EditorInfo;
import java.util.List;
-import java.util.ArrayList;
/**
* Activity that showcases different aspects of GuidedStepFragments.
*/
public class GuidedStepActivity extends Activity {
- private static final int CONTINUE = 1;
private static final int BACK = 2;
+ private static final int FIRST_NAME = 3;
+ private static final int LAST_NAME = 4;
+ private static final int PASSWORD = 5;
+ private static final int PAYMENT = 6;
+
private static final int OPTION_CHECK_SET_ID = 10;
private static final int DEFAULT_OPTION = 0;
private static final String[] OPTION_NAMES = { "Option A", "Option B", "Option C" };
private static final String[] OPTION_DESCRIPTIONS = { "Here's one thing you can do",
"Here's another thing you can do", "Here's one more thing you can do" };
- private static final int[] OPTION_DRAWABLES = { R.drawable.ic_guidedstep_option_a,
- R.drawable.ic_guidedstep_option_b, R.drawable.ic_guidedstep_option_c };
+
+ private static final String TAG = GuidedStepActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
+ Log.v(TAG, "onCreate");
super.onCreate(savedInstanceState);
- GuidedStepFragment.add(getFragmentManager(), new FirstStepFragment());
+ setContentView(R.layout.guided_step_activity);
+ GuidedStepFragment.addAsRoot(this, new FirstStepFragment(), R.id.lb_guidedstep_host);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ Log.v(TAG, "onConfigurationChanged");
+ super.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ Log.v(TAG, "onSaveInstanceState");
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ Log.v(TAG, "onRestoreInstanceState");
+ super.onRestoreInstanceState(savedInstanceState);
}
private static void addAction(List<GuidedAction> actions, long id, String title, String desc) {
@@ -60,19 +92,60 @@ public class GuidedStepActivity extends Activity {
.build());
}
- private static void addCheckedAction(List<GuidedAction> actions, int iconResId, Context context,
- String title, String desc) {
+ private static void addEditableAction(List<GuidedAction> actions, long id, String title, String desc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .description(desc)
+ .editable(true)
+ .build());
+ }
+
+ private static void addEditableAction(List<GuidedAction> actions, long id, String title,
+ String editTitle, String desc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .editTitle(editTitle)
+ .description(desc)
+ .editable(true)
+ .build());
+ }
+
+ private static void addEditableAction(List<GuidedAction> actions, long id, String title,
+ String editTitle, int editInputType, String desc, String editDesc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .editTitle(editTitle)
+ .editInputType(editInputType)
+ .description(desc)
+ .editDescription(editDesc)
+ .editable(true)
+ .build());
+ }
+
+ private static void addEditableDescriptionAction(List<GuidedAction> actions, long id,
+ String title, String desc, String editDescription, int descriptionEditInputType) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .description(desc)
+ .editDescription(editDescription)
+ .descriptionEditInputType(descriptionEditInputType)
+ .descriptionEditable(true)
+ .build());
+ }
+
+ private static void addCheckedAction(List<GuidedAction> actions, Context context,
+ String title, String desc, int checkSetId) {
actions.add(new GuidedAction.Builder()
.title(title)
.description(desc)
- .checkSetId(OPTION_CHECK_SET_ID)
- .iconResourceId(iconResId, context)
+ .checkSetId(checkSetId)
.build());
}
- /**
- * The first fragment is instantiated via XML, so it must be public.
- */
public static class FirstStepFragment extends GuidedStepFragment {
@Override
public int onProvideTheme() {
@@ -90,24 +163,41 @@ public class GuidedStepActivity extends Activity {
@Override
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- addAction(actions, CONTINUE, "Continue", "Let's do it");
- addAction(actions, BACK, "Cancel", "Nevermind");
+ actions.add(new GuidedAction.Builder().constructContinue(getActivity())
+ .description("Let's do it")
+ .build());
+ actions.add(new GuidedAction.Builder().constructCancel(getActivity())
+ .description("Never mind")
+ .build());
}
@Override
public void onGuidedActionClicked(GuidedAction action) {
FragmentManager fm = getFragmentManager();
- if (action.getId() == CONTINUE) {
- GuidedStepFragment.add(fm, new SecondStepFragment());
- } else {
- getActivity().finish();
+ if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
+ GuidedStepFragment.add(fm, new SecondStepFragment(), R.id.lb_guidedstep_host);
+ } else if (action.getId() == GuidedAction.ACTION_ID_CANCEL){
+ finishGuidedStepFragments();
}
}
+
}
- private static class SecondStepFragment extends GuidedStepFragment {
+ public static class SecondStepFragment extends GuidedStepFragment {
- private int mSelectedOption = DEFAULT_OPTION;
+ public GuidedActionsStylist onCreateActionsStylist() {
+ return new GuidedActionsStylist() {
+ protected void setupImeOptions(GuidedActionsStylist.ViewHolder vh,
+ GuidedAction action) {
+ if (action.getId() == PASSWORD) {
+ vh.getEditableDescriptionView().setImeActionLabel("Confirm!",
+ EditorInfo.IME_ACTION_DONE);
+ } else {
+ super.setupImeOptions(vh, action);
+ }
+ }
+ };
+ }
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
@@ -119,6 +209,96 @@ public class GuidedStepActivity extends Activity {
}
@Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ addEditableAction(actions, FIRST_NAME, "Pat", "Your first name");
+ addEditableAction(actions, LAST_NAME, "Smith", "Your last name");
+ addEditableAction(actions, PAYMENT, "Payment", "", InputType.TYPE_CLASS_NUMBER,
+ "Input credit card number", "Input credit card number");
+ addEditableDescriptionAction(actions, PASSWORD, "Password", "", "",
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder().constructContinue(getActivity())
+ .description("Continue")
+ .build());
+ actions.get(actions.size() - 1).setEnabled(false);
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
+ FragmentManager fm = getFragmentManager();
+ GuidedStepFragment.add(fm, new ThirdStepFragment(), R.id.lb_guidedstep_host);
+ }
+ }
+
+ @Override
+ public long onGuidedActionEditedAndProceed(GuidedAction action) {
+ if (action.getId() == PAYMENT) {
+ CharSequence editTitle = action.getEditTitle();
+ if (TextUtils.isDigitsOnly(editTitle) && editTitle.length() == 16) {
+ editTitle = editTitle.subSequence(editTitle.length() - 4, editTitle.length());
+ action.setDescription("Visa XXXX-XXXX-XXXX-"+editTitle);
+ updateContinue(isPasswordValid());
+ return GuidedAction.ACTION_ID_NEXT;
+ } else if (editTitle.length() == 0){
+ action.setDescription("Input credit card number");
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ } else {
+ action.setDescription("Error credit card number");
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ }
+ } else if (action.getId() == PASSWORD) {
+ CharSequence password = action.getEditDescription();
+ if (password.length() > 0) {
+ if (isPaymentValid()) {
+ updateContinue(true);
+ return GuidedAction.ACTION_ID_NEXT;
+ } else {
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ }
+ } else {
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ }
+ }
+ return GuidedAction.ACTION_ID_NEXT;
+ }
+
+ boolean isPaymentValid() {
+ return findActionById(PAYMENT).getDescription().subSequence(0, 4).toString().equals("Visa");
+ }
+
+ boolean isPasswordValid() {
+ return findActionById(PASSWORD).getEditDescription().length() > 0;
+ }
+
+ void updateContinue(boolean enabled) {
+ findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(enabled);
+ notifyButtonActionChanged(findButtonActionPositionById(
+ GuidedAction.ACTION_ID_CONTINUE));
+ }
+ }
+
+ public static class ThirdStepFragment extends GuidedStepFragment {
+
+ private int mSelectedOption = DEFAULT_OPTION;
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.guidedstep_third_title);
+ String breadcrumb = getString(R.string.guidedstep_third_breadcrumb);
+ String description = getString(R.string.guidedstep_third_description);
+ Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
+ return new Guidance(title, description, breadcrumb, icon);
+ }
+
+ @Override
public GuidanceStylist onCreateGuidanceStylist() {
return new GuidanceStylist() {
@Override
@@ -137,58 +317,81 @@ public class GuidedStepActivity extends Activity {
.description(desc)
.multilineDescription(true)
.infoOnly(true)
- .enabled(false)
+ .enabled(true)
+ .focusable(false)
.build());
for (int i = 0; i < OPTION_NAMES.length; i++) {
- addCheckedAction(actions, OPTION_DRAWABLES[i], getActivity(), OPTION_NAMES[i],
- OPTION_DESCRIPTIONS[i]);
+ addCheckedAction(actions, getActivity(), OPTION_NAMES[i],
+ OPTION_DESCRIPTIONS[i], GuidedAction.DEFAULT_CHECK_SET_ID);
if (i == DEFAULT_OPTION) {
actions.get(actions.size() -1).setChecked(true);
}
}
- addAction(actions, CONTINUE, "Continue", "");
+ for (int i = 0; i < OPTION_NAMES.length; i++) {
+ addCheckedAction(actions, getActivity(), OPTION_NAMES[i],
+ OPTION_DESCRIPTIONS[i], GuidedAction.CHECKBOX_CHECK_SET_ID);
+ }
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder().constructContinue(getActivity())
+ .build());
}
@Override
public void onGuidedActionClicked(GuidedAction action) {
- if (action.getId() == CONTINUE) {
+ if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
FragmentManager fm = getFragmentManager();
- GuidedStepFragment.add(fm, new ThirdStepFragment(mSelectedOption));
- } else {
+ FourthStepFragment f = new FourthStepFragment();
+ Bundle arguments = new Bundle();
+ arguments.putInt(FourthStepFragment.EXTRA_OPTION, mSelectedOption);
+ f.setArguments(arguments);
+ GuidedStepFragment.add(fm, f, R.id.lb_guidedstep_host);
+ } else if (action.getCheckSetId() == GuidedAction.DEFAULT_CHECK_SET_ID) {
mSelectedOption = getSelectedActionPosition()-1;
}
}
}
- private static class ThirdStepFragment extends GuidedStepFragment {
- private final int mOption;
+ public static class FourthStepFragment extends GuidedStepFragment {
+ public static final String EXTRA_OPTION = "extra_option";
- public ThirdStepFragment(int option) {
- mOption = option;
+ public FourthStepFragment() {
+ }
+
+ public int getOption() {
+ Bundle b = getArguments();
+ if (b == null) return 0;
+ return b.getInt(EXTRA_OPTION, 0);
}
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title = getString(R.string.guidedstep_third_title);
- String breadcrumb = getString(R.string.guidedstep_third_breadcrumb);
- String description = "You chose: " + OPTION_NAMES[mOption];
+ String title = getString(R.string.guidedstep_fourth_title);
+ String breadcrumb = getString(R.string.guidedstep_fourth_breadcrumb);
+ String description = "You chose: " + OPTION_NAMES[getOption()];
Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
return new Guidance(title, description, breadcrumb, icon);
}
@Override
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- addAction(actions, CONTINUE, "Done", "All finished");
- addAction(actions, BACK, "Back", "Forgot something...");
+ actions.add(new GuidedAction.Builder().constructFinish(getActivity())
+ .description("All Done...")
+ .build());
+ addAction(actions, BACK, "Start Over", "Let's try this again...");
}
@Override
public void onGuidedActionClicked(GuidedAction action) {
- if (action.getId() == CONTINUE) {
- getActivity().finish();
- } else {
- getFragmentManager().popBackStack();
+ if (action.getId() == GuidedAction.ACTION_ID_FINISH) {
+ finishGuidedStepFragments();
+ } else if (action.getId() == BACK) {
+ // pop 4, 3, 2
+ popBackStackToGuidedStepFragment(SecondStepFragment.class,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
new file mode 100644
index 000000000..3975dd6bc
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
@@ -0,0 +1,402 @@
+/* This file is auto-generated from GuidedStepActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepSupportFragment;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.inputmethod.EditorInfo;
+
+import java.util.List;
+
+/**
+ * Activity that showcases different aspects of GuidedStepSupportFragments.
+ */
+public class GuidedStepSupportActivity extends FragmentActivity {
+
+ private static final int BACK = 2;
+
+ private static final int FIRST_NAME = 3;
+ private static final int LAST_NAME = 4;
+ private static final int PASSWORD = 5;
+ private static final int PAYMENT = 6;
+
+ private static final int OPTION_CHECK_SET_ID = 10;
+ private static final int DEFAULT_OPTION = 0;
+ private static final String[] OPTION_NAMES = { "Option A", "Option B", "Option C" };
+ private static final String[] OPTION_DESCRIPTIONS = { "Here's one thing you can do",
+ "Here's another thing you can do", "Here's one more thing you can do" };
+
+ private static final String TAG = GuidedStepSupportActivity.class.getSimpleName();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Log.v(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.guided_step_activity);
+ GuidedStepSupportFragment.addAsRoot(this, new FirstStepFragment(), R.id.lb_guidedstep_host);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ Log.v(TAG, "onConfigurationChanged");
+ super.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ Log.v(TAG, "onSaveInstanceState");
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ Log.v(TAG, "onRestoreInstanceState");
+ super.onRestoreInstanceState(savedInstanceState);
+ }
+
+ private static void addAction(List<GuidedAction> actions, long id, String title, String desc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .description(desc)
+ .build());
+ }
+
+ private static void addEditableAction(List<GuidedAction> actions, long id, String title, String desc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .description(desc)
+ .editable(true)
+ .build());
+ }
+
+ private static void addEditableAction(List<GuidedAction> actions, long id, String title,
+ String editTitle, String desc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .editTitle(editTitle)
+ .description(desc)
+ .editable(true)
+ .build());
+ }
+
+ private static void addEditableAction(List<GuidedAction> actions, long id, String title,
+ String editTitle, int editInputType, String desc, String editDesc) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .editTitle(editTitle)
+ .editInputType(editInputType)
+ .description(desc)
+ .editDescription(editDesc)
+ .editable(true)
+ .build());
+ }
+
+ private static void addEditableDescriptionAction(List<GuidedAction> actions, long id,
+ String title, String desc, String editDescription, int descriptionEditInputType) {
+ actions.add(new GuidedAction.Builder()
+ .id(id)
+ .title(title)
+ .description(desc)
+ .editDescription(editDescription)
+ .descriptionEditInputType(descriptionEditInputType)
+ .descriptionEditable(true)
+ .build());
+ }
+
+ private static void addCheckedAction(List<GuidedAction> actions, Context context,
+ String title, String desc, int checkSetId) {
+ actions.add(new GuidedAction.Builder()
+ .title(title)
+ .description(desc)
+ .checkSetId(checkSetId)
+ .build());
+ }
+
+ public static class FirstStepFragment extends GuidedStepSupportFragment {
+ @Override
+ public int onProvideTheme() {
+ return R.style.Theme_Example_Leanback_GuidedStep_First;
+ }
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.guidedstep_first_title);
+ String breadcrumb = getString(R.string.guidedstep_first_breadcrumb);
+ String description = getString(R.string.guidedstep_first_description);
+ Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
+ return new Guidance(title, description, breadcrumb, icon);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder().constructContinue(getActivity())
+ .description("Let's do it")
+ .build());
+ actions.add(new GuidedAction.Builder().constructCancel(getActivity())
+ .description("Never mind")
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ FragmentManager fm = getFragmentManager();
+ if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
+ GuidedStepSupportFragment.add(fm, new SecondStepFragment(), R.id.lb_guidedstep_host);
+ } else if (action.getId() == GuidedAction.ACTION_ID_CANCEL){
+ finishGuidedStepSupportFragments();
+ }
+ }
+
+ }
+
+ public static class SecondStepFragment extends GuidedStepSupportFragment {
+
+ public GuidedActionsStylist onCreateActionsStylist() {
+ return new GuidedActionsStylist() {
+ protected void setupImeOptions(GuidedActionsStylist.ViewHolder vh,
+ GuidedAction action) {
+ if (action.getId() == PASSWORD) {
+ vh.getEditableDescriptionView().setImeActionLabel("Confirm!",
+ EditorInfo.IME_ACTION_DONE);
+ } else {
+ super.setupImeOptions(vh, action);
+ }
+ }
+ };
+ }
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.guidedstep_second_title);
+ String breadcrumb = getString(R.string.guidedstep_second_breadcrumb);
+ String description = getString(R.string.guidedstep_second_description);
+ Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
+ return new Guidance(title, description, breadcrumb, icon);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ addEditableAction(actions, FIRST_NAME, "Pat", "Your first name");
+ addEditableAction(actions, LAST_NAME, "Smith", "Your last name");
+ addEditableAction(actions, PAYMENT, "Payment", "", InputType.TYPE_CLASS_NUMBER,
+ "Input credit card number", "Input credit card number");
+ addEditableDescriptionAction(actions, PASSWORD, "Password", "", "",
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder().constructContinue(getActivity())
+ .description("Continue")
+ .build());
+ actions.get(actions.size() - 1).setEnabled(false);
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
+ FragmentManager fm = getFragmentManager();
+ GuidedStepSupportFragment.add(fm, new ThirdStepFragment(), R.id.lb_guidedstep_host);
+ }
+ }
+
+ @Override
+ public long onGuidedActionEditedAndProceed(GuidedAction action) {
+ if (action.getId() == PAYMENT) {
+ CharSequence editTitle = action.getEditTitle();
+ if (TextUtils.isDigitsOnly(editTitle) && editTitle.length() == 16) {
+ editTitle = editTitle.subSequence(editTitle.length() - 4, editTitle.length());
+ action.setDescription("Visa XXXX-XXXX-XXXX-"+editTitle);
+ updateContinue(isPasswordValid());
+ return GuidedAction.ACTION_ID_NEXT;
+ } else if (editTitle.length() == 0){
+ action.setDescription("Input credit card number");
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ } else {
+ action.setDescription("Error credit card number");
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ }
+ } else if (action.getId() == PASSWORD) {
+ CharSequence password = action.getEditDescription();
+ if (password.length() > 0) {
+ if (isPaymentValid()) {
+ updateContinue(true);
+ return GuidedAction.ACTION_ID_NEXT;
+ } else {
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ }
+ } else {
+ updateContinue(false);
+ return GuidedAction.ACTION_ID_CURRENT;
+ }
+ }
+ return GuidedAction.ACTION_ID_NEXT;
+ }
+
+ boolean isPaymentValid() {
+ return findActionById(PAYMENT).getDescription().subSequence(0, 4).toString().equals("Visa");
+ }
+
+ boolean isPasswordValid() {
+ return findActionById(PASSWORD).getEditDescription().length() > 0;
+ }
+
+ void updateContinue(boolean enabled) {
+ findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(enabled);
+ notifyButtonActionChanged(findButtonActionPositionById(
+ GuidedAction.ACTION_ID_CONTINUE));
+ }
+ }
+
+ public static class ThirdStepFragment extends GuidedStepSupportFragment {
+
+ private int mSelectedOption = DEFAULT_OPTION;
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.guidedstep_third_title);
+ String breadcrumb = getString(R.string.guidedstep_third_breadcrumb);
+ String description = getString(R.string.guidedstep_third_description);
+ Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
+ return new Guidance(title, description, breadcrumb, icon);
+ }
+
+ @Override
+ public GuidanceStylist onCreateGuidanceStylist() {
+ return new GuidanceStylist() {
+ @Override
+ public int onProvideLayoutId() {
+ return R.layout.guidedstep_second_guidance;
+ }
+ };
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ String desc = "The description can be quite long as well. ";
+ desc += "Just be sure to set multilineDescription to true in the GuidedAction.";
+ actions.add(new GuidedAction.Builder()
+ .title("Note that Guided Actions can have titles that are quite long.")
+ .description(desc)
+ .multilineDescription(true)
+ .infoOnly(true)
+ .enabled(true)
+ .focusable(false)
+ .build());
+ for (int i = 0; i < OPTION_NAMES.length; i++) {
+ addCheckedAction(actions, getActivity(), OPTION_NAMES[i],
+ OPTION_DESCRIPTIONS[i], GuidedAction.DEFAULT_CHECK_SET_ID);
+ if (i == DEFAULT_OPTION) {
+ actions.get(actions.size() -1).setChecked(true);
+ }
+ }
+ for (int i = 0; i < OPTION_NAMES.length; i++) {
+ addCheckedAction(actions, getActivity(), OPTION_NAMES[i],
+ OPTION_DESCRIPTIONS[i], GuidedAction.CHECKBOX_CHECK_SET_ID);
+ }
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder().constructContinue(getActivity())
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
+ FragmentManager fm = getFragmentManager();
+ FourthStepFragment f = new FourthStepFragment();
+ Bundle arguments = new Bundle();
+ arguments.putInt(FourthStepFragment.EXTRA_OPTION, mSelectedOption);
+ f.setArguments(arguments);
+ GuidedStepSupportFragment.add(fm, f, R.id.lb_guidedstep_host);
+ } else if (action.getCheckSetId() == GuidedAction.DEFAULT_CHECK_SET_ID) {
+ mSelectedOption = getSelectedActionPosition()-1;
+ }
+ }
+
+ }
+
+ public static class FourthStepFragment extends GuidedStepSupportFragment {
+ public static final String EXTRA_OPTION = "extra_option";
+
+ public FourthStepFragment() {
+ }
+
+ public int getOption() {
+ Bundle b = getArguments();
+ if (b == null) return 0;
+ return b.getInt(EXTRA_OPTION, 0);
+ }
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.guidedstep_fourth_title);
+ String breadcrumb = getString(R.string.guidedstep_fourth_breadcrumb);
+ String description = "You chose: " + OPTION_NAMES[getOption()];
+ Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
+ return new Guidance(title, description, breadcrumb, icon);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder().constructFinish(getActivity())
+ .description("All Done...")
+ .build());
+ addAction(actions, BACK, "Start Over", "Let's try this again...");
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (action.getId() == GuidedAction.ACTION_ID_FINISH) {
+ finishGuidedStepSupportFragments();
+ } else if (action.getId() == BACK) {
+ // pop 4, 3, 2
+ popBackStackToGuidedStepSupportFragment(SecondStepFragment.class,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
+ }
+ }
+
+ }
+
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
index c1b60f41c..711031664 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.support.v4.app.ActivityOptionsCompat;
import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidedAction;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
@@ -39,7 +40,8 @@ public class MainActivity extends Activity {
super.onCreate(savedInstanceState);
mGuidedStepFragment = new StepFragment();
- GuidedStepFragment.add(getFragmentManager(), mGuidedStepFragment);
+ GuidedStepFragment.addAsRoot(this, mGuidedStepFragment, android.R.id.content);
+
}
public static class StepFragment extends GuidedStepFragment {
@@ -55,24 +57,42 @@ public class MainActivity extends Activity {
@Override
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
addAction(actions, BrowseActivity.class, R.string.browse, R.string.browse_description);
+ addAction(actions, BrowseSupportActivity.class, R.string.browse_support,
+ R.string.browse_support_description);
addAction(actions, SearchActivity.class, R.string.search, R.string.search_description);
+ addAction(actions, SearchSupportActivity.class, R.string.search_support, R.string.search_support_description);
addAction(actions, DetailsActivity.class, R.string.details, R.string.details_description);
actions.get(actions.size()-1).getIntent().putExtra(DetailsActivity.EXTRA_ITEM,
new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ addAction(actions, DetailsSupportActivity.class, R.string.details_support, R.string.details_support_description);
+ actions.get(actions.size()-1).getIntent().putExtra(DetailsSupportActivity.EXTRA_ITEM,
+ new PhotoItem("Hello world", R.drawable.gallery_photo_1));
addAction(actions, SearchDetailsActivity.class, R.string.search_details,
R.string.search_details_description);
- actions.get(actions.size()-1).getIntent().putExtra(DetailsActivity.EXTRA_ITEM,
+ actions.get(actions.size()-1).getIntent().putExtra(SearchDetailsActivity.EXTRA_ITEM,
+ new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ addAction(actions, SearchDetailsSupportActivity.class, R.string.search_details_support,
+ R.string.search_details_support_description);
+ actions.get(actions.size()-1).getIntent().putExtra(SearchDetailsSupportActivity.EXTRA_ITEM,
new PhotoItem("Hello world", R.drawable.gallery_photo_1));
- addAction(actions, PlaybackOverlayActivity.class, R.string.playback,
- R.string.playback_description);
- addAction(actions, HorizontalGridTestActivity.class, R.string.hgrid,
- R.string.hgrid_description);
addAction(actions, VerticalGridActivity.class, R.string.vgrid,
R.string.vgrid_description);
+ addAction(actions, VerticalGridSupportActivity.class, R.string.vgrid_support,
+ R.string.vgrid_support_description);
addAction(actions, GuidedStepActivity.class, R.string.guidedstep,
R.string.guidedstep_description);
+ addAction(actions, GuidedStepSupportActivity.class, R.string.guidedstepsupport,
+ R.string.guidedstepsupport_description);
addAction(actions, BrowseErrorActivity.class, R.string.browseerror,
R.string.browseerror_description);
+ addAction(actions, BrowseErrorSupportActivity.class, R.string.browseerror_support,
+ R.string.browseerror_support_description);
+ addAction(actions, PlaybackOverlayActivity.class, R.string.playback,
+ R.string.playback_description);
+ addAction(actions, PlaybackOverlaySupportActivity.class, R.string.playback_support,
+ R.string.playback_support_description);
+ addAction(actions, HorizontalGridTestActivity.class, R.string.hgrid,
+ R.string.hgrid_description);
addAction(actions, DetailsPresenterSelectionActivity.class,
R.string.detail_presenter_options,
R.string.detail_presenter_options_description);
@@ -90,7 +110,9 @@ public class MainActivity extends Activity {
public void onGuidedActionClicked(GuidedAction action) {
Intent intent = action.getIntent();
if (intent != null) {
- startActivity(intent);
+ Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
+ .toBundle();
+ startActivity(intent, bundle);
}
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
index 445e1486e..4d04502b5 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
@@ -68,8 +68,7 @@ public class NewDetailsFragment extends android.support.v17.leanback.app.Details
private FullWidthDetailsOverviewSharedElementHelper mHelper;
private void initializeTest() {
- Activity activity = getActivity();
- TEST_SHARED_ELEMENT_TRANSITION = null != activity.getWindow().getSharedElementEnterTransition();
+ TEST_SHARED_ELEMENT_TRANSITION = null != getActivity().getWindow().getSharedElementEnterTransition();
TEST_OVERVIEW_ROW_ON_SECOND = !TEST_SHARED_ELEMENT_TRANSITION;
TEST_ENTRANCE_TRANSITION = true;
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
new file mode 100644
index 000000000..8a43d8b79
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
@@ -0,0 +1,255 @@
+/* This file is auto-generated from NewDetailsFragment.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.ActivityOptionsCompat;
+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.FullWidthDetailsOverviewSharedElementHelper;
+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.ListRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+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.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+public class NewDetailsSupportFragment extends android.support.v17.leanback.app.DetailsSupportFragment {
+ private static final String TAG = "leanback.DetailsSupportFragment";
+ private static final String ITEM = "item";
+
+ private static final int NUM_ROWS = 3;
+ private ArrayObjectAdapter mRowsAdapter;
+ private PhotoItem mPhotoItem;
+ final CardPresenter cardPresenter = new CardPresenter();
+ private BackgroundHelper mBackgroundHelper = new BackgroundHelper();
+
+ private static final int ACTION_PLAY = 1;
+ private static final int ACTION_RENT = 2;
+ private static final int ACTION_BUY = 3;
+
+ private boolean TEST_OVERVIEW_ROW_ON_SECOND;
+ private boolean TEST_SHARED_ELEMENT_TRANSITION;
+ private boolean TEST_ENTRANCE_TRANSITION;
+
+ private static final long TIME_TO_LOAD_OVERVIEW_ROW_MS = 1000;
+ private static final long TIME_TO_LOAD_RELATED_ROWS_MS = 2000;
+
+ private Action mActionPlay;
+ private Action mActionRent;
+ private Action mActionBuy;
+
+ private FullWidthDetailsOverviewSharedElementHelper mHelper;
+
+ private void initializeTest() {
+ TEST_SHARED_ELEMENT_TRANSITION = null != getActivity().getWindow().getSharedElementEnterTransition();
+ TEST_OVERVIEW_ROW_ON_SECOND = !TEST_SHARED_ELEMENT_TRANSITION;
+ TEST_ENTRANCE_TRANSITION = true;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ initializeTest();
+
+ setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ic_title));
+ setTitle("Leanback Sample App");
+ setOnSearchClickedListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(getActivity(), SearchSupportActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ mActionPlay = new Action(ACTION_PLAY, "Play");
+ mActionRent = new Action(ACTION_RENT, "Rent", "$3.99",
+ getResources().getDrawable(R.drawable.ic_action_a));
+ mActionBuy = new Action(ACTION_BUY, "Buy $9.99");
+
+ ClassPresenterSelector ps = new ClassPresenterSelector();
+ FullWidthDetailsOverviewRowPresenter dorPresenter =
+ new FullWidthDetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
+ dorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
+ int indexOfOverviewRow = TEST_OVERVIEW_ROW_ON_SECOND ? 1 : 0;
+ DetailsOverviewRow dor = (DetailsOverviewRow) mRowsAdapter.get(indexOfOverviewRow);
+ if (action.getId() == ACTION_BUY) {
+ // on the UI thread, we can modify actions adapter directly
+ SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
+ dor.getActionsAdapter();
+ actions.set(ACTION_PLAY, mActionPlay);
+ actions.clear(ACTION_RENT);
+ actions.clear(ACTION_BUY);
+ dor.setItem(mPhotoItem.getTitle() + "(Owned)");
+ dor.setImageDrawable(getResources().getDrawable(R.drawable.details_img_16x9));
+ } else if (action.getId() == ACTION_RENT) {
+ // on the UI thread, we can modify actions adapter directly
+ SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
+ dor.getActionsAdapter();
+ actions.set(ACTION_PLAY, mActionPlay);
+ actions.clear(ACTION_RENT);
+ dor.setItem(mPhotoItem.getTitle() + "(Rented)");
+ } else if (action.getId() == ACTION_PLAY) {
+ Intent intent = new Intent(getActivity(), PlaybackOverlaySupportActivity.class);
+ getActivity().startActivity(intent);
+ }
+ }
+ });
+ if (TEST_OVERVIEW_ROW_ON_SECOND) {
+ dorPresenter.setInitialState(FullWidthDetailsOverviewRowPresenter.STATE_SMALL);
+ }
+
+ ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter);
+ ps.addClassPresenter(ListRow.class, new ListRowPresenter());
+
+ mRowsAdapter = new ArrayObjectAdapter(ps);
+
+ PhotoItem item = (PhotoItem) (savedInstanceState != null ?
+ savedInstanceState.getParcelable(ITEM) : null);
+ if (item != null) {
+ setItem(item);
+ }
+
+ setOnItemViewClickedListener(new OnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemClicked: " + item + " row " + row);
+ if (item instanceof PhotoItem){
+ Intent intent = new Intent(getActivity(), DetailsSupportActivity.class);
+ intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);
+
+ Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
+ getActivity(),
+ ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
+ getActivity().startActivity(intent, bundle);
+ }
+ }
+ });
+ setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ }
+ });
+
+ if (TEST_SHARED_ELEMENT_TRANSITION) {
+ mHelper = new FullWidthDetailsOverviewSharedElementHelper();
+ mHelper.setSharedElementEnterTransition(getActivity(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME);
+ dorPresenter.setListener(mHelper);
+ dorPresenter.setParticipatingEntranceTransition(false);
+ } else {
+ dorPresenter.setParticipatingEntranceTransition(true);
+ }
+ if (TEST_ENTRANCE_TRANSITION) {
+ // don't run entrance transition if Activity is restored.
+ if (savedInstanceState == null) {
+ prepareEntranceTransition();
+ }
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putParcelable(ITEM, mPhotoItem);
+ }
+
+ public void setItem(PhotoItem photoItem) {
+ mPhotoItem = photoItem;
+
+ mRowsAdapter.clear();
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ if (TEST_OVERVIEW_ROW_ON_SECOND) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
+ listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3));
+ listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
+ HeaderItem header = new HeaderItem(0, "Search Result");
+ mRowsAdapter.add(0, new ListRow(header, listRowAdapter));
+ }
+
+ Resources res = getActivity().getResources();
+ DetailsOverviewRow dor = new DetailsOverviewRow(mPhotoItem.getTitle());
+ dor.setImageDrawable(res.getDrawable(mPhotoItem.getImageResourceId()));
+ SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter();
+ adapter.set(ACTION_RENT, mActionRent);
+ adapter.set(ACTION_BUY, mActionBuy);
+ dor.setActionsAdapter(adapter);
+ int indexOfOverviewRow = TEST_OVERVIEW_ROW_ON_SECOND ? 1 : 0;
+ mRowsAdapter.add(indexOfOverviewRow, dor);
+ setSelectedPosition(0, true);
+ if (TEST_SHARED_ELEMENT_TRANSITION) {
+ if (mHelper != null && !mHelper.getAutoStartSharedElementTransition()) {
+ mHelper.startPostponedEnterTransition();
+ }
+ }
+ }
+ }, TIME_TO_LOAD_OVERVIEW_ROW_MS);
+
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ for (int i = 0; i < NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
+ listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3));
+ listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
+ HeaderItem header = new HeaderItem(i, "Row " + i);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+ if (TEST_ENTRANCE_TRANSITION) {
+ startEntranceTransition();
+ }
+ }
+ }, TIME_TO_LOAD_RELATED_ROWS_MS);
+ setAdapter(mRowsAdapter);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (mPhotoItem != null) {
+ mBackgroundHelper.setBackground(
+ getActivity(), mPhotoItem.getImageResourceId());
+ }
+ }
+
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java
new file mode 100644
index 000000000..b857e17c7
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java
@@ -0,0 +1,280 @@
+/* This file is auto-generated from PlaybackControlHelper.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.support.v17.leanback.app.PlaybackControlSupportGlue;
+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.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Toast;
+
+abstract class PlaybackControlSupportHelper extends PlaybackControlSupportGlue {
+ /**
+ * Change the location of the thumbs up/down controls
+ */
+ private static final boolean THUMBS_PRIMARY = true;
+
+ private static final String FAUX_TITLE = "A short song of silence";
+ private static final String FAUX_SUBTITLE = "2014";
+ private static final int FAUX_DURATION = 33 * 1000;
+
+ // These should match the playback service FF behavior
+ private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
+
+ private boolean mIsPlaying;
+ private int mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
+ private long mStartTime;
+ private long mStartPosition = 0;
+
+ private PlaybackControlsRow.RepeatAction mRepeatAction;
+ private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
+ private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
+
+ private Handler mHandler = new Handler();
+ private final Runnable mUpdateProgressRunnable = new Runnable() {
+ @Override
+ public void run() {
+ updateProgress();
+ mHandler.postDelayed(this, getUpdatePeriod());
+ }
+ };
+
+ public PlaybackControlSupportHelper(Context context, PlaybackOverlaySupportFragment fragment) {
+ super(context, fragment, sFastForwardSpeeds);
+ mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
+ mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.OUTLINE);
+ mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
+ mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.OUTLINE);
+ mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
+ }
+
+ @Override
+ public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
+ PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
+
+ ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
+ getControlsRow().setSecondaryActionsAdapter(adapter);
+ if (!THUMBS_PRIMARY) {
+ adapter.add(mThumbsDownAction);
+ }
+ adapter.add(mRepeatAction);
+ if (!THUMBS_PRIMARY) {
+ adapter.add(mThumbsUpAction);
+ }
+
+ return presenter;
+ }
+
+ @Override
+ protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
+ PresenterSelector presenterSelector) {
+ SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
+ if (THUMBS_PRIMARY) {
+ adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
+ adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
+ }
+ return adapter;
+ }
+
+ @Override
+ public void onActionClicked(Action action) {
+ if (shouldDispatchAction(action)) {
+ dispatchAction(action);
+ return;
+ }
+ super.onActionClicked(action);
+ }
+
+ @Override
+ public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
+ if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+ Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
+ if (shouldDispatchAction(action)) {
+ dispatchAction(action);
+ return true;
+ }
+ }
+ return super.onKey(view, keyCode, keyEvent);
+ }
+
+ private boolean shouldDispatchAction(Action action) {
+ return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
+ }
+
+ private void dispatchAction(Action action) {
+ Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
+ PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
+ multiAction.nextIndex();
+ notifyActionChanged(multiAction);
+ }
+
+ private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
+ int index;
+ index = getPrimaryActionsAdapter().indexOf(action);
+ if (index >= 0) {
+ getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
+ } else {
+ index = getSecondaryActionsAdapter().indexOf(action);
+ if (index >= 0) {
+ getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
+ }
+ }
+ }
+
+ private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
+ return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
+ }
+
+ private ArrayObjectAdapter getSecondaryActionsAdapter() {
+ return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
+ }
+
+ @Override
+ public boolean hasValidMedia() {
+ return true;
+ }
+
+ @Override
+ public boolean isMediaPlaying() {
+ return mIsPlaying;
+ }
+
+ @Override
+ public CharSequence getMediaTitle() {
+ return FAUX_TITLE;
+ }
+
+ @Override
+ public CharSequence getMediaSubtitle() {
+ return FAUX_SUBTITLE;
+ }
+
+ @Override
+ public int getMediaDuration() {
+ return FAUX_DURATION;
+ }
+
+ @Override
+ public Drawable getMediaArt() {
+ return null;
+ }
+
+ @Override
+ public long getSupportedActions() {
+ return PlaybackControlSupportGlue.ACTION_PLAY_PAUSE |
+ PlaybackControlSupportGlue.ACTION_FAST_FORWARD |
+ PlaybackControlSupportGlue.ACTION_REWIND;
+ }
+
+ @Override
+ public int getCurrentSpeedId() {
+ return mSpeed;
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ int speed;
+ if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
+ speed = 0;
+ } else if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL) {
+ speed = 1;
+ } else if (mSpeed >= PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
+ int index = mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
+ speed = getFastForwardSpeeds()[index];
+ } else if (mSpeed <= -PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
+ int index = -mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
+ speed = -getRewindSpeeds()[index];
+ } else {
+ return -1;
+ }
+ long position = mStartPosition +
+ (System.currentTimeMillis() - mStartTime) * speed;
+ if (position > getMediaDuration()) {
+ position = getMediaDuration();
+ onPlaybackComplete(true);
+ } else if (position < 0) {
+ position = 0;
+ onPlaybackComplete(false);
+ }
+ return (int) position;
+ }
+
+ void onPlaybackComplete(final boolean ended) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.NONE) {
+ pausePlayback();
+ } else {
+ startPlayback(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL);
+ }
+ mStartPosition = 0;
+ onStateChanged();
+ }
+ });
+ }
+
+ @Override
+ protected void startPlayback(int speed) {
+ if (speed == mSpeed) {
+ return;
+ }
+ mStartPosition = getCurrentPosition();
+ mSpeed = speed;
+ mIsPlaying = true;
+ mStartTime = System.currentTimeMillis();
+ }
+
+ @Override
+ protected void pausePlayback() {
+ if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
+ return;
+ }
+ mStartPosition = getCurrentPosition();
+ mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
+ mIsPlaying = false;
+ }
+
+ @Override
+ protected void skipToNext() {
+ // Not supported
+ }
+
+ @Override
+ protected void skipToPrevious() {
+ // Not supported
+ }
+
+ @Override
+ public void enableProgressUpdating(boolean enable) {
+ mHandler.removeCallbacks(mUpdateProgressRunnable);
+ if (enable) {
+ mUpdateProgressRunnable.run();
+ }
+ }
+}; \ No newline at end of file
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
index 0cb981ad8..6658c67f7 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
@@ -37,6 +37,9 @@ import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
import android.widget.Toast;
public class PlaybackOverlayFragment extends android.support.v17.leanback.app.PlaybackOverlayFragment {
@@ -102,7 +105,7 @@ public class PlaybackOverlayFragment extends android.support.v17.leanback.app.Pl
@Override
public int getUpdatePeriod() {
int totalTime = getControlsRow().getTotalTime();
- if (getView() == null || totalTime <= 0) {
+ if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
return 1000;
}
return Math.max(16, totalTime / getView().getWidth());
@@ -149,11 +152,13 @@ public class PlaybackOverlayFragment extends android.support.v17.leanback.app.Pl
HeaderItem header = new HeaderItem(i, "Row " + i);
getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
}
+
}
@Override
public void onStart() {
super.onStart();
+ mGlue.setFadingEnabled(true);
mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying());
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java
new file mode 100644
index 000000000..a2f5e5a00
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java
@@ -0,0 +1,30 @@
+/* This file is auto-generated from PlaybackOverlayActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.os.Bundle;
+
+public class PlaybackOverlaySupportActivity extends FragmentActivity
+{
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.playback_controls_support);
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
new file mode 100644
index 000000000..0a93027a6
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
@@ -0,0 +1,172 @@
+/* This file is auto-generated from PlaybackOverlayFragment.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v17.leanback.app.PlaybackControlGlue;
+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.PlaybackControlsRow.RepeatAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnItemViewSelectedListener;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+public class PlaybackOverlaySupportFragment extends android.support.v17.leanback.app.PlaybackOverlaySupportFragment {
+ private static final String TAG = "leanback.PlaybackControlsFragment";
+
+ /**
+ * Change this to choose a different overlay background.
+ */
+ private static final int BACKGROUND_TYPE = PlaybackOverlaySupportFragment.BG_LIGHT;
+
+ /**
+ * Change the number of related content rows.
+ */
+ private static final int RELATED_CONTENT_ROWS = 3;
+
+ /**
+ * Change this to select hidden
+ */
+ private static final boolean SECONDARY_HIDDEN = false;
+
+ private static final int ROW_CONTROLS = 0;
+
+ private PlaybackControlSupportHelper mGlue;
+ private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
+ private ListRowPresenter mListRowPresenter;
+
+ private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemClicked: " + item + " row " + row);
+ if (item instanceof Action) {
+ mGlue.onActionClicked((Action) item);
+ }
+ }
+ };
+
+ private OnItemViewSelectedListener mOnItemViewSelectedListener = new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ }
+ };
+
+ public SparseArrayObjectAdapter getAdapter() {
+ return (SparseArrayObjectAdapter) super.getAdapter();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ setBackgroundType(BACKGROUND_TYPE);
+ setOnItemViewSelectedListener(mOnItemViewSelectedListener);
+
+ createComponents(getActivity());
+ }
+
+ private void createComponents(Context context) {
+ mGlue = new PlaybackControlSupportHelper(context, this) {
+ @Override
+ public int getUpdatePeriod() {
+ int totalTime = getControlsRow().getTotalTime();
+ if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
+ return 1000;
+ }
+ return Math.max(16, totalTime / getView().getWidth());
+ }
+
+ @Override
+ protected void onRowChanged(PlaybackControlsRow row) {
+ if (getAdapter() == null) {
+ return;
+ }
+ int index = getAdapter().indexOf(row);
+ if (index >= 0) {
+ getAdapter().notifyArrayItemRangeChanged(index, 1);
+ }
+ }
+ };
+
+ mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
+
+ mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
+ mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
+ mListRowPresenter = new ListRowPresenter();
+
+ setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
+ @Override
+ public Presenter getPresenter(Object object) {
+ if (object instanceof PlaybackControlsRow) {
+ return mPlaybackControlsRowPresenter;
+ } else if (object instanceof ListRow) {
+ return mListRowPresenter;
+ }
+ throw new IllegalArgumentException("Unhandled object: " + object);
+ }
+ }));
+
+ // Add the controls row
+ getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+
+ // Add related content rows
+ for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
+ listRowAdapter.add("Some related content");
+ listRowAdapter.add("Other related content");
+ HeaderItem header = new HeaderItem(i, "Row " + i);
+ getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
+ }
+
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mGlue.setFadingEnabled(true);
+ mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying());
+ }
+
+ @Override
+ public void onStop() {
+ mGlue.enableProgressUpdating(false);
+ super.onStop();
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportActivity.java
new file mode 100644
index 000000000..ca4d0e144
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportActivity.java
@@ -0,0 +1,60 @@
+/* This file is auto-generated from RowsActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v17.leanback.R;
+import android.support.v17.leanback.widget.BrowseFrameLayout;
+import android.support.v17.leanback.widget.TitleHelper;
+import android.support.v17.leanback.widget.TitleView;
+import android.view.View;
+
+public class RowsSupportActivity extends FragmentActivity
+{
+ private RowsSupportFragment mRowsSupportFragment;
+ private TitleHelper mTitleHelper;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.rows_support);
+
+ mRowsSupportFragment = (RowsSupportFragment) getSupportFragmentManager().findFragmentById(
+ R.id.main_rows_fragment);
+
+ setupTitleFragment();
+ }
+
+ private void setupTitleFragment() {
+ TitleView titleView = (TitleView) findViewById(R.id.title);
+ titleView.setTitle("RowsSupportFragment");
+ titleView.setOnSearchClickedListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(RowsSupportActivity.this, SearchSupportActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ BrowseFrameLayout frameLayout = (BrowseFrameLayout) findViewById(R.id.rows_frame);
+ mTitleHelper = new TitleHelper(frameLayout, titleView);
+ frameLayout.setOnFocusSearchListener(mTitleHelper.getOnFocusSearchListener());
+ mRowsSupportFragment.setTitleHelper(mTitleHelper);
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportFragment.java
new file mode 100644
index 000000000..e0a14031f
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/RowsSupportFragment.java
@@ -0,0 +1,120 @@
+/* This file is auto-generated from RowsFragment.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.TitleHelper;
+import android.support.v17.leanback.widget.TitleView;
+import android.support.v4.app.ActivityOptionsCompat;
+import android.support.v17.leanback.R;
+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.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.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class RowsSupportFragment extends android.support.v17.leanback.app.RowsSupportFragment {
+
+ private static final String TAG = "leanback.RowsSupportFragment";
+
+ private static final int NUM_ROWS = 10;
+ // Row heights default to wrap content
+ private static final boolean USE_FIXED_ROW_HEIGHT = false;
+
+ private ArrayObjectAdapter mRowsAdapter;
+ private TitleHelper mTitleHelper;
+
+ public void setTitleHelper(TitleHelper titleHelper) {
+ mTitleHelper = titleHelper;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ setupRows();
+ setOnItemViewClickedListener(new ItemViewClickedListener());
+ setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ if (mTitleHelper != null) {
+ mTitleHelper.showTitle(getAdapter() == null || getAdapter().size() == 0 ||
+ getAdapter().get(0) == row);
+ }
+ }
+ });
+ }
+
+ private void setupRows() {
+ ListRowPresenter lrp = new ListRowPresenter();
+
+ if (USE_FIXED_ROW_HEIGHT) {
+ lrp.setRowHeight(CardPresenter.getRowHeight(getActivity()));
+ lrp.setExpandedRowHeight(CardPresenter.getExpandedRowHeight(getActivity()));
+ }
+
+ mRowsAdapter = new ArrayObjectAdapter(lrp);
+
+ // For good performance, it's important to use a single instance of
+ // a card presenter for all rows using that presenter.
+ final CardPresenter cardPresenter = new CardPresenter();
+
+ for (int i = 0; i < NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
+ listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3));
+ listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_5));
+ listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_6));
+ listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_7));
+ listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_8));
+ HeaderItem header = new HeaderItem(i, "Row " + i);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+
+ setAdapter(mRowsAdapter);
+ }
+
+ private final class ItemViewClickedListener implements OnItemViewClickedListener {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Intent intent = new Intent(getActivity(), DetailsSupportActivity.class);
+ intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);
+
+ Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
+ getActivity(),
+ ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
+ getActivity().startActivity(intent, bundle);
+ }
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchDetailsSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchDetailsSupportActivity.java
new file mode 100644
index 000000000..c1d59b20c
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchDetailsSupportActivity.java
@@ -0,0 +1,23 @@
+/* This file is auto-generated from SearchDetailsActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+/**
+ * Same implementation as DetailsSupportActivity for different entries in AndroidManifest.
+ */
+public class SearchDetailsSupportActivity extends DetailsSupportActivity
+{
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportActivity.java
new file mode 100644
index 000000000..9ecdafedf
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportActivity.java
@@ -0,0 +1,67 @@
+/* This file is auto-generated from SearchActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v17.leanback.app.SearchSupportFragment;
+import android.support.v17.leanback.widget.SpeechRecognitionCallback;
+import android.util.Log;
+
+public class SearchSupportActivity extends FragmentActivity
+{
+ private static final String TAG = "SearchSupportActivity";
+ private static boolean DEBUG = true;
+
+ /** If using internal speech recognizer, you must have RECORD_AUDIO permission */
+ private static boolean USE_INTERNAL_SPEECH_RECOGNIZER = false;
+ private static final int REQUEST_SPEECH = 1;
+
+ private SearchSupportFragment mFragment;
+ private SpeechRecognitionCallback mSpeechRecognitionCallback;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.search_support);
+
+ mFragment = (SearchSupportFragment) getSupportFragmentManager().findFragmentById(R.id.search_fragment);
+
+ if (!USE_INTERNAL_SPEECH_RECOGNIZER) {
+ mSpeechRecognitionCallback = new SpeechRecognitionCallback() {
+ @Override
+ public void recognizeSpeech() {
+ if (DEBUG) Log.v(TAG, "recognizeSpeech");
+ startActivityForResult(mFragment.getRecognizerIntent(), REQUEST_SPEECH);
+ }
+ };
+ mFragment.setSpeechRecognitionCallback(mSpeechRecognitionCallback);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (DEBUG) Log.v(TAG, "onActivityResult requestCode=" + requestCode +
+ " resultCode=" + resultCode +
+ " data=" + data);
+ if (requestCode == REQUEST_SPEECH && resultCode == RESULT_OK) {
+ mFragment.setSearchQuery(data, true);
+ }
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
new file mode 100644
index 000000000..35c5eb251
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
@@ -0,0 +1,104 @@
+/* This file is auto-generated from SearchFragment.java. DO NOT MODIFY. */
+
+package com.example.android.leanback;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.ActivityOptionsCompat;
+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.ListRowPresenter;
+import android.support.v17.leanback.widget.ObjectAdapter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.text.TextUtils;
+import android.util.Log;
+
+public class SearchSupportFragment extends android.support.v17.leanback.app.SearchSupportFragment
+ implements android.support.v17.leanback.app.SearchSupportFragment.SearchResultProvider {
+ private static final String TAG = "leanback.SearchSupportFragment";
+ private static final int NUM_ROWS = 3;
+ private static final int SEARCH_DELAY_MS = 1000;
+
+ private ArrayObjectAdapter mRowsAdapter;
+ private Handler mHandler = new Handler();
+ private String mQuery;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+ setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ic_title));
+ setTitle("Leanback Sample App");
+ setSearchResultProvider(this);
+ setOnItemViewClickedListener(new ItemViewClickedListener());
+ }
+
+ @Override
+ public ObjectAdapter getResultsAdapter() {
+ return mRowsAdapter;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newQuery) {
+ Log.i(TAG, String.format("Search Query Text Change %s", newQuery));
+ mRowsAdapter.clear();
+ loadQuery(newQuery);
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ Log.i(TAG, String.format("Search Query Text Submit %s", query));
+ mRowsAdapter.clear();
+ loadQuery(query);
+ return true;
+ }
+
+ private void loadQuery(String query) {
+ mQuery = query;
+ mHandler.removeCallbacks(mDelayedLoad);
+ if (!TextUtils.isEmpty(query) && !query.equals("nil")) {
+ mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+ }
+ }
+
+ private void loadRows() {
+ for (int i = 0; i < NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
+ listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
+ listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
+ HeaderItem header = new HeaderItem(i, mQuery + " results row " + i);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+ }
+
+ private Runnable mDelayedLoad = new Runnable() {
+ @Override
+ public void run() {
+ loadRows();
+ }
+ };
+
+ private final class ItemViewClickedListener implements OnItemViewClickedListener {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Intent intent = new Intent(getActivity(), DetailsSupportActivity.class);
+ intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);
+
+ Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
+ getActivity(),
+ ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
+ getActivity().startActivity(intent, bundle);
+ }
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java
index 9ffaf66f5..fe664dd7a 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java
@@ -15,6 +15,7 @@ package com.example.android.leanback;
import android.content.Intent;
import android.os.Bundle;
+import android.os.Handler;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.RowPresenter;
@@ -34,6 +35,7 @@ public class VerticalGridFragment extends android.support.v17.leanback.app.Verti
private static final int NUM_COLUMNS = 3;
private static final int NUM_ITEMS = 50;
private static final int HEIGHT = 200;
+ private static final boolean TEST_ENTRANCE_TRANSITION = true;
private static class Adapter extends ArrayObjectAdapter {
public Adapter(StringPresenter presenter) {
@@ -54,6 +56,25 @@ public class VerticalGridFragment extends android.support.v17.leanback.app.Verti
setTitle("Leanback Vertical Grid Demo");
setupFragment();
+ if (TEST_ENTRANCE_TRANSITION) {
+ // don't run entrance transition if fragment is restored.
+ if (savedInstanceState == null) {
+ prepareEntranceTransition();
+ }
+ }
+ // simulates in a real world use case data being loaded two seconds later
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ loadData();
+ startEntranceTransition();
+ }
+ }, 2000);
+ }
+
+ private void loadData() {
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ mAdapter.add(Integer.toString(i));
+ }
}
private void setupFragment() {
@@ -62,9 +83,6 @@ public class VerticalGridFragment extends android.support.v17.leanback.app.Verti
setGridPresenter(gridPresenter);
mAdapter = new Adapter(new StringPresenter());
- for (int i = 0; i < NUM_ITEMS; i++) {
- mAdapter.add(Integer.toString(i));
- }
setAdapter(mAdapter);
setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportActivity.java
new file mode 100644
index 000000000..0754fb872
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportActivity.java
@@ -0,0 +1,32 @@
+/* This file is auto-generated from VerticalGridActivity.java. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.os.Bundle;
+
+public class VerticalGridSupportActivity extends FragmentActivity
+{
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.vertical_grid_support);
+ // TODO: use BackgroundManager here
+ getWindow().setBackgroundDrawableResource(R.drawable.bg);
+ }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportFragment.java
new file mode 100644
index 000000000..cd88f5a5b
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridSupportFragment.java
@@ -0,0 +1,114 @@
+/* This file is auto-generated from VerticalGridFragment. DO NOT MODIFY. */
+
+/*
+ * 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 com.example.android.leanback;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.VerticalGridPresenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.OnItemViewSelectedListener;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class VerticalGridSupportFragment extends android.support.v17.leanback.app.VerticalGridSupportFragment {
+ private static final String TAG = "leanback.VerticalGridSupportFragment";
+
+ private static final int NUM_COLUMNS = 3;
+ private static final int NUM_ITEMS = 50;
+ private static final int HEIGHT = 200;
+ private static final boolean TEST_ENTRANCE_TRANSITION = true;
+
+ private static class Adapter extends ArrayObjectAdapter {
+ public Adapter(StringPresenter presenter) {
+ super(presenter);
+ }
+ public void callNotifyChanged() {
+ super.notifyChanged();
+ }
+ }
+ private Adapter mAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ic_title));
+ setTitle("Leanback Vertical Grid Demo");
+
+ setupFragment();
+ if (TEST_ENTRANCE_TRANSITION) {
+ // don't run entrance transition if fragment is restored.
+ if (savedInstanceState == null) {
+ prepareEntranceTransition();
+ }
+ }
+ // simulates in a real world use case data being loaded two seconds later
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ loadData();
+ startEntranceTransition();
+ }
+ }, 2000);
+ }
+
+ private void loadData() {
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ mAdapter.add(Integer.toString(i));
+ }
+ }
+
+ private void setupFragment() {
+ VerticalGridPresenter gridPresenter = new VerticalGridPresenter();
+ gridPresenter.setNumberOfColumns(NUM_COLUMNS);
+ setGridPresenter(gridPresenter);
+
+ mAdapter = new Adapter(new StringPresenter());
+ setAdapter(mAdapter);
+
+ setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ }
+ });
+
+ setOnItemViewClickedListener(new OnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemClicked: " + item + " row " + row);
+ mAdapter.callNotifyChanged();
+ }
+ });
+ setOnSearchClickedListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(getActivity(), SearchSupportActivity.class);
+ startActivity(intent);
+ }
+ });
+ }
+}
diff --git a/samples/SupportLeanbackShowcase/.gitignore b/samples/SupportLeanbackShowcase/.gitignore
new file mode 100644
index 000000000..9c4de5825
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/.gitignore
@@ -0,0 +1,7 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/samples/SupportLeanbackShowcase/SupportLeanbackShowcase.iml b/samples/SupportLeanbackShowcase/SupportLeanbackShowcase.iml
new file mode 100644
index 000000000..62a2d86d7
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/SupportLeanbackShowcase.iml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="SupportLeanbackShowcase" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="java-gradle" name="Java-Gradle">
+ <configuration>
+ <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+ <option name="BUILDABLE" value="false" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="SupportLeanbackShowcase" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="android-gradle" name="Android-Gradle">
+ <configuration>
+ <option name="GRADLE_PROJECT_PATH" value=":app" />
+ </configuration>
+ </facet>
+ <facet type="android" name="Android">
+ <configuration>
+ <option name="SELECTED_BUILD_VARIANT" value="debug" />
+ <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+ <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+ <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+ <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+ <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
+ <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
+ <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
+ <option name="ALLOW_USER_CONFIGURATION" value="false" />
+ <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+ <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+ <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+ <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+ <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.1.1/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/leanback-v17/22.1.1/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/palette-v7/21.0.0/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.1.1/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.1.1/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+ <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+ </content>
+ <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" exported="" name="appcompat-v7-22.1.1" level="project" />
+ <orderEntry type="library" exported="" name="leanback-v17-22.1.1" level="project" />
+ <orderEntry type="library" exported="" name="palette-v7-21.0.0" level="project" />
+ <orderEntry type="library" exported="" name="gson-1.7.2" level="project" />
+ <orderEntry type="library" exported="" name="recyclerview-v7-22.1.1" level="project" />
+ <orderEntry type="library" exported="" name="support-v4-22.1.1" level="project" />
+ <orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
+ <orderEntry type="library" exported="" name="picasso-2.3.2" level="project" />
+ </component>
+</module> \ 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..d593ef556
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'com.android.application'
+
+
+android {
+ compileSdkVersion 'android-23'
+ buildToolsVersion "23.0.1"
+
+ defaultConfig {
+ applicationId "android.support.v17.leanback.supportleanbackshowcase"
+ minSdkVersion 17
+ targetSdkVersion '23'
+ 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.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.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.1'
+}
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;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+ 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..087bbd3ab
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml
@@ -0,0 +1,59 @@
+<manifest
+ package="android.support.v17.leanback.supportleanbackshowcase"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false"/>
+ <uses-feature
+ android:name="android.software.leanback"
+ android:required="true"/>
+
+ <application
+ android:allowBackup="true"
+ android:icon="@mipmap/app_banner_sample_app"
+ android:label="@string/app_name"
+ android:largeHeap="true"
+ android:theme="@style/Theme.Example.LeanbackLauncher">
+ <activity
+ android:name=".app.MainActivity"
+ android:icon="@mipmap/app_banner_sample_app"
+ android:label="@string/app_name"
+ android:logo="@mipmap/app_banner_sample_app"
+ android:screenOrientation="landscape">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+
+ <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".app.wizard.WizardExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackWizard"></activity>
+ <activity
+ android:name=".app.settings.SettingsExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackPreferences"></activity>
+ <activity
+ android:name=".app.dialog.DialogExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackDialog"></activity>
+ <activity
+ android:name=".app.details.DetailViewExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackDetails"></activity>
+ <activity
+ android:name=".app.cards.CardExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackBrowse"></activity>
+ <activity
+ android:name=".app.grid.GridExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackVerticalGrid"></activity>
+ <activity
+ android:name=".app.media.VideoExampleActivity"
+ android:theme="@style/Theme.Example.Leanback"></activity>
+ <activity
+ android:name=".app.media.MusicExampleActivity"
+ android:theme="@style/Theme.Example.LeanbackMusic"></activity>
+ </application>
+
+</manifest>
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..ab22928d8
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java
@@ -0,0 +1,181 @@
+/*
+ * 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.content.Intent;
+import android.os.Bundle;
+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.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.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.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;
+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.support.v4.app.ActivityOptionsCompat;
+
+import com.google.gson.Gson;
+
+
+public class MainFragment extends BrowseFragment {
+
+ private ArrayObjectAdapter mRowsAdapter;
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ setupUIElements();
+ setupRowAdapter();
+ setupEventListeners();
+ }
+
+ private void setupRowAdapter() {
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ createRows();
+ setAdapter(mRowsAdapter);
+ }
+
+ private void createRows() {
+ String json = Utils
+ .inputStreamToString(getResources().openRawResource(R.raw.launcher_cards));
+ 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 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());
+ }
+
+ private final class ItemViewClickedListener implements OnItemViewClickedListener {
+
+ @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 = new Intent(getActivity().getBaseContext(),
+ CardExampleActivity.class);
+ break;
+ }
+ case 2: {
+ intent = new Intent(getActivity().getBaseContext(),
+ GridExampleActivity.class);
+ break;
+ }
+ case 3: {
+ intent = new Intent(getActivity().getBaseContext(),
+ DetailViewExampleActivity.class);
+ break;
+ }
+ case 4: {
+ intent = new Intent(getActivity().getBaseContext(),
+ VideoExampleActivity.class);
+ break;
+ }
+ case 5: {
+ intent = new Intent(getActivity().getBaseContext(),
+ MusicExampleActivity.class);
+ 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 = 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.
+ break;
+ }
+ case 7: {
+ intent = new Intent(getActivity().getBaseContext(),
+ SettingsExampleActivity.class);
+ startActivity(intent);
+ return;
+ }
+ case 8: {
+ intent = new Intent(getActivity().getBaseContext(),
+ DialogExampleActivity.class);
+ break;
+ }
+ default:
+ break;
+ }
+ if (intent != null) {
+ Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
+ .toBundle();
+ startActivity(intent, bundle);
+ }
+ }
+ }
+
+ private final class ItemViewSelectedListener implements OnItemViewSelectedListener {
+
+ @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..4b2a44557
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java
@@ -0,0 +1,132 @@
+/*
+ * 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.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v17.leanback.app.BrowseFragment;
+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.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.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;
+
+/**
+ * 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();
+ }
+ });
+ 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());
+ setAdapter(mRowsAdapter);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ createRows();
+ startEntranceTransition();
+ }
+ }, 500);
+ }
+
+ 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/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..eed800ffd
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java
@@ -0,0 +1,179 @@
+/*
+ * 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.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;
+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.FullWidthDetailsOverviewSharedElementHelper;
+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 {
+
+ public static final String TRANSITION_NAME = "t_for_transition";
+ public static final String EXTRA_CARD = "card";
+
+ private ArrayObjectAdapter mRowsAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(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;
+ }
+ };
+
+ FullWidthDetailsOverviewSharedElementHelper mHelper = new FullWidthDetailsOverviewSharedElementHelper();
+ mHelper.setSharedElementEnterTransition(getActivity(), TRANSITION_NAME);
+ rowPresenter.setListener(mHelper);
+ rowPresenter.setParticipatingEntranceTransition(false);
+ prepareEntranceTransition();
+
+ 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());
+
+ 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()));
+ 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);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ startEntranceTransition();
+ }
+ }, 500);
+ }
+
+ 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().setBackground(null);
+ }
+ }
+}
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..55f75759a
--- /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.addAsRoot(this, fragment, android.R.id.content);
+ }
+}
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<GuidedAction> 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/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/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..6640b5180
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java
@@ -0,0 +1,72 @@
+/*
+ * 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.os.Handler;
+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;
+
+ private ArrayObjectAdapter mAdapter;
+
+ 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());
+ 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/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: <ul> <li>{@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction}</li>
+ * <li>{@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}</li> <li>{@link
+ * android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction}</li> <li>{@link
+ * android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction}</li> <li>{@link
+ * android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction}</li> <li>{@link
+ * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction}</li> <li>{@link
+ * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction}</li> </ul>
+ * <p/>
+ */
+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
+ * <u>after</u> 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 <code>startPlayback(1)</code>.
+ *
+ * @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 <code>true</code> iff 'Shuffle' is <code>ON</code>.
+ */
+ public boolean useShuffle() {
+ return mShuffleAction.getIndex() == PlaybackControlsRow.ShuffleAction.ON;
+ }
+
+ /**
+ * @return Returns <code>true</code> iff 'Repeat-One' is <code>ON</code>.
+ */
+ public boolean repeatOne() {
+ return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ONE;
+ }
+
+ /**
+ * @return Returns <code>true</code> iff 'Repeat-All' is <code>ON</code>.
+ */
+ 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
+ * <u>NOT</u> 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<Song> 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/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/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..9a40635cf
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/media/VideoConsumptionExampleFragment.java
@@ -0,0 +1,117 @@
+/*
+ * 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(VideoExampleActivity.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/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/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..b9bb77f6a
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/settings/SettingsExampleFragment.java
@@ -0,0 +1,107 @@
+/*
+ * 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.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.widget.Toast;
+
+import java.util.Arrays;
+import java.util.Stack;
+
+public class SettingsExampleFragment extends LeanbackSettingsFragment implements DialogPreference.TargetFragment {
+
+ private final Stack<Fragment> fragments = new Stack<Fragment>();
+
+ @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());
+ 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 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);
+ 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..b40cc8257
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.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.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;
+
+/**
+ * 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 {
+
+ private static final int ACTION_ID_BUY_HD = 1;
+ private static final int ACTION_ID_BUY_SD = ACTION_ID_BUY_HD + 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<GuidedAction> actions, Bundle savedInstanceState) {
+ 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();
+ actions.add(action);
+ 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();
+ actions.add(action);
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ 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
new file mode 100644
index 000000000..c1df8a131
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java
@@ -0,0 +1,101 @@
+/*
+ * 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.text.TextUtils;
+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;
+
+/**
+ * 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;
+ }
+
+ @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<GuidedAction> actions, Bundle savedInstanceState) {
+ boolean rentHighDefinition = getArguments().getBoolean(ARG_HD);
+
+ GuidedAction action = new GuidedAction.Builder()
+ .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))
+ .editTitle("")
+ .description(getString(R.string.wizard_example_input_credit))
+ .editable(true)
+ .build();
+ actions.add(action);
+ }
+
+ @Override
+ 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/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..37f662f0a
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample3rdStepFragment.java
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+/**
+ * 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 {
+
+ private static final int ACTION_ID_PROCESSING = 1;
+ private final Handler mFakeHttpHandler = new Handler();
+
+ @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(),
+ getString(R.string.wizard_example_just_a_second),
+ mMovie.getBreadcrump(), null);
+ return guidance;
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> 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..be5e6459a
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+/**
+ * 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 {
+
+ private static final int ACTION_ID_WATCH = 1;
+ private static final int ACTION_ID_LATER = ACTION_ID_WATCH + 1;
+
+ @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<GuidedAction> 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);
+ }
+
+ @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..f5d293708
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleActivity.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+/**
+ * An Activity displaying a wizard for renting a movie.
+ */
+public class WizardExampleActivity extends Activity {
+
+ @Override public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().setBackgroundDrawableResource(R.drawable.wizard_background_blackned);
+
+ GuidedStepFragment fragment = new WizardExample1stStepFragment();
+ fragment.setArguments(getIntent().getExtras()); // Delegate Movie to first step.
+ GuidedStepFragment.addAsRoot(this, fragment, android.R.id.content);
+ }
+
+ @Override
+ public void onBackPressed() {
+ 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();
+ }
+
+}
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..8fd59814b
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExampleBaseStepFragment.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+/**
+ * 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 abstract 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
new file mode 100644
index 000000000..962adb007
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java
@@ -0,0 +1,69 @@
+/*
+ * 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.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.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class CharacterCardView extends BaseCardView {
+
+ public CharacterCardView(Context context) {
+ super(context, null, R.style.CharacterCardStyle);
+ 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..830b47441
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/TextCardView.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.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.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.ImageView;
+import android.widget.TextView;
+
+public class TextCardView extends BaseCardView {
+
+ public TextCardView(Context context) {
+ super(context, null, R.style.TextCardStyle);
+ 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/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..0301cdc1c
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/AbstractCardPresenter.java
@@ -0,0 +1,79 @@
+/*
+ * 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.models.Card;
+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 <CardViewType> The cards' View Type.
+ */
+public abstract class AbstractCardPresenter<CardViewType extends BaseCardView> 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/CardPresenterSelector.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.java
new file mode 100644
index 000000000..1228b14a9
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CardPresenterSelector.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.cards.presenters;
+
+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.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.
+ */
+public class CardPresenterSelector extends PresenterSelector {
+
+ private final Context mContext;
+ private final HashMap<Card.Type, Presenter> presenters = new HashMap<Card.Type, Presenter>();
+
+ 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 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;
+ }
+ }
+ 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..35a42a969
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/CharacterCardPresenter.java
@@ -0,0 +1,40 @@
+/*
+ * 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.CharacterCardView;
+import android.support.v17.leanback.supportleanbackshowcase.models.Card;
+
+/**
+ * This Presenter is used to display the characters card row in the DetailView examples.
+ */
+public class CharacterCardPresenter extends AbstractCardPresenter<CharacterCardView> {
+
+ public CharacterCardPresenter(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected CharacterCardView onCreateView() {
+ return new CharacterCardView(getContext());
+ }
+
+ @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/IconCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java
new file mode 100644
index 000000000..bf5be70f4
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/IconCardPresenter.java
@@ -0,0 +1,51 @@
+/*
+ * 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.widget.ImageCardView;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * 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 ImageCardViewPresenter {
+
+ public IconCardPresenter(Context context) {
+ super(context, R.style.IconCardStyle);
+ }
+
+ @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 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
new file mode 100644
index 000000000..813c1e78d
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/ImageCardViewPresenter.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.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
+ * 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<ImageCardView> {
+
+ private final int mCardStyleResId;
+
+ public ImageCardViewPresenter(Context context, int cardStyleResId) {
+ super(context);
+ mCardStyleResId = cardStyleResId;
+ }
+
+ public ImageCardViewPresenter(Context context) {
+ super(context);
+ mCardStyleResId = R.style.DefaultCardStyle;
+ }
+
+ @Override
+ protected ImageCardView onCreateView() {
+ return new ImageCardView(getContext(), mCardStyleResId);
+ }
+
+ @Override
+ public void onBindViewHolder(Card card, final ImageCardView cardView) {
+ cardView.setTag(card);
+ 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).into(cardView.getMainImageView());
+ }
+ }
+
+}
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..b9f44fc43
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SideInfoCardPresenter.java
@@ -0,0 +1,74 @@
+/*
+ * 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.models.Card;
+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<BaseCardView> {
+
+ public SideInfoCardPresenter(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected BaseCardView onCreateView() {
+ final BaseCardView cardView = new BaseCardView(getContext(), null,
+ R.style.SideInfoCardStyle);
+ cardView.setFocusable(true);
+ cardView.addView(LayoutInflater.from(getContext()).inflate(R.layout.side_info_card, null));
+ return cardView;
+ }
+
+ @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);
+ 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 = (TextView) cardView.findViewById(R.id.primary_text);
+ primaryText.setText(card.getTitle());
+
+ TextView secondaryText = (TextView) cardView.findViewById(R.id.secondary_text);
+ secondaryText.setText(card.getDescription());
+
+ TextView extraText = (TextView) cardView.findViewById(R.id.extra_text);
+ extraText.setText(card.getExtraText());
+ }
+
+}
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..24dedd5c6
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/SingleLineCardPresenter.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.cards.presenters;
+
+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;
+
+/**
+ * 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 ImageCardViewPresenter {
+
+ public SingleLineCardPresenter(Context context) {
+ super(context, R.style.SingleLineCardStyle);
+ }
+
+ @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/TextCardPresenter.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java
new file mode 100644
index 000000000..7e65f0f13
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/presenters/TextCardPresenter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.TextCardView;
+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
+ * also quite unique since it does contain two images rather than one or non.
+ */
+public class TextCardPresenter extends AbstractCardPresenter<TextCardView> {
+
+ public TextCardPresenter(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected TextCardView onCreateView() {
+ return new TextCardView(getContext());
+ }
+
+ @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/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<Card> mCards;
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public boolean useShadow() {
+ return mShadow;
+ }
+
+ public List<Card> 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<Song> mSongs;
+
+ public List<Song> 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<View> mCachedViews = new SparseArray<View>();
+
+ public <ViewType extends View> 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..4416cbe49
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java
@@ -0,0 +1,58 @@
+/*
+ * 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.net.Uri;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 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 <code>null</code> 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;
+ }
+ }
+
+ 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/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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item>
+ <color android:color="#384248"></color>
+ </item>
+ <item>
+ <ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <corners android:radius="2dp"/>
+ <solid android:color="#FFFFFF"/>
+ </shape>
+ </item>
+
+ </ripple>
+ </item>
+
+</layer-list> \ 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_canyon.jpg
Binary files differ
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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_food.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/background_sax.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_dummy_16_9_l.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_01.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_02.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_03.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_04.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_05.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_06.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_07.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_08.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_movie_09.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_01.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_02.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_03.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_04.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_05.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_06.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_07.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_08.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_09.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_10.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_11.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_12.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/card_image_music_13.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_action.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_animation.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_classics.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_comedy.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_crime.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_documentary.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/category_drama.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_01.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_02.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_03.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_04.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_05.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_06.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_07.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/coffee_and_tea_08.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_01.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_02.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_03.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_04.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_05.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_06.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_07.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_08.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_09.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_10.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_11.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_12.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_13.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/food_14.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_angry_bird_w.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_badland_w.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_leos_fortune_w.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_minion_rush_w.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/game_monument_valley_w.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_cc.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_installed.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_apps.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_more.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_parental_control.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_settings.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_time.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_3_bar.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_settings_wifi_4_bar.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_off.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/ic_star_on_yellow.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/movie_poster_01.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_red.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/stars_white.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_browse.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_cards.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_custom_01.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_detail.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_dialog.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_grid.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_music_consumption.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_settings.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_video_consumption.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/thumbnail_example_wizard.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable-xhdpi/title_android_tv.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/app_icon_your_company.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room.jpg
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/bg_living_room_wide.jpg
Binary files 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..5c2570d53
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_focused.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <padding
+ android:bottom="4dp"
+ android:left="4dp"
+ android:right="4dp"
+ android:top="4dp"></padding>
+ <solid android:color="#FFEEEEEE"></solid>
+</shape> \ 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..db4cf9c7d
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <padding
+ android:bottom="4dp"
+ android:left="4dp"
+ android:right="4dp"
+ android:top="4dp"></padding>
+ <solid android:color="#FFCCCCCC"></solid>
+</shape> \ 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..8da381217
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/character_not_focused_padding.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <padding
+ android:bottom="4dp"
+ android:left="4dp"
+ android:right="4dp"
+ android:top="4dp"></padding>
+ <solid android:color="#00CCCCCC"></solid>
+</shape> \ 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..d9fa80b2c
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/default_background.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <gradient
+ android:angle="-270"
+ android:endColor="@color/background_gradient_end"
+ android:startColor="@color/background_gradient_start"/>
+</shape> \ 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_01.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_02.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_03.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_04.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_05.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_06.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_07.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/face_08.png
Binary files 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..bab1cc6f9
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/icon_focused.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="#4DEEEEEE"></solid>
+ <size
+ android:width="96dp"
+ android:height="96dp"/>
+</shape> \ 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..9fccc2454
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/overlay_black.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#E6000000"></solid>
+</shape> \ 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..0329874e6
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/song_row_background_focused" android:state_focused="true"></item>
+ <item>
+ <color android:color="#384248"></color>
+ </item>
+</selector> \ 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..152e7e6f8
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/song_row_background_focused.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <color android:color="#384248"></color>
+ </item>
+ <item>
+ <color android:color="#1AFFFFFF"></color>
+ </item>
+</layer-list> \ 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..bea8d6689
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_background_blackned.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/background_canyon"></item>
+ <item android:drawable="@drawable/overlay_black"></item>
+</layer-list> \ 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..b4fd39ec4
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/wizard_important_action_item_background_focused" android:state_focused="true"></item>
+ <item android:drawable="@drawable/wizard_important_action_item_background_not_focused"></item>
+</selector> \ 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..d6a1023c3
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_focused.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#FFFFFF"></solid>
+</shape> \ 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..74cccd0f5
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/drawable/wizard_important_action_item_background_not_focused.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#B2FFFFFF"></solid>
+</shape> \ No newline at end of file
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..45b550567
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <fragment
+ android:id="@+id/cardsFragment"
+ android:name="android.support.v17.leanback.supportleanbackshowcase.app.cards.CardExampleFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"></fragment>
+</RelativeLayout> \ 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
new file mode 100644
index 000000000..1dd92d8c9
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_detail_example.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <fragment
+ android:id="@+id/detailsFragment"
+ android:name="android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"></fragment>
+</RelativeLayout> \ No newline at end of file
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
new file mode 100644
index 000000000..f3fcdeaac
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_grid_example.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <fragment
+ android:id="@+id/cardsFragment"
+ android:name="android.support.v17.leanback.supportleanbackshowcase.app.grid.GridExampleFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"></fragment>
+</RelativeLayout> \ 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..9d2eda6c7
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout
+ android:id="@+id/fragmentContainer"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:deviceIds="tv"
+ tools:ignore="MergeRootFrame">
+</RelativeLayout>
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..9eef61a91
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_music_example.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <fragment
+ android:id="@+id/musicFragment"
+ android:name="android.support.v17.leanback.supportleanbackshowcase.app.media.MusicConsumptionExampleFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"></fragment>
+</RelativeLayout> \ 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
new file mode 100644
index 000000000..c6c81a3a1
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_settings_example.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <fragment
+ android:id="@+id/settingsFragment"
+ android:name="android.support.v17.leanback.supportleanbackshowcase.app.settings.SettingsExampleFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"></fragment>
+</RelativeLayout> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <RelativeLayout
+ android:id="@+id/videoFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ </RelativeLayout>
+</RelativeLayout> \ 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..dee09a8e6
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ 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">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/character_not_focused_padding">
+
+ <ImageView
+ android:id="@+id/main_image"
+ android:layout_width="@dimen/character_image_card_width"
+ android:layout_height="@dimen/character_image_card_height"
+ android:background="@drawable/character_not_focused"
+ android:src="@drawable/face_08"/>
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/primary_text"
+ style="@style/Widget.Leanback.ImageCardView.TitleStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="7dp"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center"/>
+ </LinearLayout>
+</FrameLayout> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/primary_text"
+ style="@style/Widget.Leanback.DetailsDescriptionTitleStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="3dp"
+ android:layout_marginTop="15dp"
+ android:fontFamily="sans-serif-light"
+ android:text="Title Text"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="14dp"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/secondary_text_first"
+ style="@style/Widget.Leanback.DetailsDescriptionSubtitleStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="16dp"
+ android:fontFamily="sans-serif-condensed"
+ android:text="Secondary Text Area"/>
+
+ <TextView
+ android:id="@+id/secondary_text_second"
+ style="@style/Widget.Leanback.DetailsDescriptionSubtitleStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="16dp"
+ android:fontFamily="sans-serif-condensed"
+ android:text="With Icons"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="16dp"
+ android:src="@drawable/ic_cc"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_star_on_yellow"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_star_on_yellow"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_star_on_yellow"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_star_off"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_star_off"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/extra_text"
+ style="@style/Widget.Leanback.DetailsDescriptionBodyStyle"
+ android:layout_width="match_parent"
+ android:fontFamily="sans-serif-regular"
+ android:layout_height="wrap_content"
+ android:text="Filmmaker Guillermo del Toro teas up with Legendary Pictures to bring audiences a unique take on the monster film with this sci/fi production."/>
+</LinearLayout> \ 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..b8d660d50
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_song.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:lb="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="horizontal"
+ android:paddingEnd="@dimen/lb_playback_controls_margin_end"
+ android:paddingStart="@dimen/lb_playback_controls_margin_start"
+ lb:rowHeight="wrap_content">
+
+
+ <RelativeLayout
+ android:id="@+id/rowContainer"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:background="@drawable/song_row_background"
+ android:focusable="true"
+ android:focusableInTouchMode="true">
+
+ <TextView
+ android:id="@+id/trackNumber"
+ android:layout_width="56dp"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="32dp"
+ android:fontFamily="sans-serif-regular"
+ android:gravity="center_vertical"
+ android:text="1"
+ android:textColor="#FFFFFF"
+ android:textSize="18sp"/>
+
+
+ <TextView
+ android:id="@+id/trackName"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_alignParentTop="true"
+ android:layout_toEndOf="@+id/trackNumber"
+ android:layout_toLeftOf="@+id/trackDuration"
+ android:fontFamily="sans-serif-regular"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:text="A Song!!11"
+ android:textColor="#FFFFFF"
+ android:textSize="18sp"/>
+
+
+ <TextView
+ android:id="@+id/trackDuration"
+ android:layout_width="66dp"
+ android:layout_height="48dp"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginRight="32dp"
+ android:fontFamily="sans-serif-regular"
+ android:gravity="center_vertical|right"
+ android:text="1:13:54"
+ android:textColor="#80FFFFFF"
+ android:textSize="18sp"/>
+ </RelativeLayout>
+</LinearLayout> \ 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..df16028fb
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/row_track_list_header.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:lb="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingEnd="@dimen/lb_playback_controls_margin_end"
+ android:paddingStart="@dimen/lb_playback_controls_margin_start"
+ lb:rowHeight="wrap_content">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentTop="true"
+ android:background="#263238"
+ android:fontFamily="sans-serif-regular"
+ android:gravity="center_vertical"
+ android:paddingLeft="32dp"
+ android:text="Tracks"
+ android:textColor="#80EEEEEE"
+ android:textSize="18sp"/>
+ </RelativeLayout>
+</RelativeLayout> \ 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..725af09fb
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/side_info_card.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:lb="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/main_image"
+ android:layout_width="144dp"
+ android:layout_height="144dp"
+ lb:layout_viewType="main"
+ />
+
+ <LinearLayout
+ android:id="@+id/info"
+ android:layout_width="144dp"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="11dp"
+ android:paddingRight="11dp"
+ android:paddingTop="7dp"
+ android:background="@color/default_card_footer_background_color">
+
+ <TextView
+ android:id="@+id/primary_text"
+ style="@style/Widget.Leanback.ImageCardView.TitleStyle"
+ android:fontFamily="sans-serif-condensed"
+ android:maxLines="2"
+ android:textSize="16sp"/>
+
+ <TextView
+ android:id="@+id/secondary_text"
+ style="@style/Widget.Leanback.ImageCardView.ContentStyle"
+ android:layout_marginTop="4dp"
+ android:fontFamily="sans-serif-condensed"
+ android:maxLines="1"
+ android:textColor="#EEEEEE"/>
+
+ <TextView
+ android:id="@+id/extra_text"
+ style="@style/Widget.Leanback.ImageCardView.ContentStyle"
+ android:layout_marginTop="6dp"
+ android:fontFamily="sans-serif-condensed"
+ android:maxLines="5"/>
+ </LinearLayout>
+</LinearLayout> \ 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..339549a07
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/text_icon_card.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:lb="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/extra_text"
+ style="@style/Widget.Leanback.ImageCardView.ContentStyle"
+ android:layout_width="256dp"
+ android:layout_height="wrap_content"
+ android:background="@color/default_card_background_color"
+ 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"/>
+
+ <android.support.v17.leanback.widget.NonOverlappingRelativeLayout
+ android:layout_width="256dp"
+ android:layout_height="36dp"
+ android:background="@color/default_card_footer_background_color"
+ android:gravity="left"
+ android:orientation="horizontal"
+ android:paddingBottom="7dp"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp"
+ android:paddingTop="7dp">
+
+ <ImageView
+ android:id="@+id/main_image"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:layout_centerVertical="true"
+ android:layout_gravity="center_vertical"
+ android:layout_marginRight="8dp"
+ android:adjustViewBounds="true"/>
+
+ <TextView
+ android:id="@+id/primary_text"
+ style="@style/Widget.Leanback.ImageCardView.TitleStyle"
+ android:layout_width="match_parent"
+ android:layout_centerVertical="true"
+ android:layout_gravity="left"
+ android:layout_toRightOf="@+id/main_image"
+ android:fontFamily="sans-serif-condensed"
+ android:maxLines="1"
+ />
+
+ <ImageView
+ android:id="@+id/footer_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="32dp"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"
+ android:layout_gravity="center_vertical"
+ android:adjustViewBounds="true"
+ android:src="@drawable/stars_white"/>
+
+ </android.support.v17.leanback.widget.NonOverlappingRelativeLayout>
+</merge> \ 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..ff5be6929
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/video_surface_fragment.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+</SurfaceView> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <RelativeLayout
+ style="?attr/guidedActionsContainerStyle">
+
+ <FrameLayout
+ android:id="@+id/guidedactions_selector"
+ style="?attr/guidedActionsSelectorStyle"
+ android:visibility="gone"/>
+
+ <android.support.v17.leanback.widget.VerticalGridView
+ android:id="@+id/guidedactions_list"
+ style="?attr/guidedActionsListStyle"/>
+
+ </RelativeLayout>
+
+</RelativeLayout>
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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<android.support.v17.leanback.widget.NonOverlappingLinearLayout
+ style="?attr/guidedActionItemContainerStyle"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <ProgressBar
+ android:id="@+id/progressBar"
+ style="?android:attr/progressBarStyle"
+ android:indeterminateTintMode="src_in"
+ android:indeterminateTint="#FFAB91"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="10dp"
+ android:indeterminate="false"/>
+
+ <android.support.v17.leanback.widget.NonOverlappingLinearLayout
+ android:id="@+id/guidedactions_item_content"
+ style="?attr/guidedActionItemContentStyle">
+
+ <TextView
+ android:id="@+id/guidedactions_item_title"
+ style="?attr/guidedActionItemTitleStyle"
+ android:text="Processing..."/>
+
+ </android.support.v17.leanback.widget.NonOverlappingLinearLayout>
+
+</android.support.v17.leanback.widget.NonOverlappingLinearLayout>
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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/app_banner_sample_app.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
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
new file mode 100644
index 000000000..b6d06e26a
--- /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": "MOVIE",
+ "title": "The Amazing Spuder-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"
+ }
+ ]
+} \ 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/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
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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_01.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_02.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_03.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_04.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_05.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_06.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_07.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_08.mp3
Binary files 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
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/raw/track_09.mp3
Binary files 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..9933ba7e1
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/arrays.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+
+<resources>
+ <array name="pref_parent_control_entries">
+ <item>Everyone</item>
+ <item>Low maturity</item>
+ <item>Medium maturity</item>
+ <item>High maturity</item>
+ </array>
+ <array name="pref_parent_control_entries_values">
+ <item>everyone</item>
+ <item>low</item>
+ <item>medium</item>
+ <item>high</item>
+ </array>
+ <array name="pref_parent_control_entries_summaries">
+ <item>This description becomes visible only on focus.</item>
+ <item>This description becomes visible only on focus.</item>
+ <item>This description becomes visible only on focus.</item>
+ <item>This description becomes visible only on focus.</item>
+ </array>
+ <array name="pref_wifi_networks">
+ <item>Wi-Fi network 1</item>
+ <item>Wi-Fi network 2</item>
+ <item>Wi-Fi network 3</item>
+ <item>Wi-Fi network 4</item>
+ <item>Wi-Fi network 5</item>
+ <item>Wi-Fi network 6</item>
+ </array>
+</resources> \ 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..6305c4119
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/colors.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<resources>
+ <color name="background_gradient_start">#FFFFFF</color>
+ <color name="background_gradient_end">#DDDDDD</color>
+ <color name="fastlane_background">#06838f</color>
+ <color name="fastlane_teal_background">#00796B</color>
+ <color name="search_opaque">#ffaa3f</color>
+ <color name="search_color">#FFEB3B</color>
+ <color name="search_bright_color">#FFEB3B</color>
+ <color name="search_icon_color">#222222</color>
+ <color name="accent">#80D3FB</color>
+ <color name="settings_background">#00695C</color>
+
+ <color name="default_background">#3d3d3d</color>
+
+ <color name="default_card_background_color">#263238</color>
+ <color name="default_card_footer_background_color">#37474F</color>
+ <color name="selected_card_footer_background_color">#F0F</color>
+
+ <color name="card_primary_text">#EEEEEE</color>
+ <color name="card_secondary_text">#99EEEEEE</color>
+
+ <color name="loading_error_card_background">#86c739</color>
+
+ <color name="card_examples_background">#222222</color>
+
+ <color name="detail_view_actionbar_background">#04549D</color>
+ <color name="detail_view_background">#0374BF</color>
+ <color name="detail_view_related_background">#022A4E</color>
+</resources>
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..07c802733
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/dims.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<resources>
+ <dimen name="default_image_card_width">224dp</dimen>
+ <dimen name="default_image_card_height">126dp</dimen>
+
+ <dimen name="movie_image_card_width">120dp</dimen>
+ <dimen name="movie_image_card_height">172dp</dimen>
+
+ <dimen name="icon_image_card_width">224dp</dimen>
+ <dimen name="icon_image_card_height">109dp</dimen>
+
+ <dimen name="big_square_image_card_width">144dp</dimen>
+ <dimen name="big_square_image_card_height">144dp</dimen>
+
+ <dimen name="square_image_card_width">128dp</dimen>
+ <dimen name="square_image_card_height">128dp</dimen>
+
+ <dimen name="small_square_image_card_width">96dp</dimen>
+ <dimen name="small_square_image_card_height">96dp</dimen>
+
+ <dimen name="sidetext_image_card_width">144dp</dimen>
+ <dimen name="sidetext_image_card_height">144dp</dimen>
+
+ <dimen name="wide_short_image_card_width">224dp</dimen>
+ <dimen name="wide_short_image_card_height">109dp</dimen>
+
+ <dimen name="character_image_card_width">120dp</dimen>
+ <dimen name="character_image_card_height">120dp</dimen>
+
+ <dimen name="grid_card_width">200dp</dimen>
+ <dimen name="grid_card_height">200dp</dimen>
+</resources> \ 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..a25b964c8
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<resources>
+ <string name="app_name">ShowcaseApp</string>
+ <string name="browse_title"><![CDATA[androidTV]]></string>
+
+ <!-- Error messages -->
+ <string name="implement_search">Implement your own in-app search.</string>
+ <string name="card_examples_title">Card Examples</string>
+ <string name="detail_view_title">DetailView Example</string>
+ <string name="action_cicked">Action clicked. Implement your own handler.</string>
+ <string name="grid_example_title">Grid Example</string>
+ <string name="action_buy">Buy </string>
+ <string name="action_wishlist">Add to wishlist</string>
+ <string name="action_related">Related</string>
+ <string name="header_related">Related Items</string>
+ <string name="header_recommended">Recommended</string>
+
+ <!-- Dialog example -->
+ <string name="dialog_example_title">Use Google\'s location service?</string>
+ <string name="dialog_example_description">Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.</string>
+ <string name="dialog_example_button_positive">Agree</string>
+ <string name="dialog_example_button_negative">Disagree</string>
+ <string name="dialog_example_button_toast_positive_clicked">\'Agree\' clicked.</string>
+ <string name="dialog_example_button_toast_negative_clicked">\'Disagree\' clicked.</string>
+
+ <!-- Wizard example -->
+ <string name="wizard_example_choose_rent_options">Choose rent options</string>
+ <string name="wizard_example_watch_hd">Watch in HD on supported devices</string>
+ <string name="wizard_example_watch_sd">Watch in standard definition on the web and supported devices</string>
+ <string name="wizard_example_rental_period">Rental period: start within 30 days,\nfinish within 24 hours</string>
+ <string name="wizard_example_payment_method">Payment Method</string>
+ <string name="wizard_example_toast_payment_method_clicked">\'Payment Method\' clicked.</string>
+ <string name="wizard_example_rent">Rent</string>
+ <string name="wizard_example_rent_hd">Rent HD</string>
+ <string name="wizard_example_rent_sd">Rent SD</string>
+ <string name="wizard_example_processing">Processinig...</string>
+ <string name="wizard_example_watch_now">Watch now</string>
+ <string name="wizard_example_later">Later</string>
+ <string name="wizard_example_watch_now_clicked">\'Watch now\' clicked.</string>
+ <string name="wizard_example_input_credit">Input credit card number</string>
+ <string name="wizard_example_visa">Visa XXXX-XXXX-XXXX-%s</string>
+ <string name="wizard_example_input_credit_wrong">Error credit card number</string>
+ s<string name="wizard_example_just_a_second">Just a second...</string>
+</resources> \ 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..c9b047676
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/styles.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<resources>
+
+ <style name="AppTheme" parent="@style/Theme.Leanback">
+ </style>
+
+ <style name="WizardActionsContainerStyle" parent="Widget.Leanback.GuidedActionsContainerStyle">
+ <item name="android:background">#C03800</item>
+ </style>
+
+ <style name="DialogActionsContainerStyle" parent="Widget.Leanback.GuidedActionsContainerStyle">
+ <item name="android:background">#263238</item>
+ </style>
+
+ <!-- Various movie card styles. Used in cards example. -->
+ <style name="MovieCardBadgeStyle" parent="Widget.Leanback.ImageCardView.BadgeStyle">
+ <item name="android:src">@drawable/stars_red</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:scaleType">center</item>
+ </style>
+
+ <style name="MovieCardTitleTwoLineStyle" parent="Widget.Leanback.ImageCardView.TitleStyle">
+ <item name="android:maxLines">2</item>
+ <item name="android:minLines">2</item>
+ </style>
+
+ <style name="MovieCardContentGoneStyle" parent="Widget.Leanback.ImageCardView.ContentStyle">
+ <item name="android:visibility">invisible</item>
+ </style>
+
+ <style name="MovieCardContentStyle" parent="Widget.Leanback.ImageCardView.ContentStyle">
+ <item name="android:gravity">right</item>
+ </style>
+
+ <style name="MovieCardImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
+ <item name="android:layout_width">@dimen/movie_image_card_width</item>
+ <item name="android:layout_height">@dimen/movie_image_card_height</item>
+ </style>
+
+ <style name="MovieCardSimpleStyle" parent="Widget.Leanback.ImageCardViewStyle">
+ <item name="lbImageCardViewType">Title</item>
+ <item name="lbImageCardViewImageStyle">@style/MovieCardImageStyle</item>
+ <item name="cardBackground">@null</item>
+ </style>
+
+ <style name="MovieCardCompleteStyle" parent="MovieCardSimpleStyle">
+ <item name="lbImageCardViewTitleStyle">@style/MovieCardTitleTwoLineStyle</item>
+ <item name="lbImageCardViewBadgeStyle">@style/MovieCardBadgeStyle</item>
+ <item name="lbImageCardViewContentStyle">@style/MovieCardContentStyle</item>
+ <item name="lbImageCardViewType">Title|Content|IconOnLeft</item>
+ </style>
+
+ <style name="MovieCardBasicStyle" parent="MovieCardCompleteStyle">
+ <item name="lbImageCardViewContentStyle">@style/MovieCardContentGoneStyle</item>
+ </style>
+
+ <!-- Squared Title/Content card style. Used in cards example. -->
+ <style name="SquareBigCardImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
+ <item name="android:layout_width">@dimen/big_square_image_card_width</item>
+ <item name="android:layout_height">@dimen/big_square_image_card_height</item>
+ </style>
+
+ <style name="SquareBigCard" parent="Widget.Leanback.ImageCardViewStyle">
+ <item name="lbImageCardViewImageStyle">@style/SquareBigCardImageStyle</item>
+ <item name="cardBackground">@null</item>
+ </style>
+
+ <!-- SideInfo. used in cards example -->
+ <style name="SideInfoCardStyle" parent="Widget.Leanback.BaseCardViewStyle">
+ <item name="cardType">mainOnly</item>
+ <item name="cardBackground">@null</item>
+ </style>
+
+ <!-- TextCardView. used in cards example -->
+ <style name="TextCardStyle" parent="Widget.Leanback.BaseCardViewStyle">
+ <item name="cardBackground">@null</item>
+ </style>
+
+ <!-- CharacterCardView. used in details example -->
+ <style name="CharacterCardStyle" parent="Widget.Leanback.BaseCardViewStyle">
+ <item name="cardBackground">@null</item>
+ </style>
+
+ <!-- Grid card style. Used by Grid example. -->
+ <style name="GridCardImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
+ <item name="android:layout_width">@dimen/grid_card_width</item>
+ <item name="android:layout_height">@dimen/grid_card_height</item>
+ </style>
+
+ <style name="GridCardStyle" parent="Widget.Leanback.ImageCardViewStyle">
+ <item name="lbImageCardViewImageStyle">@style/GridCardImageStyle</item>
+ <item name="cardBackground">@null</item>
+ </style>
+
+ <!-- A default card style. Used in cards example. -->
+ <style name="DefaultCardImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
+ <item name="android:layout_width">@dimen/default_image_card_width</item>
+ <item name="android:layout_height">@dimen/default_image_card_height</item>
+ </style>
+
+ <style name="DefaultCardStyle" parent="Widget.Leanback.ImageCardViewStyle">
+ <item name="cardBackground">@null</item>
+ <item name="lbImageCardViewImageStyle">@style/DefaultCardImageStyle</item>
+ </style>
+
+ <!-- Game card styles with custom Badge icon. Used in cards example. -->
+ <style name="GameCardContentStyle" parent="Widget.Leanback.ImageCardView.ContentStyle">
+ <item name="android:textColor">#80c349</item>
+ </style>
+
+ <style name="GameCardBadgeStyle" parent="Widget.Leanback.ImageCardView.BadgeStyle">
+ <item name="android:src">@drawable/ic_installed</item>
+ </style>
+
+ <style name="GameCardStyle" parent="DefaultCardStyle">
+ <item name="lbImageCardViewContentStyle">@style/GameCardContentStyle</item>
+ <item name="lbImageCardViewType">Title|Content|IconOnLeft</item>
+ <item name="lbImageCardViewBadgeStyle">@style/GameCardBadgeStyle</item>
+ </style>
+
+ <!-- Squared single line card with colored footer style. Used in cards example. -->
+ <style name="SingleLineCardTitleStyle" parent="Widget.Leanback.ImageCardView.TitleStyle">
+ <item name="android:textAlignment">center</item>
+ <item name="android:gravity">center</item>
+ </style>
+
+ <style name="SingleLineCardInfoAreaStyle" parent="Widget.Leanback.ImageCardView.InfoAreaStyle">
+ <item name="android:layout_width">@dimen/square_image_card_width</item>
+ <item name="layout_viewType">main</item>
+ </style>
+
+ <style name="SingleLineCardImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
+ <item name="android:layout_width">@dimen/square_image_card_width</item>
+ <item name="android:layout_height">@dimen/square_image_card_height</item>
+ </style>
+
+ <style name="SingleLineCardStyle" parent="DefaultCardStyle">
+ <item name="lbImageCardViewTitleStyle">@style/SingleLineCardTitleStyle</item>
+ <item name="lbImageCardViewType">Title</item>
+ <item name="lbImageCardViewImageStyle">@style/SingleLineCardImageStyle</item>
+ <item name="lbImageCardViewInfoAreaStyle">@style/SingleLineCardInfoAreaStyle</item>
+ </style>
+
+ <!-- Icon card style with custom focus handler. Used in cards example. -->
+ <style name="IconCardImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
+ <item name="android:layout_width">96dp</item>
+ <item name="android:layout_height">96dp</item>
+ <item name="android:padding">16dp</item>
+ </style>
+
+ <style name="IconCardTitleStyle" parent="Widget.Leanback.ImageCardView.TitleStyle">
+ <item name="android:maxLines">2</item>
+ <item name="android:minLines">2</item>
+ <item name="android:gravity">center</item>
+ </style>
+
+ <style name="IconCardInfoAreaStyle" parent="Widget.Leanback.ImageCardView.InfoAreaStyle">
+ <item name="android:layout_width">96dp</item>
+ <item name="android:background">@null</item>
+ <item name="layout_viewType">main</item>
+ </style>
+
+ <style name="IconCardStyle" parent="DefaultCardStyle">
+ <item name="android:layout_width">96dp</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="lbImageCardViewTitleStyle">@style/IconCardTitleStyle</item>
+ <item name="lbImageCardViewType">Title</item>
+ <item name="lbImageCardViewImageStyle">@style/IconCardImageStyle</item>
+ <item name="lbImageCardViewInfoAreaStyle">@style/IconCardInfoAreaStyle</item>
+ </style>
+
+</resources>
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..feb9f036a
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/values/themes.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<resources>
+
+ <style name="Theme.Example.Leanback" parent="Theme.Leanback">
+ <item name="android:colorPrimary">#00A2B8</item>
+ <item name="android:colorAccent">@color/accent</item>
+ <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackLauncher" parent="Theme.Example.Leanback">
+ <item name="android:windowBackground">@drawable/bg_living_room_wide</item>
+ <item name="browseRowsMarginTop">275dp</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackBrowse" parent="Theme.Leanback.Browse">
+ <item name="android:windowBackground">@color/card_examples_background</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackVerticalGrid" parent="Theme.Leanback.VerticalGrid">
+ <item name="android:windowBackground">@drawable/background_food</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackWizard" parent="Theme.Leanback.GuidedStep">
+ <item name="guidedActionsContainerStyle">@style/WizardActionsContainerStyle</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackDialog" parent="Theme.Leanback.GuidedStep">
+ <item name="guidedActionsContainerStyle">@style/DialogActionsContainerStyle</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackPreferences" parent="Theme.Leanback">
+ <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14</item>
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:backgroundDimEnabled">true</item>
+ <item name="android:colorPrimary">@color/settings_background</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackDetails" parent="Theme.Leanback.Details">
+ <item name="android:colorPrimary">@color/detail_view_actionbar_background</item>
+ <item name="android:windowBackground">@drawable/background_canyon</item>
+ </style>
+
+ <style name="Theme.Example.LeanbackMusic" parent="Theme.Example.Leanback">
+ <item name="android:windowBackground">@drawable/background_sax</item>
+ </style>
+
+</resources>
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..e69c4e2d5
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/app/src/main/res/xml/prefs.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:summary="This is a dummy activitiy only to show case how to build a settings in an application. Changing configurations in this example doesn't affect anything."
+ android:title="Settings Example">
+ <PreferenceScreen
+ android:icon="@drawable/ic_settings_wifi_4_bar"
+ android:key="prefs_wifi_screen_key"
+ android:title="Wi-Fi">
+ <PreferenceCategory
+ android:key="prefs_wifi_networks_key"
+ android:title="Available Wi-Fi networks">
+ <ListPreference
+ android:defaultValue="-1"
+ android:entries="@array/pref_wifi_networks"
+ android:entryValues="@array/pref_wifi_networks"
+ android:title="Available Wi-Fi networks"
+ android:key="prefs_wifi_key">
+ </ListPreference>
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="prefs_wifi_others_key"
+ android:title="Other options">
+ <Preference
+ android:title="Connect via WPS"
+ android:key="prefs_wifi_connect_wps"><!-- You can use Intents here -->
+ </Preference>
+ </PreferenceCategory>
+ </PreferenceScreen>
+ <PreferenceScreen
+ android:icon="@drawable/ic_settings_time"
+ android:key="prefs_date_time_screen_key"
+ android:title="Date &amp; time">
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:disableDependentsState="true"
+ android:key="prefs_date_time_automatic"
+ android:summaryOff="On"
+ android:summaryOn="Off"
+ android:title="Automatic date &amp; time"></CheckBoxPreference>
+ <Preference
+ android:dependency="prefs_date_time_automatic"
+ android:key="prefs_date"
+ android:summary="01/01/1970"
+ android:title="Date"></Preference>
+ <Preference
+ android:dependency="prefs_date_time_automatic"
+ android:key="prefs_time"
+ android:summary="00:43 PM"
+ android:title="Time"></Preference>
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:disableDependentsState="true"
+ android:key="prefs_date_time_use_timezone"
+ android:summary="Use network provided time zone"
+ android:title="Automatic time zone"></CheckBoxPreference>
+ <Preference
+ android:dependency="prefs_date_time_use_timezone"
+ android:summary="GMT 07:00 Pacific Daylight Time"
+ android:title="Time zone"></Preference>
+ </PreferenceScreen>
+ <ListPreference
+ android:defaultValue="everyone"
+ android:icon="@drawable/ic_settings_parental_control"
+ android:entries="@array/pref_parent_control_entries"
+ android:entryValues="@array/pref_parent_control_entries_values"
+ android:key="prefs_parental_control_level_key"
+ android:dialogMessage="Allow contents rated for"
+ android:title="Parental Control">
+ </ListPreference>
+ <PreferenceScreen
+ android:icon="@drawable/ic_settings_apps"
+ android:key="prefs_apps_screen_key"
+ android:title="Apps">
+ <PreferenceCategory
+ android:key="prefs_app_settings_category"
+ android:title="Apps settings">
+ <PreferenceScreen
+ android:key="prefs_app_settings_screen_key"
+ android:summary="Lorem ipsum dolor sit amet consectur adipiscing."
+ android:title="App permissions">
+ <Preference
+ android:icon="@mipmap/app_banner_sample_app"
+ android:summary="45.5 MB"
+ android:selectable="false"
+ android:title="Application A"></Preference>
+ <Preference
+ android:selectable="false"
+ android:summary="Hier steht ein voelligst sinnfreier Text den ja sowieso niemandhier lesen kann. Deshalb macht es auch keinen Unterschied ob hier sinnvolles und nicht so sinnvolles Zeug steht. Hm... Sasha, du kannst das vielleicht lesen und denkst dir jetzt auch, dass ich voll haengen geblieben bin, oder?... ^_^"></Preference>
+ <Preference
+ android:title="Force Stop"
+ android:key="pref_force_stop"><!-- Start an Intent --></Preference>
+ <Preference
+ android:title="Uninstall"
+ android:key="pref_uninstall"><!-- Start an Intent --></Preference>
+ <Preference
+ android:title="More Information"
+ android:key="pref_more_info"></Preference>
+ </PreferenceScreen>
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:key="prefs_app_downloaded_apps_category"
+ android:title="Downloaded Apps">
+ <ListPreference
+ android:defaultValue="everyone"
+ android:entries="@array/pref_parent_control_entries"
+ android:entryValues="@array/pref_parent_control_entries_values"
+ android:key="prefs_parental_control_level_key"
+ android:title="Downloaded Apps">
+ </ListPreference>
+ </PreferenceCategory>
+ </PreferenceScreen>
+</PreferenceScreen>
diff --git a/samples/SupportLeanbackShowcase/build.gradle b/samples/SupportLeanbackShowcase/build.gradle
new file mode 100644
index 000000000..dd5b172df
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/build.gradle
@@ -0,0 +1,20 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.2.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ maven { url "$System.env.LOCAL_REPO/out/host/gradle/frameworks/support/build/support_repo/"}
+ jcenter()
+ }
+}
diff --git a/samples/SupportLeanbackShowcase/gradle.properties b/samples/SupportLeanbackShowcase/gradle.properties
new file mode 100644
index 000000000..1d3591c8a
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true \ No newline at end of file
diff --git a/samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.jar b/samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..8c0fb64a8
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.properties b/samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..0c71e760d
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/samples/SupportLeanbackShowcase/gradlew b/samples/SupportLeanbackShowcase/gradlew
new file mode 100755
index 000000000..91a7e269e
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/samples/SupportLeanbackShowcase/gradlew.bat b/samples/SupportLeanbackShowcase/gradlew.bat
new file mode 100644
index 000000000..aec99730b
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/SupportLeanbackShowcase/settings.gradle b/samples/SupportLeanbackShowcase/settings.gradle
new file mode 100644
index 000000000..e7b4def49
--- /dev/null
+++ b/samples/SupportLeanbackShowcase/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/sdk/plat_tools_source.prop_template b/sdk/plat_tools_source.prop_template
index e846b1c00..811dad851 100644
--- a/sdk/plat_tools_source.prop_template
+++ b/sdk/plat_tools_source.prop_template
@@ -1,2 +1,2 @@
Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.1
diff --git a/sdk/platform_source.prop_template b/sdk/platform_source.prop_template
index 35a00af81..c97dd97d3 100644
--- a/sdk/platform_source.prop_template
+++ b/sdk/platform_source.prop_template
@@ -2,9 +2,9 @@ Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
Pkg.UserSrc=false
Platform.Version=${PLATFORM_VERSION}
Platform.CodeName=
-Pkg.Revision=1
+Pkg.Revision=2
AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
Layoutlib.Api=15
-Layoutlib.Revision=1
+Layoutlib.Revision=2
Platform.MinToolsRev=22
diff --git a/sdk/support_source.prop_template b/sdk/support_source.prop_template
index f89771291..03d6962fb 100644
--- a/sdk/support_source.prop_template
+++ b/sdk/support_source.prop_template
@@ -1,5 +1,5 @@
Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.1
+Pkg.Revision=${PLATFORM_SDK_VERSION}.1.1
Extra.Vendor=android
Extra.VendorId=android
Extra.VendorDisplay=Android
diff --git a/tools/recovery_l10n/res/values-gu-rIN/strings.xml b/tools/recovery_l10n/res/values-gu-rIN/strings.xml
deleted file mode 100644
index a364b523c..000000000
--- a/tools/recovery_l10n/res/values-gu-rIN/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recovery_installing" msgid="7864047928003865598">"સિસ્ટમ અપડેટ ઇન્સ્ટોલ કરી રહ્યાં છે…"</string>
- <string name="recovery_erasing" msgid="4612809744968710197">"કાઢી નાખી રહ્યાં છે…"</string>
- <string name="recovery_no_command" msgid="1915703879031023455">"કોઈ આદેશ નથી."</string>
- <string name="recovery_error" msgid="4550265746256727080">"ભૂલ!"</string>
-</resources>
diff --git a/tools/recovery_l10n/res/values-pt-rBR/strings.xml b/tools/recovery_l10n/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 3cc57234e..000000000
--- a/tools/recovery_l10n/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recovery_installing" msgid="7864047928003865598">"Instalando atualização do sistema..."</string>
- <string name="recovery_erasing" msgid="4612809744968710197">"Apagando..."</string>
- <string name="recovery_no_command" msgid="1915703879031023455">"Nenhum comando."</string>
- <string name="recovery_error" msgid="4550265746256727080">"Erro!"</string>
-</resources>
diff --git a/tools/recovery_l10n/res/values-sq-rAL/strings.xml b/tools/recovery_l10n/res/values-sq-rAL/strings.xml
deleted file mode 100644
index 29f8ef592..000000000
--- a/tools/recovery_l10n/res/values-sq-rAL/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recovery_installing" msgid="7864047928003865598">"Po instalon përditësimin e sistemit..."</string>
- <string name="recovery_erasing" msgid="4612809744968710197">"Po spastron..."</string>
- <string name="recovery_no_command" msgid="1915703879031023455">"Nuk ka komanda."</string>
- <string name="recovery_error" msgid="4550265746256727080">"Gabim!"</string>
-</resources>