16193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu/* This file is auto-generated from BrowseFragment.java. DO NOT MODIFY. */ 26193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu 361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/* 461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Copyright (C) 2014 The Android Open Source Project 561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * in compliance with the License. You may obtain a copy of the License at 861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * http://www.apache.org/licenses/LICENSE-2.0 1061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 1161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License 1261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * or implied. See the License for the specific language governing permissions and limitations under 1461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the License. 1561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 1661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gupackage android.support.v17.leanback.app; 1761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 18bb0a680c10b84b83833a59634373140f8bd0750csusnataimport static android.support.v7.widget.RecyclerView.NO_POSITION; 19bb0a680c10b84b83833a59634373140f8bd0750csusnata 202f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v4.app.Fragment; 212f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v4.app.FragmentManager; 222f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v4.app.FragmentManager.BackStackEntry; 23bb0a680c10b84b83833a59634373140f8bd0750csusnataimport android.support.v4.app.FragmentTransaction; 242f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.content.res.TypedArray; 252f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.graphics.Color; 262f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.graphics.Rect; 272f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.os.Bundle; 2870acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt; 2961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.R; 3061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.transition.TransitionHelper; 3161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.transition.TransitionListener; 3261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.BrowseFrameLayout; 338ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Guimport android.support.v17.leanback.widget.InvisibleRowPresenter; 341c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnataimport android.support.v17.leanback.widget.ListRow; 352f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.ObjectAdapter; 3661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemViewClickedListener; 3761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemViewSelectedListener; 381c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnataimport android.support.v17.leanback.widget.PageRow; 3961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.Presenter; 4061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.PresenterSelector; 412f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.Row; 428df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Guimport android.support.v17.leanback.widget.RowHeaderPresenter; 4361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.RowPresenter; 44a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnataimport android.support.v17.leanback.widget.ScaleFrameLayout; 45a373804d10f93a9488adc35cf6ce44dce09b3778Dake Guimport android.support.v17.leanback.widget.TitleViewAdapter; 4661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.VerticalGridView; 478e3566285de4ac771d6188f62fe947e23d371a3dKris Giesingimport android.support.v4.view.ViewCompat; 48041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Guimport android.support.v7.widget.RecyclerView; 4961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.util.Log; 5061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.LayoutInflater; 5161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.View; 5261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup; 5361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup.MarginLayoutParams; 54a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnataimport android.view.ViewTreeObserver; 5561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 56fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basakimport java.util.HashMap; 57fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basakimport java.util.Map; 58fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 5961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/** 6061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A fragment for creating Leanback browse screens. It is composed of a 6161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * RowsSupportFragment and a HeadersSupportFragment. 6261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 6361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A BrowseSupportFragment renders the elements of its {@link ObjectAdapter} as a set 6461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of rows in a vertical list. The elements in this adapter must be subclasses 6561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of {@link Row}. 6661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 6761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * The HeadersSupportFragment can be set to be either shown or hidden by default, or 6861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * may be disabled entirely. See {@link #setHeadersState} for details. 6961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 7061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * By default the BrowseSupportFragment includes support for returning to the headers 7161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * when the user presses Back. For Activities that customize {@link 726193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu * android.support.v4.app.FragmentActivity#onBackPressed()}, you must disable this default Back key support by 7361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * calling {@link #setHeadersTransitionOnBackEnabled(boolean)} with false and 7461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * use {@link BrowseSupportFragment.BrowseTransitionListener} and 7561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #startHeadersTransition(boolean)}. 76a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p> 77a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * The recommended theme to use with a BrowseSupportFragment is 78a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link android.support.v17.leanback.R.style#Theme_Leanback_Browse}. 79a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p> 8061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 813f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gupublic class BrowseSupportFragment extends BaseSupportFragment { 8261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 8361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for saving header show/hide status when backstack is used: 8461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String HEADER_STACK_INDEX = "headerStackIndex"; 8561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for saving header show/hide status when backstack is not used: 8661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String HEADER_SHOW = "headerShow"; 87fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private static final String IS_PAGE_ROW = "isPageRow"; 88fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition"; 89e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout 9061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final class BackStackListener implements FragmentManager.OnBackStackChangedListener { 9161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mLastEntryCount; 9261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mIndexOfHeadersBackStack; 9361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 9461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackListener() { 9561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLastEntryCount = getFragmentManager().getBackStackEntryCount(); 9661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = -1; 9761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 9961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void load(Bundle savedInstanceState) { 10061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (savedInstanceState != null) { 10161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = savedInstanceState.getInt(HEADER_STACK_INDEX, -1); 10261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = mIndexOfHeadersBackStack == -1; 10361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 10461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingHeaders) { 10561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().beginTransaction() 10661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 10761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 11061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void save(Bundle outState) { 11261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putInt(HEADER_STACK_INDEX, mIndexOfHeadersBackStack); 11361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 11461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 11761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onBackStackChanged() { 11861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getFragmentManager() == null) { 11961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Log.w(TAG, "getFragmentManager() is null, stack:", new Exception()); 12061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 12161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 12261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int count = getFragmentManager().getBackStackEntryCount(); 12361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if backstack is growing and last pushed entry is "headers" backstack, 12461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // remember the index of the entry. 12561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (count > mLastEntryCount) { 12661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackEntry entry = getFragmentManager().getBackStackEntryAt(count - 1); 12761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mWithHeadersBackStackName.equals(entry.getName())) { 12861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = count - 1; 12961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 13061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (count < mLastEntryCount) { 13161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if popped "headers" backstack, initiate the show header transition if needed 13261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mIndexOfHeadersBackStack >= count) { 13369381509eace8e71ba4886e9e1e78cda62b66516Dake Gu if (!isHeadersDataReady()) { 13469381509eace8e71ba4886e9e1e78cda62b66516Dake Gu // if main fragment was restored first before BrowseSupportFragment's adapater gets 13569381509eace8e71ba4886e9e1e78cda62b66516Dake Gu // restored: dont start header transition, but add the entry back. 13669381509eace8e71ba4886e9e1e78cda62b66516Dake Gu getFragmentManager().beginTransaction() 13769381509eace8e71ba4886e9e1e78cda62b66516Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 13869381509eace8e71ba4886e9e1e78cda62b66516Dake Gu return; 13969381509eace8e71ba4886e9e1e78cda62b66516Dake Gu } 14061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = -1; 14161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingHeaders) { 14261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(true); 14361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLastEntryCount = count; 14761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 15061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 15161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Listener for transitions between browse headers and rows. 15261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 15361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static class BrowseTransitionListener { 15461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 15561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Callback when headers transition starts. 15661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 15761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the transition will result in headers 15861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * being shown, false otherwise. 15961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 16061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeadersTransitionStart(boolean withHeaders) { 16161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 16361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Callback when headers transition stops. 16461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 16561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the transition will result in headers 16661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * being shown, false otherwise. 16761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 16861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeadersTransitionStop(boolean withHeaders) { 16961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 17061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 17161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 172aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private class SetSelectionRunnable implements Runnable { 173aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout static final int TYPE_INVALID = -1; 174aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout static final int TYPE_INTERNAL_SYNC = 0; 175aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout static final int TYPE_USER_REQUEST = 1; 176aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 177aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private int mPosition; 178aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private int mType; 179aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private boolean mSmooth; 180aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 181aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout SetSelectionRunnable() { 182aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout reset(); 183aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 184aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 185aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout void post(int position, int type, boolean smooth) { 186aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // Posting the set selection, rather than calling it immediately, prevents an issue 187aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // with adapter changes. Example: a row is added before the current selected row; 188aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // first the fast lane view updates its selection, then the rows fragment has that 189aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // new selection propagated immediately; THEN the rows view processes the same adapter 190aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // change and moves the selection again. 191aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout if (type >= mType) { 192aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mPosition = position; 193aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mType = type; 194aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSmooth = smooth; 195aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mBrowseFrame.removeCallbacks(this); 196aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mBrowseFrame.post(this); 197aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 198aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 199aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 200aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout @Override 201aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout public void run() { 202aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout setSelection(mPosition, mSmooth); 203aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout reset(); 204aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 205aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 206aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private void reset() { 207aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mPosition = -1; 208aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mType = TYPE_INVALID; 209aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSmooth = false; 210aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 211aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 212aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 2131c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata /** 214cabb8eca86d0248274f57008ff66427fec2e927csusnata * Possible set of actions that {@link BrowseSupportFragment} exposes to clients. Custom 215cabb8eca86d0248274f57008ff66427fec2e927csusnata * fragments can interact with {@link BrowseSupportFragment} using this interface. 216cabb8eca86d0248274f57008ff66427fec2e927csusnata */ 217cabb8eca86d0248274f57008ff66427fec2e927csusnata public interface FragmentHost { 218cabb8eca86d0248274f57008ff66427fec2e927csusnata /** 219a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * Fragments are required to invoke this callback once their view is created 220a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * inside {@link Fragment#onViewCreated} method. {@link BrowseSupportFragment} starts the entrance 221cabb8eca86d0248274f57008ff66427fec2e927csusnata * animation only after receiving this callback. Failure to invoke this method 222cabb8eca86d0248274f57008ff66427fec2e927csusnata * will lead to fragment not showing up. 223cabb8eca86d0248274f57008ff66427fec2e927csusnata * 224cabb8eca86d0248274f57008ff66427fec2e927csusnata * @param fragmentAdapter {@link MainFragmentAdapter} used by the current fragment. 225cabb8eca86d0248274f57008ff66427fec2e927csusnata */ 226cabb8eca86d0248274f57008ff66427fec2e927csusnata void notifyViewCreated(MainFragmentAdapter fragmentAdapter); 2276fd4441435b14669deced90a05097dd5fe459acesusnata 2286fd4441435b14669deced90a05097dd5fe459acesusnata /** 229a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * Fragments mapped to {@link PageRow} are required to invoke this callback once their data 230a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * is created for transition, the entrance animation only after receiving this callback. 231a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * Failure to invoke this method will lead to fragment not showing up. 232a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * 233a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * @param fragmentAdapter {@link MainFragmentAdapter} used by the current fragment. 234a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu */ 235a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu void notifyDataReady(MainFragmentAdapter fragmentAdapter); 236a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 237a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu /** 238a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * Show or hide title view in {@link BrowseSupportFragment} for fragments mapped to 239a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * {@link PageRow}. Otherwise the request is ignored, in that case BrowseSupportFragment is fully 240a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * in control of showing/hiding title view. 241a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * <p> 242a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * When HeadersSupportFragment is visible, BrowseSupportFragment will hide search affordance view if 243a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * there are other focusable rows above currently focused row. 2446fd4441435b14669deced90a05097dd5fe459acesusnata * 2456fd4441435b14669deced90a05097dd5fe459acesusnata * @param show Boolean indicating whether or not to show the title view. 2466fd4441435b14669deced90a05097dd5fe459acesusnata */ 2476fd4441435b14669deced90a05097dd5fe459acesusnata void showTitleView(boolean show); 248cabb8eca86d0248274f57008ff66427fec2e927csusnata } 249cabb8eca86d0248274f57008ff66427fec2e927csusnata 250cabb8eca86d0248274f57008ff66427fec2e927csusnata /** 251cabb8eca86d0248274f57008ff66427fec2e927csusnata * Default implementation of {@link FragmentHost} that is used only by 252cabb8eca86d0248274f57008ff66427fec2e927csusnata * {@link BrowseSupportFragment}. 253cabb8eca86d0248274f57008ff66427fec2e927csusnata */ 254cabb8eca86d0248274f57008ff66427fec2e927csusnata private final class FragmentHostImpl implements FragmentHost { 2557350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata boolean mShowTitleView = true; 256a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu boolean mDataReady = false; 257cabb8eca86d0248274f57008ff66427fec2e927csusnata 258cabb8eca86d0248274f57008ff66427fec2e927csusnata @Override 259cabb8eca86d0248274f57008ff66427fec2e927csusnata public void notifyViewCreated(MainFragmentAdapter fragmentAdapter) { 260a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu performPendingStates(); 261a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu } 262a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 263a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu @Override 264a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu public void notifyDataReady(MainFragmentAdapter fragmentAdapter) { 265a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu mDataReady = true; 266a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 267a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu // If fragment host is not the currently active fragment (in BrowseSupportFragment), then 268a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu // ignore the request. 269a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu if (mMainFragmentAdapter == null || mMainFragmentAdapter.getFragmentHost() != this) { 270a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu return; 271a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu } 272a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 273a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu // We only honor showTitle request for PageRows. 274a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu if (!mIsPageRow) { 275a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu return; 276a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu } 277a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 278a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu performPendingStates(); 279cabb8eca86d0248274f57008ff66427fec2e927csusnata } 2806fd4441435b14669deced90a05097dd5fe459acesusnata 2816fd4441435b14669deced90a05097dd5fe459acesusnata @Override 2826fd4441435b14669deced90a05097dd5fe459acesusnata public void showTitleView(boolean show) { 2837350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata mShowTitleView = show; 284d0fc2e48059f718676a531af06a31849f54c1ca9susnata 285d0fc2e48059f718676a531af06a31849f54c1ca9susnata // If fragment host is not the currently active fragment (in BrowseSupportFragment), then 286d0fc2e48059f718676a531af06a31849f54c1ca9susnata // ignore the request. 287d0fc2e48059f718676a531af06a31849f54c1ca9susnata if (mMainFragmentAdapter == null || mMainFragmentAdapter.getFragmentHost() != this) { 288d0fc2e48059f718676a531af06a31849f54c1ca9susnata return; 289b10ba3b01290ce801180a3d5dc992825af8cb3absusnata } 290d0fc2e48059f718676a531af06a31849f54c1ca9susnata 291d0fc2e48059f718676a531af06a31849f54c1ca9susnata // We only honor showTitle request for PageRows. 292d0fc2e48059f718676a531af06a31849f54c1ca9susnata if (!mIsPageRow) { 293d0fc2e48059f718676a531af06a31849f54c1ca9susnata return; 294d0fc2e48059f718676a531af06a31849f54c1ca9susnata } 295d0fc2e48059f718676a531af06a31849f54c1ca9susnata 2968ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu updateTitleViewVisibility(); 2976fd4441435b14669deced90a05097dd5fe459acesusnata } 298cabb8eca86d0248274f57008ff66427fec2e927csusnata } 299cabb8eca86d0248274f57008ff66427fec2e927csusnata 300cabb8eca86d0248274f57008ff66427fec2e927csusnata /** 3011c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * Interface that defines the interaction between {@link BrowseSupportFragment} and it's main 302fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * content fragment. The key method is {@link MainFragmentAdapter#getFragment()}, 3031c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * it will be used to get the fragment to be shown in the content section. Clients can 3041c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * provide any implementation of fragment and customize it's interaction with 3051c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * {@link BrowseSupportFragment} by overriding the necessary methods. 3061c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * 3071c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * <p> 3081c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * Clients are expected to provide 309fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * an instance of {@link MainFragmentAdapterRegistry} which will be responsible for providing 310fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * implementations of {@link MainFragmentAdapter} for given content types. Currently 3111c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * we support different types of content - {@link ListRow}, {@link PageRow} or any subtype 3121c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * of {@link Row}. We provide an out of the box adapter implementation for any rows other than 313fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * {@link PageRow} - {@link android.support.v17.leanback.app.RowsSupportFragment.MainFragmentAdapter}. 3141c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * 3151c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * <p> 3161c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * {@link PageRow} is intended to give full flexibility to developers in terms of Fragment 317fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * design. Users will have to provide an implementation of {@link MainFragmentAdapter} 318fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * and provide that through {@link MainFragmentAdapterRegistry}. 319fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * {@link MainFragmentAdapter} implementation can supply any fragment and override 3201c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * just those interactions that makes sense. 3211c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata */ 322fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public static class MainFragmentAdapter<T extends Fragment> { 323f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata private boolean mScalingEnabled; 324fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private final T mFragment; 325d0fc2e48059f718676a531af06a31849f54c1ca9susnata private FragmentHostImpl mFragmentHost; 326fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 327fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public MainFragmentAdapter(T fragment) { 328fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak this.mFragment = fragment; 329fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 330fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 331fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final T getFragment() { 332fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return mFragment; 333fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 3342f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3352f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3362f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Returns whether its scrolling. 3372f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3381c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public boolean isScrolling() { 3391c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return false; 3401c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3412f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3422f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3432f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Set the visibility of titles/hovercard of browse rows. 3442f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3451c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void setExpand(boolean expand) { 3461c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3472f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3482f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3492f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * For rows that willing to participate entrance transition, this function 3502f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * hide views if afterTransition is true, show views if afterTransition is false. 3512f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3521c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void setEntranceTransitionState(boolean state) { 3531c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3542f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3552f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3562f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Sets the window alignment and also the pivots for scale operation. 3572f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3581c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void setAlignment(int windowAlignOffsetFromTop) { 3591c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3602f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3612f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3622f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Callback indicating transition prepare start. 3632f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3641c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public boolean onTransitionPrepare() { 3651c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return false; 3661c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3672f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3682f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3692f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Callback indicating transition start. 3702f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3711c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void onTransitionStart() { 3721c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3732f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3742f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3752f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Callback indicating transition end. 3762f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3771c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void onTransitionEnd() { 3781c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 379f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata 380f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata /** 381f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * Returns whether row scaling is enabled. 382f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata */ 383f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata public boolean isScalingEnabled() { 384f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata return mScalingEnabled; 385f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata } 386f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata 387f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata /** 388f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * Sets the row scaling property. 389f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata */ 390f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata public void setScalingEnabled(boolean scalingEnabled) { 391f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata this.mScalingEnabled = scalingEnabled; 392f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata } 393cabb8eca86d0248274f57008ff66427fec2e927csusnata 3947350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata /** 3957350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata * Returns the current host interface so that main fragment can interact with 3967350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata * {@link BrowseSupportFragment}. 3977350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata */ 398cabb8eca86d0248274f57008ff66427fec2e927csusnata public final FragmentHost getFragmentHost() { 399cabb8eca86d0248274f57008ff66427fec2e927csusnata return mFragmentHost; 400cabb8eca86d0248274f57008ff66427fec2e927csusnata } 4017350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 4027350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata void setFragmentHost(FragmentHostImpl fragmentHost) { 4037350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata this.mFragmentHost = fragmentHost; 4047350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata } 4052f5ebf3f6f7bb6a24856f389e369b247118ba119susnata } 4062f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4071c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata /** 408d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Interface to be implemented by all fragments for providing an instance of 409d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * {@link MainFragmentAdapter}. Both {@link RowsSupportFragment} and custom fragment provided 410d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * against {@link PageRow} will need to implement this interface. 411d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 412d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata public interface MainFragmentAdapterProvider { 413d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 414d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Returns an instance of {@link MainFragmentAdapter} that {@link BrowseSupportFragment} 415d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * would use to communicate with the target fragment. 416d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 417d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata MainFragmentAdapter getMainFragmentAdapter(); 418d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 419d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 420d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 421d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Interface to be implemented by {@link RowsSupportFragment} and it's subclasses for providing 422d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * an instance of {@link MainFragmentRowsAdapter}. 423d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 424d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata public interface MainFragmentRowsAdapterProvider { 425d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 426d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Returns an instance of {@link MainFragmentRowsAdapter} that {@link BrowseSupportFragment} 427d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * would use to communicate with the target fragment. 428d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 429d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata MainFragmentRowsAdapter getMainFragmentRowsAdapter(); 430d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 431d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 432d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 433d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * This is used to pass information to {@link RowsSupportFragment} or its subclasses. 434d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * {@link BrowseSupportFragment} uses this interface to pass row based interaction events to 435d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * the target fragment. 4361c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata */ 437fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public static class MainFragmentRowsAdapter<T extends Fragment> { 438fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private final T mFragment; 439fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 440fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public MainFragmentRowsAdapter(T fragment) { 441fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (fragment == null) { 442fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak throw new IllegalArgumentException("Fragment can't be null"); 443fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 444fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak this.mFragment = fragment; 445fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 446fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 447fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final T getFragment() { 448fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return mFragment; 449fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 450a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 451a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Set the visibility titles/hover of browse rows. 452a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 453a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setAdapter(ObjectAdapter adapter) { 454a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 4551c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 456a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 457a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Sets an item clicked listener on the fragment. 458a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 459a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 460a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 461a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 462a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 463a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Sets an item selection listener. 464a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 465a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 466a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 467a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 468a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 469a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Selects a Row and perform an optional task on the Row. 470a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 471a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setSelectedPosition(int rowPosition, 472a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata boolean smooth, 473a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata final Presenter.ViewHolderTask rowHolderTask) { 474a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 475a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 476a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 477a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Selects a Row. 478a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 479a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setSelectedPosition(int rowPosition, boolean smooth) { 480a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 481a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 482a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 483a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Returns the selected position. 484a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 485a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public int getSelectedPosition() { 486a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata return 0; 487a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 488a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 4891c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 490a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata private boolean createMainFragment(ObjectAdapter adapter, int position) { 491a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata Object item = null; 492a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata if (adapter == null || adapter.size() == 0) { 493fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return false; 494a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } else { 495bb0a680c10b84b83833a59634373140f8bd0750csusnata if (position < 0) { 496bb0a680c10b84b83833a59634373140f8bd0750csusnata position = 0; 497bb0a680c10b84b83833a59634373140f8bd0750csusnata } else if (position >= adapter.size()) { 4981c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata throw new IllegalArgumentException( 4991c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata String.format("Invalid position %d requested", position)); 5001c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 501a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata item = adapter.get(position); 502a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 5031c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 504a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu mSelectedPosition = position; 505fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak boolean oldIsPageRow = mIsPageRow; 506fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mIsPageRow = item instanceof PageRow; 507fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak boolean swap; 508fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 509fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragment == null) { 510fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak swap = true; 511a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } else { 512fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (oldIsPageRow) { 513fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak swap = true; 514fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } else { 515fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak swap = mIsPageRow; 516fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 5171c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 518fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 519fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (swap) { 520fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragment = mMainFragmentAdapterRegistry.createFragment(item); 521d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata if (!(mMainFragment instanceof MainFragmentAdapterProvider)) { 522d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata throw new IllegalArgumentException( 523d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata "Fragment must implement MainFragmentAdapterProvider"); 524d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 525d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 526d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentAdapter = ((MainFragmentAdapterProvider)mMainFragment) 527d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentAdapter(); 528cabb8eca86d0248274f57008ff66427fec2e927csusnata mMainFragmentAdapter.setFragmentHost(new FragmentHostImpl()); 529fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (!mIsPageRow) { 530d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata if (mMainFragment instanceof MainFragmentRowsAdapterProvider) { 531d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = ((MainFragmentRowsAdapterProvider)mMainFragment) 532d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentRowsAdapter(); 533d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } else { 534d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = null; 535d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 536fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mIsPageRow = mMainFragmentRowsAdapter == null; 537fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } else { 538fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter = null; 539fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 540fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 541d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 542fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return swap; 543a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 544a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 545a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 546fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * Factory class responsible for creating fragment given the current item. {@link ListRow} 547fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * should returns {@link RowsSupportFragment} or it's subclass whereas {@link PageRow} 548fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * can return any fragment class. 549a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 550fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public abstract static class FragmentFactory<T extends Fragment> { 551fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public abstract T createFragment(Object row); 552fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 5531c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 554fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak /** 555fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * FragmentFactory implementation for {@link ListRow}. 556fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak */ 557fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public static class ListRowFragmentFactory extends FragmentFactory<RowsSupportFragment> { 558fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak @Override 559fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public RowsSupportFragment createFragment(Object row) { 560fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return new RowsSupportFragment(); 56180a1d2dfbe5c1f26370cc1753c3ae321f126f5d2Carlos Valdivia } 562fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 5634400ca12ff731a7392715bc3d8ad3539b4c37889susnata 564fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak /** 565fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * Registry class maintaining the mapping of {@link Row} subclasses to {@link FragmentFactory}. 566fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * BrowseRowFragment automatically registers {@link ListRowFragmentFactory} for 567fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * handling {@link ListRow}. Developers can override that and also if they want to 568fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * use custom fragment, they can register a custom {@link FragmentFactory} 569fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * against {@link PageRow}. 570fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak */ 571fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final static class MainFragmentAdapterRegistry { 572cfcb31c4895793dda843faf67d1b769268e3cce8susnata private final Map<Class, FragmentFactory> mItemToFragmentFactoryMapping = new HashMap(); 573cfcb31c4895793dda843faf67d1b769268e3cce8susnata private final static FragmentFactory sDefaultFragmentFactory = new ListRowFragmentFactory(); 574cfcb31c4895793dda843faf67d1b769268e3cce8susnata 575cfcb31c4895793dda843faf67d1b769268e3cce8susnata public MainFragmentAdapterRegistry() { 576cfcb31c4895793dda843faf67d1b769268e3cce8susnata registerFragment(ListRow.class, sDefaultFragmentFactory); 577cfcb31c4895793dda843faf67d1b769268e3cce8susnata } 578fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 579fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public void registerFragment(Class rowClass, FragmentFactory factory) { 580cfcb31c4895793dda843faf67d1b769268e3cce8susnata mItemToFragmentFactoryMapping.put(rowClass, factory); 581fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 582fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 583fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public Fragment createFragment(Object item) { 584fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (item == null) { 585fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak throw new IllegalArgumentException("Item can't be null"); 586fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 587fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 588cfcb31c4895793dda843faf67d1b769268e3cce8susnata FragmentFactory fragmentFactory = mItemToFragmentFactoryMapping.get(item.getClass()); 589cfcb31c4895793dda843faf67d1b769268e3cce8susnata if (fragmentFactory == null && !(item instanceof PageRow)) { 590cfcb31c4895793dda843faf67d1b769268e3cce8susnata fragmentFactory = sDefaultFragmentFactory; 591cfcb31c4895793dda843faf67d1b769268e3cce8susnata } 592cfcb31c4895793dda843faf67d1b769268e3cce8susnata 593cfcb31c4895793dda843faf67d1b769268e3cce8susnata return fragmentFactory.createFragment(item); 594a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 5951c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 5962f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 59761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String TAG = "BrowseSupportFragment"; 59861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 59961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String LB_HEADERS_BACKSTACK = "lbHeadersBackStack_"; 60061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static boolean DEBUG = false; 60261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is enabled and shown by default. */ 60461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_ENABLED = 1; 60561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is enabled and hidden by default. */ 60761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_HIDDEN = 2; 60861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is disabled and will never be shown. */ 61061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_DISABLED = 3; 61161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 612fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private MainFragmentAdapterRegistry mMainFragmentAdapterRegistry 613fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak = new MainFragmentAdapterRegistry(); 614fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private MainFragmentAdapter mMainFragmentAdapter; 6151c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata private Fragment mMainFragment; 61661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private HeadersSupportFragment mHeadersSupportFragment; 617fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private MainFragmentRowsAdapter mMainFragmentRowsAdapter; 61861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 61961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ObjectAdapter mAdapter; 6208ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private PresenterSelector mAdapterPresenter; 6218ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private PresenterSelector mWrappingPresenterSelector; 62261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 62361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mHeadersState = HEADERS_ENABLED; 62461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBrandColor = Color.TRANSPARENT; 62561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mBrandColorSet; 62661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 62761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private BrowseFrameLayout mBrowseFrame; 628a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private ScaleFrameLayout mScaleFrameLayout; 62961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mHeadersBackStackEnabled = true; 63061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private String mWithHeadersBackStackName; 63161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mShowingHeaders = true; 63261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mCanShowHeaders = true; 6338e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing private int mContainerListMarginStart; 63461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mContainerListAlignTop; 635f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata private boolean mMainFragmentScaleEnabled = true; 63661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemViewSelectedListener mExternalOnItemViewSelectedListener; 63761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemViewClickedListener mOnItemViewClickedListener; 638bb0a680c10b84b83833a59634373140f8bd0750csusnata private int mSelectedPosition = -1; 639f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata private float mScaleFactor; 640fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private boolean mIsPageRow; 64161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 64261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private PresenterSelector mHeaderPresenterSelector; 643aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private final SetSelectionRunnable mSetSelectionRunnable = new SetSelectionRunnable(); 64461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 64561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // transition related: 64661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mSceneWithHeaders; 64761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mSceneWithoutHeaders; 648c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private Object mSceneAfterEntranceTransition; 64961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mHeadersTransition; 65061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private BackStackListener mBackStackChangedListener; 65161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private BrowseTransitionListener mBrowseTransitionListener; 65261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 65361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_TITLE = BrowseSupportFragment.class.getCanonicalName() + ".title"; 65461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_HEADERS_STATE = 65561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BrowseSupportFragment.class.getCanonicalName() + ".headersState"; 65661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 65761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 658a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Creates arguments for a browse fragment. 65961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 66061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param args The Bundle to place arguments into, or null if the method 66161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * should return a new Bundle. 66261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param title The title of the BrowseSupportFragment. 66361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headersState The initial state of the headers of the 66461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * BrowseSupportFragment. Must be one of {@link #HEADERS_ENABLED}, {@link 66561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * #HEADERS_HIDDEN}, or {@link #HEADERS_DISABLED}. 66661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @return A Bundle with the given arguments for creating a BrowseSupportFragment. 66761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 66861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static Bundle createArgs(Bundle args, String title, int headersState) { 66961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args == null) { 67061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args = new Bundle(); 67161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 67261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args.putString(ARG_TITLE, title); 67361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args.putInt(ARG_HEADERS_STATE, headersState); 67461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return args; 67561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 67661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 67761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 67861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the brand color for the browse fragment. The brand color is used as 67961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the primary color for UI elements in the browse fragment. For example, 68061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the background color of the headers fragment uses the brand color. 68161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 68261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param color The color to use as the brand color of the fragment. 68361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 68470acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye public void setBrandColor(@ColorInt int color) { 68561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrandColor = color; 68661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrandColorSet = true; 68761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 68961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setBackgroundColor(mBrandColor); 69061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 69161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 69261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 69361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 69461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the brand color for the browse fragment. 69561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * The default is transparent. 69661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 69770acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye @ColorInt 69861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getBrandColor() { 69961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mBrandColor; 70061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 70161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 70261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 7038ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu * Wrapping app provided PresenterSelector to support InvisibleRowPresenter for SectionRow 7048ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu * DividerRow and PageRow. 7058ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu */ 7068ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private void createAndSetWrapperPresenter() { 7078ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final PresenterSelector adapterPresenter = mAdapter.getPresenterSelector(); 7088ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (adapterPresenter == null) { 7098ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu throw new IllegalArgumentException("Adapter.getPresenterSelector() is null"); 7108ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7118ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (adapterPresenter == mAdapterPresenter) { 7128ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return; 7138ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7148ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu mAdapterPresenter = adapterPresenter; 7158ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 7168ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu Presenter[] presenters = adapterPresenter.getPresenters(); 7178ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Presenter invisibleRowPresenter = new InvisibleRowPresenter(); 7188ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Presenter[] allPresenters = new Presenter[presenters.length + 1]; 7198ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu System.arraycopy(allPresenters, 0, presenters, 0, presenters.length); 7208ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu allPresenters[allPresenters.length - 1] = invisibleRowPresenter; 7218ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu mAdapter.setPresenterSelector(new PresenterSelector() { 7228ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu @Override 7238ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu public Presenter getPresenter(Object item) { 7248ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu Row row = (Row) item; 7258ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (row.isRenderedAsRowView()) { 7268ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return adapterPresenter.getPresenter(item); 7278ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 7288ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return invisibleRowPresenter; 7298ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7308ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7318ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 7328ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu @Override 7338ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu public Presenter[] getPresenters() { 7348ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return allPresenters; 7358ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7368ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu }); 7378ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7388ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 7398ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu /** 74061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the adapter containing the rows for the fragment. 74161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 74261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>The items referenced by the adapter must be be derived from 74361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link Row}. These rows will be used by the rows fragment and the headers 74461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * fragment (if not disabled) to render the browse rows. 74561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 74661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param adapter An ObjectAdapter for the browse rows. All items must 74761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * derive from {@link Row}. 74861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 74961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setAdapter(ObjectAdapter adapter) { 75061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mAdapter = adapter; 7518ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu createAndSetWrapperPresenter(); 752c0ad3d1d9ee64cf0bdb68ac70bfb04cc919c53e6Dake Gu if (getView() == null) { 753c0ad3d1d9ee64cf0bdb68ac70bfb04cc919c53e6Dake Gu return; 754c0ad3d1d9ee64cf0bdb68ac70bfb04cc919c53e6Dake Gu } 755bb0a680c10b84b83833a59634373140f8bd0750csusnata replaceMainFragment(mSelectedPosition); 756bb0a680c10b84b83833a59634373140f8bd0750csusnata 757bb0a680c10b84b83833a59634373140f8bd0750csusnata if (adapter != null) { 758bb0a680c10b84b83833a59634373140f8bd0750csusnata if (mMainFragmentRowsAdapter != null) { 759bb0a680c10b84b83833a59634373140f8bd0750csusnata mMainFragmentRowsAdapter.setAdapter(adapter); 760bb0a680c10b84b83833a59634373140f8bd0750csusnata } 76161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setAdapter(adapter); 76261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 76361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 76461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 765fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final MainFragmentAdapterRegistry getMainFragmentRegistry() { 766fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return mMainFragmentAdapterRegistry; 7671c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 768fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 76961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 77061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the adapter containing the rows for the fragment. 77161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 77261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public ObjectAdapter getAdapter() { 77361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mAdapter; 77461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 77561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 77661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 77761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item selection listener. 77861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 77961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 78061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemViewSelectedListener = listener; 78161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 78261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 78361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 78461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns an item selection listener. 78561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 78661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemViewSelectedListener getOnItemViewSelectedListener() { 78761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mExternalOnItemViewSelectedListener; 78861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 78961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 79061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 7911c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * Get RowsSupportFragment if it's bound to BrowseSupportFragment or null if either BrowseSupportFragment has 7921c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * not been created yet or a different fragment is bound to it. 7931c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * 7941c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * @return RowsSupportFragment if it's bound to BrowseSupportFragment or null otherwise. 7950d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 7960d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public RowsSupportFragment getRowsSupportFragment() { 7971c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata if (mMainFragment instanceof RowsSupportFragment) { 7981c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return (RowsSupportFragment) mMainFragment; 7991c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 8001c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 8011c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return null; 8020d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 8030d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 8040d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 8050d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * Get currently bound HeadersSupportFragment or null if HeadersSupportFragment has not been created yet. 8060d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @return Currently bound HeadersSupportFragment or null if HeadersSupportFragment has not been created yet. 8070d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 8080d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public HeadersSupportFragment getHeadersSupportFragment() { 8090d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu return mHeadersSupportFragment; 8100d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 8110d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 8120d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 81361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item clicked listener on the fragment. 81461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * OnItemViewClickedListener will override {@link View.OnClickListener} that 81561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}. 816cabb8eca86d0248274f57008ff66427fec2e927csusnata * So in general, developer should choose one of the listeners but not both. 81761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 81861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 81961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOnItemViewClickedListener = listener; 8202aff8659c7362b48f099a13ffad390bf7984dd5aJaewan Kim if (mMainFragmentRowsAdapter != null) { 821fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setOnItemViewClickedListener(listener); 82261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 82361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 82461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 82561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 82661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the item Clicked listener. 82761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 82861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemViewClickedListener getOnItemViewClickedListener() { 82961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mOnItemViewClickedListener; 83061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 83161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 83261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 833a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Starts a headers transition. 83461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 83561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>This method will begin a transition to either show or hide the 83661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * headers, depending on the value of withHeaders. If headers are disabled 83761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * for this browse fragment, this method will throw an exception. 83861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 83961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the headers should transition to being shown, 84061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * false if the transition should result in headers being hidden. 84161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 84261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void startHeadersTransition(boolean withHeaders) { 84361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders) { 84461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalStateException("Cannot start headers transition"); 84561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 84661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (isInHeadersTransition() || mShowingHeaders == withHeaders) { 84761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 84861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 84961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(withHeaders); 85061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 85161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 85261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 85361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if the headers transition is currently running. 85461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 85561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isInHeadersTransition() { 85661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersTransition != null; 85761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 85861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 85961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 86061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if headers are shown. 86161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 86261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isShowingHeaders() { 86361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mShowingHeaders; 86461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 86561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 86661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 867a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Sets a listener for browse fragment transitions. 86861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 86961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param listener The listener to call when a browse headers transition 87061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * begins or ends. 87161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 87261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setBrowseTransitionListener(BrowseTransitionListener listener) { 87361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener = listener; 87461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 87561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 87661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 877f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * @deprecated use {@link BrowseSupportFragment#enableMainFragmentScaling(boolean)} instead. 87861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 87961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param enable true to enable row scaling 88061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 881d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette @Deprecated 88261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void enableRowScaling(boolean enable) { 883f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata enableMainFragmentScaling(enable); 884f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata } 885f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata 886f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata /** 887f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * Enables scaling of main fragment when headers are present. For the page/row fragment, 888f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * scaling is enabled only when both this method and 889fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * {@link MainFragmentAdapter#isScalingEnabled()} are enabled. 890f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * 891f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * @param enable true to enable row scaling 892f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata */ 893f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata public void enableMainFragmentScaling(boolean enable) { 894f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata mMainFragmentScaleEnabled = enable; 89561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 89661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 89761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void startHeadersTransitionInternal(final boolean withHeaders) { 89861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getFragmentManager().isDestroyed()) { 89961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 90061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 90169381509eace8e71ba4886e9e1e78cda62b66516Dake Gu if (!isHeadersDataReady()) { 90269381509eace8e71ba4886e9e1e78cda62b66516Dake Gu return; 90369381509eace8e71ba4886e9e1e78cda62b66516Dake Gu } 90461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = withHeaders; 9051c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionPrepare(); 9061c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionStart(); 907a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata onExpandTransitionStart(!withHeaders, new Runnable() { 90861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 90961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 910902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu mHeadersSupportFragment.onTransitionPrepare(); 91161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.onTransitionStart(); 91261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu createHeadersTransition(); 91361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrowseTransitionListener != null) { 91461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener.onHeadersTransitionStart(withHeaders); 91561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9161c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata TransitionHelper.runTransition( 9171c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata withHeaders ? mSceneWithHeaders : mSceneWithoutHeaders, mHeadersTransition); 91861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersBackStackEnabled) { 91961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!withHeaders) { 92061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().beginTransaction() 92161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 92261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 92361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int index = mBackStackChangedListener.mIndexOfHeadersBackStack; 92461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (index >= 0) { 92561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackEntry entry = getFragmentManager().getBackStackEntryAt(index); 92661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().popBackStackImmediate(entry.getId(), 92761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu FragmentManager.POP_BACK_STACK_INCLUSIVE); 92861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 92961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 93361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 9350d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu boolean isVerticalScrolling() { 93661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // don't run transition 9371c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return mHeadersSupportFragment.isScrolling() || mMainFragmentAdapter.isScrolling(); 93861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 940e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout 94161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener = 94261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new BrowseFrameLayout.OnFocusSearchListener() { 94361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 94461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onFocusSearch(View focused, int direction) { 94561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if headers is running transition, focus stays 9465ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout if (mCanShowHeaders && isInHeadersTransition()) { 9475ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout return focused; 9485ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout } 94961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction); 9505ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout 951e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (getTitleView() != null && focused != getTitleView() && 952e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout direction == View.FOCUS_UP) { 953e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout return getTitleView(); 954e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout } 955e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (getTitleView() != null && getTitleView().hasFocus() && 956e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout direction == View.FOCUS_DOWN) { 9575ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout return mCanShowHeaders && mShowingHeaders ? 9581c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mHeadersSupportFragment.getVerticalGridView() : mMainFragment.getView(); 9595ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout } 9605ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout 9618e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing boolean isRtl = ViewCompat.getLayoutDirection(focused) == View.LAYOUT_DIRECTION_RTL; 9628e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing int towardStart = isRtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT; 9638e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing int towardEnd = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT; 964e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (mCanShowHeaders && direction == towardStart) { 96569381509eace8e71ba4886e9e1e78cda62b66516Dake Gu if (isVerticalScrolling() || mShowingHeaders || !isHeadersDataReady()) { 96661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return focused; 96761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 96861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersSupportFragment.getVerticalGridView(); 9698e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing } else if (direction == towardEnd) { 970e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (isVerticalScrolling()) { 97161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return focused; 97261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9731c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return mMainFragment.getView(); 9748ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else if (direction == View.FOCUS_DOWN && mShowingHeaders) { 9758ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // disable focus_down moving into PageFragment. 9768ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return focused; 97761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 97861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return null; 97961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 98061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 98161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 98261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 98369381509eace8e71ba4886e9e1e78cda62b66516Dake Gu private final boolean isHeadersDataReady() { 98469381509eace8e71ba4886e9e1e78cda62b66516Dake Gu return mAdapter != null && mAdapter.size() != 0; 98569381509eace8e71ba4886e9e1e78cda62b66516Dake Gu } 98669381509eace8e71ba4886e9e1e78cda62b66516Dake Gu 98761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final BrowseFrameLayout.OnChildFocusListener mOnChildFocusListener = 98861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new BrowseFrameLayout.OnChildFocusListener() { 98961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 99061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 99161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 99228fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu if (getChildFragmentManager().isDestroyed()) { 99328fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu return true; 99428fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu } 99561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Make sure not changing focus when requestFocus() is called. 99661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders && mShowingHeaders) { 9977fd35190a1f0fd92f1275324b23708b5a2087a76Craig Stout if (mHeadersSupportFragment != null && mHeadersSupportFragment.getView() != null && 9987fd35190a1f0fd92f1275324b23708b5a2087a76Craig Stout mHeadersSupportFragment.getView().requestFocus(direction, previouslyFocusedRect)) { 99961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return true; 100061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10021c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata if (mMainFragment != null && mMainFragment.getView() != null && 10031c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragment.getView().requestFocus(direction, previouslyFocusedRect)) { 100461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return true; 100561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1006e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (getTitleView() != null && 1007e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout getTitleView().requestFocus(direction, previouslyFocusedRect)) { 10087fd35190a1f0fd92f1275324b23708b5a2087a76Craig Stout return true; 10097fd35190a1f0fd92f1275324b23708b5a2087a76Craig Stout } 10107fd35190a1f0fd92f1275324b23708b5a2087a76Craig Stout return false; 10111c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 101261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 101361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 101461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onRequestChildFocus(View child, View focused) { 101528fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu if (getChildFragmentManager().isDestroyed()) { 101628fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu return; 101728fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu } 101861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders || isInHeadersTransition()) return; 101928fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu int childId = child.getId(); 102061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (childId == R.id.browse_container_dock && mShowingHeaders) { 102161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(false); 102261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (childId == R.id.browse_headers_dock && !mShowingHeaders) { 102361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(true); 102461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 102561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 102661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 102761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 102861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 102961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onSaveInstanceState(Bundle outState) { 1030e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout super.onSaveInstanceState(outState); 1031fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak outState.putInt(CURRENT_SELECTED_POSITION, mSelectedPosition); 1032fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak outState.putBoolean(IS_PAGE_ROW, mIsPageRow); 1033fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 103461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBackStackChangedListener != null) { 103561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBackStackChangedListener.save(outState); 103661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 103761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putBoolean(HEADER_SHOW, mShowingHeaders); 103861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 103961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 104061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 104161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 104261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onCreate(Bundle savedInstanceState) { 104361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onCreate(savedInstanceState); 104461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu TypedArray ta = getActivity().obtainStyledAttributes(R.styleable.LeanbackTheme); 10458e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing mContainerListMarginStart = (int) ta.getDimension( 104646443cb5b092f1d9156342645088eead9da026f6Dake Gu R.styleable.LeanbackTheme_browseRowsMarginStart, getActivity().getResources() 104746443cb5b092f1d9156342645088eead9da026f6Dake Gu .getDimensionPixelSize(R.dimen.lb_browse_rows_margin_start)); 104861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mContainerListAlignTop = (int) ta.getDimension( 104946443cb5b092f1d9156342645088eead9da026f6Dake Gu R.styleable.LeanbackTheme_browseRowsMarginTop, getActivity().getResources() 105046443cb5b092f1d9156342645088eead9da026f6Dake Gu .getDimensionPixelSize(R.dimen.lb_browse_rows_margin_top)); 105161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ta.recycle(); 105261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 105361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu readArguments(getArguments()); 105461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 105534f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (mCanShowHeaders) { 105634f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (mHeadersBackStackEnabled) { 105734f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mWithHeadersBackStackName = LB_HEADERS_BACKSTACK + this; 105834f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mBackStackChangedListener = new BackStackListener(); 105934f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout getFragmentManager().addOnBackStackChangedListener(mBackStackChangedListener); 106034f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mBackStackChangedListener.load(savedInstanceState); 106134f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } else { 106234f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (savedInstanceState != null) { 106334f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mShowingHeaders = savedInstanceState.getBoolean(HEADER_SHOW); 106434f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 106534f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 106634f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 1067a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1068f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata mScaleFactor = getResources().getFraction(R.fraction.lb_browse_rows_scale, 1, 1); 106961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 107061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 107161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 1072fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public void onDestroyView() { 1073fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter = null; 1074fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentAdapter = null; 1075fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragment = null; 1076fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mHeadersSupportFragment = null; 1077fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak super.onDestroyView(); 1078fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 1079fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 1080fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak @Override 108161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onDestroy() { 108261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBackStackChangedListener != null) { 108361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().removeOnBackStackChangedListener(mBackStackChangedListener); 108461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 108561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onDestroy(); 108661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 108761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 108861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 108961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onCreateView(LayoutInflater inflater, ViewGroup container, 109061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Bundle savedInstanceState) { 10917350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 1092a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata if (getChildFragmentManager().findFragmentById(R.id.scale_frame) == null) { 109361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment = new HeadersSupportFragment(); 1094bb0a680c10b84b83833a59634373140f8bd0750csusnata 1095a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata createMainFragment(mAdapter, mSelectedPosition); 1096bb0a680c10b84b83833a59634373140f8bd0750csusnata FragmentTransaction ft = getChildFragmentManager().beginTransaction() 1097bb0a680c10b84b83833a59634373140f8bd0750csusnata .replace(R.id.browse_headers_dock, mHeadersSupportFragment); 1098bb0a680c10b84b83833a59634373140f8bd0750csusnata 1099bb0a680c10b84b83833a59634373140f8bd0750csusnata if (mMainFragment != null) { 1100bb0a680c10b84b83833a59634373140f8bd0750csusnata ft.replace(R.id.scale_frame, mMainFragment); 1101bb0a680c10b84b83833a59634373140f8bd0750csusnata } else { 1102bb0a680c10b84b83833a59634373140f8bd0750csusnata // Empty adapter used to guard against lazy adapter loading. When this 1103bb0a680c10b84b83833a59634373140f8bd0750csusnata // fragment is instantiated, mAdapter might not have the data or might not 1104bb0a680c10b84b83833a59634373140f8bd0750csusnata // have been set. In either of those cases mFragmentAdapter will be null. 1105bb0a680c10b84b83833a59634373140f8bd0750csusnata // This way we can maintain the invariant that mMainFragmentAdapter is never 1106bb0a680c10b84b83833a59634373140f8bd0750csusnata // null and it avoids doing null checks all over the code. 1107bb0a680c10b84b83833a59634373140f8bd0750csusnata mMainFragmentAdapter = new MainFragmentAdapter(null); 1108cabb8eca86d0248274f57008ff66427fec2e927csusnata mMainFragmentAdapter.setFragmentHost(new FragmentHostImpl()); 1109bb0a680c10b84b83833a59634373140f8bd0750csusnata } 1110bb0a680c10b84b83833a59634373140f8bd0750csusnata 1111bb0a680c10b84b83833a59634373140f8bd0750csusnata ft.commit(); 111261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 111361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment = (HeadersSupportFragment) getChildFragmentManager() 1114fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak .findFragmentById(R.id.browse_headers_dock); 1115fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragment = getChildFragmentManager().findFragmentById(R.id.scale_frame); 1116d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentAdapter = ((MainFragmentAdapterProvider)mMainFragment) 1117d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentAdapter(); 1118dc1492d3655550b7a9c861aae1bd538410c7324dDake Gu mMainFragmentAdapter.setFragmentHost(new FragmentHostImpl()); 1119fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 1120fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mIsPageRow = savedInstanceState != null ? 1121fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak savedInstanceState.getBoolean(IS_PAGE_ROW, false) : false; 1122fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 1123fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mSelectedPosition = savedInstanceState != null ? 1124fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak savedInstanceState.getInt(CURRENT_SELECTED_POSITION, 0) : 0; 11257350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 1126fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (!mIsPageRow) { 1127d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata if (mMainFragment instanceof MainFragmentRowsAdapterProvider) { 1128d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = ((MainFragmentRowsAdapterProvider) mMainFragment) 1129d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentRowsAdapter(); 1130d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } else { 1131d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = null; 1132d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 1133fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } else { 1134fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter = null; 1135fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 113661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 113761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 113861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setHeadersGone(!mCanShowHeaders); 113961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeaderPresenterSelector != null) { 114061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setPresenterSelector(mHeaderPresenterSelector); 114161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 114261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setAdapter(mAdapter); 11438df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu mHeadersSupportFragment.setOnHeaderViewSelectedListener(mHeaderViewSelectedListener); 114461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setOnHeaderClickedListener(mHeaderClickedListener); 11452f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 114661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View root = inflater.inflate(R.layout.lb_browse_fragment, container, false); 114761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1148684f4a94f6f55b2abc5ed2677dfdfc9501dd6407susnata getProgressBarManager().setRootView((ViewGroup)root); 1149684f4a94f6f55b2abc5ed2677dfdfc9501dd6407susnata 115061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame); 115161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame.setOnChildFocusListener(mOnChildFocusListener); 1152e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener); 115361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1154a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu installTitleView(inflater, mBrowseFrame, savedInstanceState); 1155a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu 1156a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout = (ScaleFrameLayout) root.findViewById(R.id.scale_frame); 1157a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setPivotX(0); 1158a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setPivotY(mContainerListAlignTop); 1159a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1160a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata setupMainFragment(); 1161a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 116261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrandColorSet) { 116361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setBackgroundColor(mBrandColor); 116461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 116561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11668403619efebe94666c0615c3fc85080a303acf80Dake Gu mSceneWithHeaders = TransitionHelper.createScene(mBrowseFrame, new Runnable() { 116761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 116861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 116961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(true); 117061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 117161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 11728403619efebe94666c0615c3fc85080a303acf80Dake Gu mSceneWithoutHeaders = TransitionHelper.createScene(mBrowseFrame, new Runnable() { 117361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 117461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 117561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(false); 117661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 117761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 11788403619efebe94666c0615c3fc85080a303acf80Dake Gu mSceneAfterEntranceTransition = TransitionHelper.createScene(mBrowseFrame, new Runnable() { 1179c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 1180c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void run() { 1181c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setEntranceTransitionEndState(); 1182c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1183c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu }); 1184d0fc2e48059f718676a531af06a31849f54c1ca9susnata 118561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return root; 118661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 118761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11881c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata private void setupMainFragment() { 1189fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragmentRowsAdapter != null) { 1190fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setAdapter(mAdapter); 11913eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu mMainFragmentRowsAdapter.setOnItemViewSelectedListener( 11923eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu new MainFragmentItemViewSelectedListener(mMainFragmentRowsAdapter)); 1193fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setOnItemViewClickedListener(mOnItemViewClickedListener); 1194a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 11951c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 11961c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 1197a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu @Override 1198a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu boolean isReadyForPrepareEntranceTransition() { 1199cabb8eca86d0248274f57008ff66427fec2e927csusnata return mMainFragment != null && mMainFragment.getView() != null; 1200a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu } 1201a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu 1202a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu @Override 1203a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu boolean isReadyForStartEntranceTransition() { 1204a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu return mMainFragment != null && mMainFragment.getView() != null 1205a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu && (!mIsPageRow || mMainFragmentAdapter.mFragmentHost.mDataReady); 1206a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu } 1207a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu 120861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void createHeadersTransition() { 12098403619efebe94666c0615c3fc85080a303acf80Dake Gu mHeadersTransition = TransitionHelper.loadTransition(getActivity(), 12104735bfcd924fec2d694523f34fac5f8151257dc7Dake Gu mShowingHeaders ? 12114735bfcd924fec2d694523f34fac5f8151257dc7Dake Gu R.transition.lb_browse_headers_in : R.transition.lb_browse_headers_out); 121261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 12138403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.addTransitionListener(mHeadersTransition, new TransitionListener() { 121461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 121561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onTransitionStart(Object transition) { 121661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 121761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 121861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onTransitionEnd(Object transition) { 121961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransition = null; 122054bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mMainFragmentAdapter != null) { 122154bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu mMainFragmentAdapter.onTransitionEnd(); 122254bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (!mShowingHeaders && mMainFragment != null) { 122354bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu View mainFragmentView = mMainFragment.getView(); 122454bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mainFragmentView != null && !mainFragmentView.hasFocus()) { 122554bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu mainFragmentView.requestFocus(); 122654bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu } 122761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 122854bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu } 122954bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mHeadersSupportFragment != null) { 123054bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu mHeadersSupportFragment.onTransitionEnd(); 123154bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mShowingHeaders) { 123254bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu VerticalGridView headerGridView = mHeadersSupportFragment.getVerticalGridView(); 123354bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (headerGridView != null && !headerGridView.hasFocus()) { 123454bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu headerGridView.requestFocus(); 123554bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu } 123661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1237d0fc2e48059f718676a531af06a31849f54c1ca9susnata } 12386fd4441435b14669deced90a05097dd5fe459acesusnata 12397350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata // Animate TitleView once header animation is complete. 12408ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu updateTitleViewVisibility(); 1241d0fc2e48059f718676a531af06a31849f54c1ca9susnata 124261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrowseTransitionListener != null) { 124361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener.onHeadersTransitionStop(mShowingHeaders); 124461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 124561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 124661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 124761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 124861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 12498ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu void updateTitleViewVisibility() { 12508ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (!mShowingHeaders) { 12518ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean showTitleView; 12528ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mIsPageRow && mMainFragmentAdapter != null) { 12538ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // page fragment case: 12548ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitleView = mMainFragmentAdapter.mFragmentHost.mShowTitleView; 12558ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 12568ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // regular row view case: 12578ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitleView = isFirstRowWithContent(mSelectedPosition); 12588ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12598ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (showTitleView) { 1260a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu showTitle(TitleViewAdapter.FULL_VIEW_VISIBLE); 12618ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 12628ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitle(false); 12638ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12648ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 12658ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // when HeaderFragment is showing, showBranding and showSearch are slightly different 12668ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean showBranding; 12678ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean showSearch; 12688ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mIsPageRow && mMainFragmentAdapter != null) { 12698ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showBranding = mMainFragmentAdapter.mFragmentHost.mShowTitleView; 12708ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 12718ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showBranding = isFirstRowWithContent(mSelectedPosition); 12728ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12738ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showSearch = isFirstRowWithContentOrPageRow(mSelectedPosition); 12748ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu int flags = 0; 1275a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu if (showBranding) flags |= TitleViewAdapter.BRANDING_VIEW_VISIBLE; 1276a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu if (showSearch) flags |= TitleViewAdapter.SEARCH_VIEW_VISIBLE; 12778ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (flags != 0) { 12788ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitle(flags); 12798ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 12808ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitle(false); 12818ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12828ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12838ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12848ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 12858ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean isFirstRowWithContentOrPageRow(int rowPosition) { 12868ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAdapter == null || mAdapter.size() == 0) { 12878ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 12888ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12898ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu for (int i = 0; i < mAdapter.size(); i++) { 12908ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Row row = (Row) mAdapter.get(i); 12918ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (row.isRenderedAsRowView() || row instanceof PageRow) { 12928ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return rowPosition == i; 12938ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12948ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12958ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 12968ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12978ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 12988ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean isFirstRowWithContent(int rowPosition) { 12998ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAdapter == null || mAdapter.size() == 0) { 13008ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 13018ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13028ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu for (int i = 0; i < mAdapter.size(); i++) { 13038ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Row row = (Row) mAdapter.get(i); 13048ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (row.isRenderedAsRowView()) { 13058ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return rowPosition == i; 13068ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13078ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13088ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 13098ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13108ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 131161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 131261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the {@link PresenterSelector} used to render the row headers. 131361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 131461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headerPresenterSelector The PresenterSelector that will determine 131561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the Presenter for each row header. 131661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 131761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setHeaderPresenterSelector(PresenterSelector headerPresenterSelector) { 131861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeaderPresenterSelector = headerPresenterSelector; 131961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 132061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setPresenterSelector(mHeaderPresenterSelector); 132161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 132261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 132361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1324c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void setHeadersOnScreen(boolean onScreen) { 1325c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu MarginLayoutParams lp; 1326c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu View containerList; 132761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList = mHeadersSupportFragment.getView(); 132861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu lp = (MarginLayoutParams) containerList.getLayoutParams(); 13298e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing lp.setMarginStart(onScreen ? 0 : -mContainerListMarginStart); 133061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList.setLayoutParams(lp); 1331c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 133261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1333c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void showHeaders(boolean show) { 1334c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (DEBUG) Log.v(TAG, "showHeaders " + show); 1335c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mHeadersSupportFragment.setHeadersEnabled(show); 1336c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(show); 1337a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata expandMainFragment(!show); 1338a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1339a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1340a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private void expandMainFragment(boolean expand) { 1341a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata MarginLayoutParams params = (MarginLayoutParams) mScaleFrameLayout.getLayoutParams(); 1342c1ec7d7eff002329b245a4edb1b87da2f3b5e006Dake Gu params.setMarginStart(!expand ? mContainerListMarginStart : 0); 1343a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setLayoutParams(params); 1344a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mMainFragmentAdapter.setExpand(expand); 1345a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1346a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata setMainFragmentAlignment(); 1347f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata final float scaleFactor = !expand 1348bb0a680c10b84b83833a59634373140f8bd0750csusnata && mMainFragmentScaleEnabled 1349bb0a680c10b84b83833a59634373140f8bd0750csusnata && mMainFragmentAdapter.isScalingEnabled() ? mScaleFactor : 1; 1350a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setLayoutScaleY(scaleFactor); 1351a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setChildScale(scaleFactor); 135261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 135361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 135461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private HeadersSupportFragment.OnHeaderClickedListener mHeaderClickedListener = 135561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new HeadersSupportFragment.OnHeaderClickedListener() { 135661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 1357729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu public void onHeaderClicked(RowHeaderPresenter.ViewHolder viewHolder, Row row) { 135861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders || !mShowingHeaders || isInHeadersTransition()) { 135961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 136061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 136161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(false); 13621c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragment.getView().requestFocus(); 136361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 136461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 136561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 13663eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu class MainFragmentItemViewSelectedListener implements OnItemViewSelectedListener { 13673eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu MainFragmentRowsAdapter mMainFragmentRowsAdapter; 13683eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu 13693eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu public MainFragmentItemViewSelectedListener(MainFragmentRowsAdapter fragmentRowsAdapter) { 13703eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu mMainFragmentRowsAdapter = fragmentRowsAdapter; 13713eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu } 13723eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu 137361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 137461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 137561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu RowPresenter.ViewHolder rowViewHolder, Row row) { 13763eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu int position = mMainFragmentRowsAdapter.getSelectedPosition(); 137761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "row selected position " + position); 137861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu onRowSelected(position); 137961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mExternalOnItemViewSelectedListener != null) { 138061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemViewSelectedListener.onItemSelected(itemViewHolder, item, 138161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu rowViewHolder, row); 138261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 138361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 138461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 138561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 13868df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu private HeadersSupportFragment.OnHeaderViewSelectedListener mHeaderViewSelectedListener = 13878df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu new HeadersSupportFragment.OnHeaderViewSelectedListener() { 138861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 13898df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu public void onHeaderSelected(RowHeaderPresenter.ViewHolder viewHolder, Row row) { 13900d841b3454f896da58deb506ca22730bfd04f34fDake Gu int position = mHeadersSupportFragment.getSelectedPosition(); 139161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "header selected position " + position); 139261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu onRowSelected(position); 139361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 139461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 139561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 139661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void onRowSelected(int position) { 139761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (position != mSelectedPosition) { 1398aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSetSelectionRunnable.post( 1399aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout position, SetSelectionRunnable.TYPE_INTERNAL_SYNC, true); 140061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 140161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 140261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 14033f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu private void setSelection(int position, boolean smooth) { 14041c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata if (position == NO_POSITION) { 14051c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return; 140661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14071c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 14081c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mHeadersSupportFragment.setSelectedPosition(position, smooth); 1409bb0a680c10b84b83833a59634373140f8bd0750csusnata replaceMainFragment(position); 1410bb0a680c10b84b83833a59634373140f8bd0750csusnata 1411bb0a680c10b84b83833a59634373140f8bd0750csusnata if (mMainFragmentRowsAdapter != null) { 1412bb0a680c10b84b83833a59634373140f8bd0750csusnata mMainFragmentRowsAdapter.setSelectedPosition(position, smooth); 1413bb0a680c10b84b83833a59634373140f8bd0750csusnata } 1414bb0a680c10b84b83833a59634373140f8bd0750csusnata mSelectedPosition = position; 14157350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 14168ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu updateTitleViewVisibility(); 1417bb0a680c10b84b83833a59634373140f8bd0750csusnata } 14183faa5780307cf10ff0e4a1d89a9ba099cdad2e15susnata 1419bb0a680c10b84b83833a59634373140f8bd0750csusnata private void replaceMainFragment(int position) { 1420a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata if (createMainFragment(mAdapter, position)) { 1421041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu swapToMainFragment(); 1422a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata expandMainFragment(!(mCanShowHeaders && mShowingHeaders)); 14231c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata setupMainFragment(); 1424a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu performPendingStates(); 14251c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 142661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 142761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1428041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu private void swapToMainFragment() { 1429041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu final VerticalGridView gridView = mHeadersSupportFragment.getVerticalGridView(); 14303f19c1616ed2749a70ecc764dccb467ec96aa1f4Dake Gu if (isShowingHeaders() && gridView != null 14313f19c1616ed2749a70ecc764dccb467ec96aa1f4Dake Gu && gridView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { 1432041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu // if user is scrolling HeadersSupportFragment, swap to empty fragment and wait scrolling 1433041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu // finishes. 1434041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu getChildFragmentManager().beginTransaction() 1435041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu .replace(R.id.scale_frame, new Fragment()).commit(); 1436041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu gridView.addOnScrollListener(new RecyclerView.OnScrollListener() { 1437041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu @Override 1438041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 1439041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu if (newState == RecyclerView.SCROLL_STATE_IDLE) { 1440041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu gridView.removeOnScrollListener(this); 1441041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu FragmentManager fm = getChildFragmentManager(); 1442041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu Fragment currentFragment = fm.findFragmentById(R.id.scale_frame); 1443041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu if (currentFragment != mMainFragment) { 1444041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu fm.beginTransaction().replace(R.id.scale_frame, mMainFragment).commit(); 1445041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 1446041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 1447041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 1448041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu }); 1449041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } else { 1450041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu // Otherwise swap immediately 1451041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu getChildFragmentManager().beginTransaction() 1452041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu .replace(R.id.scale_frame, mMainFragment).commit(); 1453041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 14541c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 14551c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 14563f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu /** 14573f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu * Sets the selected row position with smooth animation. 14583f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu */ 14593f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu public void setSelectedPosition(int position) { 14603f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu setSelectedPosition(position, true); 14613f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu } 14623f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu 14633f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu /** 14640d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * Gets position of currently selected row. 14650d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @return Position of currently selected row. 14660d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 14670d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public int getSelectedPosition() { 14680d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu return mSelectedPosition; 14690d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 14700d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 14710d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 14723f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu * Sets the selected row position. 14733f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu */ 14743f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu public void setSelectedPosition(int position, boolean smooth) { 1475aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSetSelectionRunnable.post( 1476aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout position, SetSelectionRunnable.TYPE_USER_REQUEST, smooth); 14773f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu } 14783f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu 14790d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 14800d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * Selects a Row and perform an optional task on the Row. For example 14810d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * <code>setSelectedPosition(10, true, new ListRowPresenterSelectItemViewHolderTask(5))</code> 14820d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * scrolls to 11th row and selects 6th item on that row. The method will be ignored if 14830d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * RowsSupportFragment has not been created (i.e. before {@link #onCreateView(LayoutInflater, 14840d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * ViewGroup, Bundle)}). 14850d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * 14860d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @param rowPosition Which row to select. 14870d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @param smooth True to scroll to the row, false for no animation. 14880d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @param rowHolderTask Optional task to perform on the Row. When the task is not null, headers 14890d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * fragment will be collapsed. 14900d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 14910d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public void setSelectedPosition(int rowPosition, boolean smooth, 1492cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu final Presenter.ViewHolderTask rowHolderTask) { 1493fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragmentAdapterRegistry == null) { 14940d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu return; 14950d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 14960d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu if (rowHolderTask != null) { 14970d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu startHeadersTransition(false); 14980d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 1499fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragmentRowsAdapter != null) { 1500fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setSelectedPosition(rowPosition, smooth, rowHolderTask); 1501a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 15020d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 15030d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 150461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 150561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onStart() { 150661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onStart(); 15072f5ebf3f6f7bb6a24856f389e369b247118ba119susnata mHeadersSupportFragment.setAlignment(mContainerListAlignTop); 1508a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata setMainFragmentAlignment(); 150961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 151061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders && mShowingHeaders && mHeadersSupportFragment.getView() != null) { 151161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.getView().requestFocus(); 151261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if ((!mCanShowHeaders || !mShowingHeaders) 15131c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata && mMainFragment.getView() != null) { 15141c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragment.getView().requestFocus(); 151561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 15161c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 151761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders) { 151861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(mShowingHeaders); 151961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 15201c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 15213f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu if (isEntranceTransitionEnabled()) { 1522c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setEntranceTransitionStartState(); 1523c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 152461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 152561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1526a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private void onExpandTransitionStart(boolean expand, final Runnable callback) { 1527a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata if (expand) { 1528a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata callback.run(); 1529a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata return; 1530a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1531a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata // Run a "pre" layout when we go non-expand, in order to get the initial 1532a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata // positions of added rows. 1533fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak new ExpandPreLayout(callback, mMainFragmentAdapter, getView()).execute(); 1534a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1535a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1536a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private void setMainFragmentAlignment() { 1537a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata int alignOffset = mContainerListAlignTop; 1538f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata if (mMainFragmentScaleEnabled 1539f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata && mMainFragmentAdapter.isScalingEnabled() 1540f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata && mShowingHeaders) { 1541f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata alignOffset = (int) (alignOffset / mScaleFactor + 0.5f); 1542a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1543a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mMainFragmentAdapter.setAlignment(alignOffset); 1544a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1545a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 154661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 1547a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Enables/disables headers transition on back key support. This is enabled by 154861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * default. The BrowseSupportFragment will add a back stack entry when headers are 154961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * showing. Running a headers transition when the back key is pressed only 155061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * works when the headers state is {@link #HEADERS_ENABLED} or 155161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #HEADERS_HIDDEN}. 155261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 155361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * NOTE: If an Activity has its own onBackPressed() handling, you must 155461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * disable this feature. You may use {@link #startHeadersTransition(boolean)} 155561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * and {@link BrowseTransitionListener} in your own back stack handling. 155661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 155761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public final void setHeadersTransitionOnBackEnabled(boolean headersBackStackEnabled) { 155861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersBackStackEnabled = headersBackStackEnabled; 155961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 156061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 156161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 156261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if headers transition on back key support is enabled. 156361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 156461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public final boolean isHeadersTransitionOnBackEnabled() { 156561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersBackStackEnabled; 156661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 156761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 156861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void readArguments(Bundle args) { 156961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args == null) { 157061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 157161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 157261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args.containsKey(ARG_TITLE)) { 157361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setTitle(args.getString(ARG_TITLE)); 157461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 157561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args.containsKey(ARG_HEADERS_STATE)) { 157661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setHeadersState(args.getInt(ARG_HEADERS_STATE)); 157761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 157861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 157961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 158061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 158161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the state for the headers column in the browse fragment. Must be one 158261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of {@link #HEADERS_ENABLED}, {@link #HEADERS_HIDDEN}, or 158361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #HEADERS_DISABLED}. 158461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 158561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headersState The state of the headers for the browse fragment. 158661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 158761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setHeadersState(int headersState) { 158861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headersState < HEADERS_ENABLED || headersState > HEADERS_DISABLED) { 158961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalArgumentException("Invalid headers state: " + headersState); 159061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 159161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "setHeadersState " + headersState); 159261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 159361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headersState != mHeadersState) { 159461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersState = headersState; 159561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu switch (headersState) { 159661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_ENABLED: 159761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = true; 159861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = true; 159961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 160061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_HIDDEN: 160161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = true; 160261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = false; 160361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 160461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_DISABLED: 160561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = false; 160661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = false; 160761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 160861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu default: 160961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Log.w(TAG, "Unknown headers state: " + headersState); 161061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 161161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 161261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 161361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setHeadersGone(!mCanShowHeaders); 161461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 161561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 161661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 161761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 161861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 161961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the state of the headers column in the browse fragment. 162061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 162161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getHeadersState() { 162261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersState; 162361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1624c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 16253f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 16263f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected Object createEntranceTransition() { 16278403619efebe94666c0615c3fc85080a303acf80Dake Gu return TransitionHelper.loadTransition(getActivity(), 16283f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu R.transition.lb_browse_entrance_transition); 1629c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1630c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 16313f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 16323f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected void runEntranceTransition(Object entranceTransition) { 16338403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.runTransition(mSceneAfterEntranceTransition, entranceTransition); 1634c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1635c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 16363f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 1637902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu protected void onEntranceTransitionPrepare() { 1638902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu mHeadersSupportFragment.onTransitionPrepare(); 1639a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu // setEntranceTransitionStartState() might be called when mMainFragment is null, 1640a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu // make sure it is called. 1641a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu mMainFragmentAdapter.setEntranceTransitionState(false); 16421c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionPrepare(); 1643902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu } 1644902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu 1645902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu @Override 16463f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected void onEntranceTransitionStart() { 16473f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu mHeadersSupportFragment.onTransitionStart(); 16481c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionStart(); 1649c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1650c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 16513f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 16523f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected void onEntranceTransitionEnd() { 1653b082c7277cff057bdff19e411e345c3d6fea2e12susnata if (mMainFragmentAdapter != null) { 1654b082c7277cff057bdff19e411e345c3d6fea2e12susnata mMainFragmentAdapter.onTransitionEnd(); 1655b082c7277cff057bdff19e411e345c3d6fea2e12susnata } 1656b082c7277cff057bdff19e411e345c3d6fea2e12susnata 1657b082c7277cff057bdff19e411e345c3d6fea2e12susnata if (mHeadersSupportFragment != null) { 1658b082c7277cff057bdff19e411e345c3d6fea2e12susnata mHeadersSupportFragment.onTransitionEnd(); 1659b082c7277cff057bdff19e411e345c3d6fea2e12susnata } 1660c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1661c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 16623f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu void setSearchOrbViewOnScreen(boolean onScreen) { 1663a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu View searchOrbView = getTitleViewAdapter().getSearchAffordanceView(); 1664b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata if (searchOrbView != null) { 1665b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata MarginLayoutParams lp = (MarginLayoutParams) searchOrbView.getLayoutParams(); 1666b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata lp.setMarginStart(onScreen ? 0 : -mContainerListMarginStart); 1667b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata searchOrbView.setLayoutParams(lp); 1668b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata } 1669c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1670c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1671c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void setEntranceTransitionStartState() { 1672c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(false); 1673c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setSearchOrbViewOnScreen(false); 16741c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.setEntranceTransitionState(false); 1675c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1676c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1677c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void setEntranceTransitionEndState() { 1678c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(mShowingHeaders); 1679c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setSearchOrbViewOnScreen(true); 16801c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.setEntranceTransitionState(true); 1681c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1682a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1683dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu private class ExpandPreLayout implements ViewTreeObserver.OnPreDrawListener { 1684a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1685a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private final View mView; 1686a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private final Runnable mCallback; 1687a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private int mState; 1688fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private MainFragmentAdapter mainFragmentAdapter; 1689a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1690a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata final static int STATE_INIT = 0; 1691a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata final static int STATE_FIRST_DRAW = 1; 1692a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata final static int STATE_SECOND_DRAW = 2; 1693a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1694fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak ExpandPreLayout(Runnable callback, MainFragmentAdapter adapter, View view) { 1695fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mView = view; 1696a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mCallback = callback; 1697a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mainFragmentAdapter = adapter; 1698a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1699a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1700a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata void execute() { 1701a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mView.getViewTreeObserver().addOnPreDrawListener(this); 1702a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mainFragmentAdapter.setExpand(false); 1703a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mState = STATE_INIT; 1704a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1705a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1706a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata @Override 1707a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata public boolean onPreDraw() { 1708dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu if (getView() == null || getActivity() == null) { 1709dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu mView.getViewTreeObserver().removeOnPreDrawListener(this); 1710dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu return true; 1711dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu } 1712a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata if (mState == STATE_INIT) { 1713a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mainFragmentAdapter.setExpand(true); 1714a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mState = STATE_FIRST_DRAW; 1715a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } else if (mState == STATE_FIRST_DRAW) { 1716a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mCallback.run(); 1717a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mView.getViewTreeObserver().removeOnPreDrawListener(this); 1718a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mState = STATE_SECOND_DRAW; 1719a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1720a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata return false; 1721a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1722a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 172361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu} 1724