MainFragment.java revision 01a567100c9b8120d590e9e9f4cc6395ab0159fe
158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell/* 258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * Copyright (C) 2016 The Android Open Source Project 358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * 458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * Licensed under the Apache License, Version 2.0 (the "License"); 558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * you may not use this file except in compliance with the License. 658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * You may obtain a copy of the License at 758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * 858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * http://www.apache.org/licenses/LICENSE-2.0 958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * 1058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * Unless required by applicable law or agreed to in writing, software 1158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * distributed under the License is distributed on an "AS IS" BASIS, 1258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * See the License for the specific language governing permissions and 1458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * limitations under the License 1558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell */ 1658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 1758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellpackage com.google.android.leanbackjank.ui; 1858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 1958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.content.Intent; 2058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.net.Uri; 2158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.os.Bundle; 2258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.app.BackgroundManager; 2358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.app.BrowseFragment; 2458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.widget.ArrayObjectAdapter; 2558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.widget.HeaderItem; 2658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.widget.ListRow; 2758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.widget.ListRowPresenter; 2858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.widget.Presenter; 2958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport android.support.v17.leanback.widget.PresenterSelector; 30a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikasimport android.support.v4.content.res.ResourcesCompat; 3158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 3258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.IntentDefaults; 3358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.IntentKeys; 3458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.R; 3558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.data.VideoProvider; 3658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.model.VideoInfo; 3758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.presenter.CardPresenter; 3858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.presenter.GridItemPresenter; 3958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport com.google.android.leanbackjank.presenter.HeaderItemPresenter; 4058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 4158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport java.util.HashMap; 4258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport java.util.List; 4358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellimport java.util.Map; 4458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 4558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell/** 4658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell * Main class to show BrowseFragment with header and rows of videos 4758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell */ 4858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassellpublic class MainFragment extends BrowseFragment { 4958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 5058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell private BackgroundManager mBackgroundManager; 5158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell private ArrayObjectAdapter mRowsAdapter; 5258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 5358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell @Override 5458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell public void onActivityCreated(Bundle savedInstanceState) { 5558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell super.onActivityCreated(savedInstanceState); 5658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 5758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell // Define defaults. 5858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell int categoryCount = IntentDefaults.CATEGORY_COUNT; 5958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell int entriesPerCat = IntentDefaults.ENTRIES_PER_CATEGORY; 6058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell boolean disableShadows = IntentDefaults.DISABLE_SHADOWS; 6158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell int cardWidth = IntentDefaults.CARD_WIDTH; 6258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell int cardHeight = IntentDefaults.CARD_HEIGHT; 63734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas int whichVideo = IntentDefaults.WHICH_VIDEO; 6458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell boolean useSingleBitmap = IntentDefaults.USE_SINGLE_BITMAP; 6558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 6658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell Intent intent = getActivity().getIntent(); 6758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell if (intent.getExtras() != null) { 6858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell categoryCount = intent.getIntExtra(IntentKeys.CATEGORY_COUNT, categoryCount); 6958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell entriesPerCat = intent.getIntExtra(IntentKeys.ENTRIES_PER_CATEGORY, entriesPerCat); 7058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell disableShadows = intent.getBooleanExtra(IntentKeys.DISABLE_SHADOWS, disableShadows); 7158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell cardWidth = intent.getIntExtra(IntentKeys.CARD_WIDTH, cardWidth); 7258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell cardHeight = intent.getIntExtra(IntentKeys.CARD_HEIGHT, cardHeight); 73734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas whichVideo = intent.getIntExtra(IntentKeys.WHICH_VIDEO, whichVideo); 7458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell useSingleBitmap = intent.getBooleanExtra(IntentKeys.USE_SINGLE_BITMAP, useSingleBitmap); 7558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 7658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 7758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell loadVideoData(categoryCount, entriesPerCat, disableShadows, useSingleBitmap, cardWidth, 7858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell cardHeight); 7958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setBackground(); 8058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setupUIElements(); 8158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 82734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas if (whichVideo != IntentKeys.NO_VIDEO) { 83734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas int resource = 0; 84734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas /* For info on how to generate videos see: 85734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas * https://docs.google.com/document/d/1HV8O-Nm4rc2DwVwiZmT4Wa9pf8XttWndg9saGncTRGw 86734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas */ 87734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas if (whichVideo == IntentKeys.VIDEO_2160P_60FPS) { 88734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas resource = R.raw.bbb_sunflower_2160p_60fps; 89734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas } else if (whichVideo == IntentKeys.VIDEO_1080P_60FPS) { 90734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas resource = R.raw.testvideo_1080p_60fps; 91734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas } else if (whichVideo == IntentKeys.VIDEO_480P_60FPS) { 92734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas resource = R.raw.bbb_480p; 93734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas } 94a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas Uri uri = Uri.parse("android.resource://" + getActivity().getPackageName() + "/" 95734bc41ce2a1f549a972bfda05ede02d969ebefbDaniel Cardenas + resource); 96a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas Intent videoIntent = new Intent(Intent.ACTION_VIEW, uri, getActivity(), 9758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell VideoActivity.class); 9858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell startActivity(videoIntent); 9958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 10058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 10158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 10258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell private void setBackground() { 10358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell mBackgroundManager = BackgroundManager.getInstance(getActivity()); 10458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell mBackgroundManager.attach(getActivity().getWindow()); 10558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell mBackgroundManager.setDrawable( 106a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas ResourcesCompat.getDrawable(getResources(), R.drawable.default_background, null)); 10758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 10858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 10958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell private void setupUIElements() { 110a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas setBadgeDrawable(ResourcesCompat.getDrawable( 111a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas getActivity().getResources(), R.drawable.app_banner, null)); 11258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell // Badge, when set, takes precedent over title 11358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setTitle(getString(R.string.browse_title)); 11458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setHeadersState(HEADERS_ENABLED); 11558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setHeadersTransitionOnBackEnabled(true); 11658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell // set headers background color 117a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas setBrandColor(ResourcesCompat.getColor(getResources(), R.color.jank_yellow, null)); 11858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell // set search icon color 119a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas setSearchAffordanceColor( 120a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas ResourcesCompat.getColor(getResources(), R.color.search_opaque, null)); 12158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 12258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setHeaderPresenterSelector(new PresenterSelector() { 12358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell @Override 12458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell public Presenter getPresenter(Object o) { 12558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell return new HeaderItemPresenter(); 12658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 12758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell }); 12858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 12958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 13058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell private void loadVideoData(int categoryCount, int entriesPerCat, boolean disableShadows, 13158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell boolean useSingleBitmap, int cardWidth, int cardHeight) { 13258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell ListRowPresenter listRowPresenter = new ListRowPresenter(); 13358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell listRowPresenter.setShadowEnabled(!disableShadows); 13401a567100c9b8120d590e9e9f4cc6395ab0159feDake Gu // see b/64451726, leanback bug causes child rounded corner is incorrectly disabled when 13501a567100c9b8120d590e9e9f4cc6395ab0159feDake Gu // shadow is disabled. To make the test data consistent and comparable, by default treat 13601a567100c9b8120d590e9e9f4cc6395ab0159feDake Gu // the rounded corner option same as shadow option. 13701a567100c9b8120d590e9e9f4cc6395ab0159feDake Gu boolean disableRoundedCorner = disableShadows; 13801a567100c9b8120d590e9e9f4cc6395ab0159feDake Gu listRowPresenter.enableChildRoundedCorners(!disableRoundedCorner); 13958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell mRowsAdapter = new ArrayObjectAdapter(listRowPresenter); 14058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell HashMap<String, List<VideoInfo>> data = VideoProvider.buildMedia(categoryCount, 141a3eaac19490539262eff7832eff880566c57cafcAurimas Liutikas entriesPerCat, cardWidth, cardHeight, getActivity(), useSingleBitmap); 14258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell CardPresenter cardPresenter = new CardPresenter(cardWidth, cardHeight); 14358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 14458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell int i = 0; 14558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell for (Map.Entry<String, List<VideoInfo>> entry : data.entrySet()) { 14658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); 14758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell for (VideoInfo videoInfo : entry.getValue()) { 14858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell listRowAdapter.add(videoInfo); 14958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 15058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell HeaderItem header = new HeaderItem(i++, entry.getKey()); 15158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell mRowsAdapter.add(new ListRow(header, listRowAdapter)); 15258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 15358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 15458b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell ArrayObjectAdapter settingsListAdapter = new ArrayObjectAdapter(new GridItemPresenter()); 15558b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell for (int j = 0; j < entriesPerCat; j++) { 15658b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell settingsListAdapter.add("Settings " + j); 15758b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 15858b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell HeaderItem settingsHeader = new HeaderItem(i++, "Settings"); 15958b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell mRowsAdapter.add(new ListRow(settingsHeader, settingsListAdapter)); 16058b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell 16158b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell setAdapter(mRowsAdapter); 16258b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell } 16358b7bbb83053e664ada2e1ace49f8960dfecdbfdBryan Cassell} 164