1cc671dd3caac1d0cbf3f6999ab063c9ff1f297b2Dake Gu// CHECKSTYLE:OFF Generated code 26193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu/* This file is auto-generated from BrowseFragment.java. DO NOT MODIFY. */ 36193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu 461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/* 561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Copyright (C) 2014 The Android Open Source Project 661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * in compliance with the License. You may obtain a copy of the License at 961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 1061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * http://www.apache.org/licenses/LICENSE-2.0 1161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 1261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License 1361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * or implied. See the License for the specific language governing permissions and limitations under 1561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the License. 1661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 1761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gupackage android.support.v17.leanback.app; 1861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 193103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport static android.support.v7.widget.RecyclerView.NO_POSITION; 203103f63e99d47573823957f7aa34308555873221Aurimas Liutikas 215d926e60b034b2e4d1404c6ac088a13b9c91ee3eDake Guimport android.support.v4.app.Fragment; 225d926e60b034b2e4d1404c6ac088a13b9c91ee3eDake Guimport android.support.v4.app.FragmentManager; 235d926e60b034b2e4d1404c6ac088a13b9c91ee3eDake Guimport android.support.v4.app.FragmentManager.BackStackEntry; 245d926e60b034b2e4d1404c6ac088a13b9c91ee3eDake Guimport android.support.v4.app.FragmentTransaction; 252452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Guimport android.content.Context; 262f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.content.res.TypedArray; 272f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.graphics.Color; 282f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.graphics.Rect; 292f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.os.Bundle; 3070acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt; 3161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.R; 3261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.transition.TransitionHelper; 3361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.transition.TransitionListener; 3489097f67f988ebba714a95e10369665280db0c27Dake Guimport android.support.v17.leanback.util.StateMachine.Event; 3589097f67f988ebba714a95e10369665280db0c27Dake Guimport android.support.v17.leanback.util.StateMachine.State; 3661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.BrowseFrameLayout; 378ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Guimport android.support.v17.leanback.widget.InvisibleRowPresenter; 381c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnataimport android.support.v17.leanback.widget.ListRow; 392f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.ObjectAdapter; 4061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemViewClickedListener; 4161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemViewSelectedListener; 421c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnataimport android.support.v17.leanback.widget.PageRow; 4361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.Presenter; 4461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.PresenterSelector; 452f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.Row; 468df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Guimport android.support.v17.leanback.widget.RowHeaderPresenter; 4761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.RowPresenter; 48a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnataimport android.support.v17.leanback.widget.ScaleFrameLayout; 49a373804d10f93a9488adc35cf6ce44dce09b3778Dake Guimport android.support.v17.leanback.widget.TitleViewAdapter; 5061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.VerticalGridView; 518e3566285de4ac771d6188f62fe947e23d371a3dKris Giesingimport android.support.v4.view.ViewCompat; 52041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Guimport android.support.v7.widget.RecyclerView; 5361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.util.Log; 5461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.LayoutInflater; 5561905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.View; 5661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup; 5761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup.MarginLayoutParams; 58a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnataimport android.view.ViewTreeObserver; 5961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basakimport java.util.HashMap; 61fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basakimport java.util.Map; 62fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 6361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/** 6461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A fragment for creating Leanback browse screens. It is composed of a 6561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * RowsSupportFragment and a HeadersSupportFragment. 6661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 6761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A BrowseSupportFragment renders the elements of its {@link ObjectAdapter} as a set 6861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of rows in a vertical list. The elements in this adapter must be subclasses 6961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of {@link Row}. 7061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 7161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * The HeadersSupportFragment can be set to be either shown or hidden by default, or 7261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * may be disabled entirely. See {@link #setHeadersState} for details. 7361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 7461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * By default the BrowseSupportFragment includes support for returning to the headers 7561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * when the user presses Back. For Activities that customize {@link 766193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu * android.support.v4.app.FragmentActivity#onBackPressed()}, you must disable this default Back key support by 7761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * calling {@link #setHeadersTransitionOnBackEnabled(boolean)} with false and 7861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * use {@link BrowseSupportFragment.BrowseTransitionListener} and 7961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #startHeadersTransition(boolean)}. 80a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p> 81a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * The recommended theme to use with a BrowseSupportFragment is 82a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link android.support.v17.leanback.R.style#Theme_Leanback_Browse}. 83a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p> 8461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 853f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gupublic class BrowseSupportFragment extends BaseSupportFragment { 8661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 8761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for saving header show/hide status when backstack is used: 8861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String HEADER_STACK_INDEX = "headerStackIndex"; 8961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for saving header show/hide status when backstack is not used: 9061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String HEADER_SHOW = "headerShow"; 91fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private static final String IS_PAGE_ROW = "isPageRow"; 92fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition"; 93e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout 9489097f67f988ebba714a95e10369665280db0c27Dake Gu /** 9589097f67f988ebba714a95e10369665280db0c27Dake Gu * State to hide headers fragment. 9689097f67f988ebba714a95e10369665280db0c27Dake Gu */ 9789097f67f988ebba714a95e10369665280db0c27Dake Gu final State STATE_SET_ENTRANCE_START_STATE = new State("SET_ENTRANCE_START_STATE") { 9889097f67f988ebba714a95e10369665280db0c27Dake Gu @Override 9989097f67f988ebba714a95e10369665280db0c27Dake Gu public void run() { 10089097f67f988ebba714a95e10369665280db0c27Dake Gu setEntranceTransitionStartState(); 10189097f67f988ebba714a95e10369665280db0c27Dake Gu } 10289097f67f988ebba714a95e10369665280db0c27Dake Gu }; 10389097f67f988ebba714a95e10369665280db0c27Dake Gu 10489097f67f988ebba714a95e10369665280db0c27Dake Gu /** 10589097f67f988ebba714a95e10369665280db0c27Dake Gu * Event for Header fragment view is created, we could perform 10689097f67f988ebba714a95e10369665280db0c27Dake Gu * {@link #setEntranceTransitionStartState()} to hide headers fragment initially. 10789097f67f988ebba714a95e10369665280db0c27Dake Gu */ 10889097f67f988ebba714a95e10369665280db0c27Dake Gu final Event EVT_HEADER_VIEW_CREATED = new Event("headerFragmentViewCreated"); 10989097f67f988ebba714a95e10369665280db0c27Dake Gu 11089097f67f988ebba714a95e10369665280db0c27Dake Gu /** 11189097f67f988ebba714a95e10369665280db0c27Dake Gu * Event for {@link #getMainFragment()} view is created, it's additional requirement to execute 11289097f67f988ebba714a95e10369665280db0c27Dake Gu * {@link #onEntranceTransitionPrepare()}. 11389097f67f988ebba714a95e10369665280db0c27Dake Gu */ 11489097f67f988ebba714a95e10369665280db0c27Dake Gu final Event EVT_MAIN_FRAGMENT_VIEW_CREATED = new Event("mainFragmentViewCreated"); 11589097f67f988ebba714a95e10369665280db0c27Dake Gu 11689097f67f988ebba714a95e10369665280db0c27Dake Gu /** 11789097f67f988ebba714a95e10369665280db0c27Dake Gu * Event that data for the screen is ready, this is additional requirement to launch entrance 11889097f67f988ebba714a95e10369665280db0c27Dake Gu * transition. 11989097f67f988ebba714a95e10369665280db0c27Dake Gu */ 12089097f67f988ebba714a95e10369665280db0c27Dake Gu final Event EVT_SCREEN_DATA_READY = new Event("screenDataReady"); 12189097f67f988ebba714a95e10369665280db0c27Dake Gu 12289097f67f988ebba714a95e10369665280db0c27Dake Gu @Override 12389097f67f988ebba714a95e10369665280db0c27Dake Gu void createStateMachineStates() { 12489097f67f988ebba714a95e10369665280db0c27Dake Gu super.createStateMachineStates(); 12589097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE); 12689097f67f988ebba714a95e10369665280db0c27Dake Gu } 12789097f67f988ebba714a95e10369665280db0c27Dake Gu 12889097f67f988ebba714a95e10369665280db0c27Dake Gu @Override 12989097f67f988ebba714a95e10369665280db0c27Dake Gu void createStateMachineTransitions() { 13089097f67f988ebba714a95e10369665280db0c27Dake Gu super.createStateMachineTransitions(); 13189097f67f988ebba714a95e10369665280db0c27Dake Gu // when headers fragment view is created we could setEntranceTransitionStartState() 13289097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, STATE_SET_ENTRANCE_START_STATE, 13389097f67f988ebba714a95e10369665280db0c27Dake Gu EVT_HEADER_VIEW_CREATED); 13489097f67f988ebba714a95e10369665280db0c27Dake Gu 13589097f67f988ebba714a95e10369665280db0c27Dake Gu // add additional requirement for onEntranceTransitionPrepare() 13689097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, 13789097f67f988ebba714a95e10369665280db0c27Dake Gu STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW, 13889097f67f988ebba714a95e10369665280db0c27Dake Gu EVT_MAIN_FRAGMENT_VIEW_CREATED); 13989097f67f988ebba714a95e10369665280db0c27Dake Gu // add additional requirement to launch entrance transition. 14089097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, STATE_ENTRANCE_PERFORM, 14189097f67f988ebba714a95e10369665280db0c27Dake Gu EVT_SCREEN_DATA_READY); 14289097f67f988ebba714a95e10369665280db0c27Dake Gu } 14389097f67f988ebba714a95e10369665280db0c27Dake Gu 14461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final class BackStackListener implements FragmentManager.OnBackStackChangedListener { 14561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mLastEntryCount; 14661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mIndexOfHeadersBackStack; 14761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 14861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackListener() { 14961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLastEntryCount = getFragmentManager().getBackStackEntryCount(); 15061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = -1; 15161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 15261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 15361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void load(Bundle savedInstanceState) { 15461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (savedInstanceState != null) { 15561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = savedInstanceState.getInt(HEADER_STACK_INDEX, -1); 15661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = mIndexOfHeadersBackStack == -1; 15761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 15861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingHeaders) { 15961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().beginTransaction() 16061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 16161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 16561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void save(Bundle outState) { 16661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putInt(HEADER_STACK_INDEX, mIndexOfHeadersBackStack); 16761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 16961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 17061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 17161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onBackStackChanged() { 17261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getFragmentManager() == null) { 17361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Log.w(TAG, "getFragmentManager() is null, stack:", new Exception()); 17461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 17561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 17661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int count = getFragmentManager().getBackStackEntryCount(); 17761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if backstack is growing and last pushed entry is "headers" backstack, 17861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // remember the index of the entry. 17961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (count > mLastEntryCount) { 18061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackEntry entry = getFragmentManager().getBackStackEntryAt(count - 1); 18161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mWithHeadersBackStackName.equals(entry.getName())) { 18261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = count - 1; 18361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 18461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (count < mLastEntryCount) { 18561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if popped "headers" backstack, initiate the show header transition if needed 18661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mIndexOfHeadersBackStack >= count) { 18769381509eace8e71ba4886e9e1e78cda62b66516Dake Gu if (!isHeadersDataReady()) { 188b3756c53c5be55e8c8a2f6e2cda264407be84881susnata // if main fragment was restored first before BrowseSupportFragment's adapter gets 189b3756c53c5be55e8c8a2f6e2cda264407be84881susnata // restored: don't start header transition, but add the entry back. 19069381509eace8e71ba4886e9e1e78cda62b66516Dake Gu getFragmentManager().beginTransaction() 19169381509eace8e71ba4886e9e1e78cda62b66516Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 19269381509eace8e71ba4886e9e1e78cda62b66516Dake Gu return; 19369381509eace8e71ba4886e9e1e78cda62b66516Dake Gu } 19461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = -1; 19561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingHeaders) { 19661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(true); 19761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 19861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 19961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLastEntryCount = count; 20161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 20461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 20561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Listener for transitions between browse headers and rows. 20661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 20761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static class BrowseTransitionListener { 20861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 20961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Callback when headers transition starts. 21061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 21161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the transition will result in headers 21261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * being shown, false otherwise. 21361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 21461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeadersTransitionStart(boolean withHeaders) { 21561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 21661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 21761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Callback when headers transition stops. 21861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 21961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the transition will result in headers 22061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * being shown, false otherwise. 22161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 22261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeadersTransitionStop(boolean withHeaders) { 22361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 22461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 22561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 226aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private class SetSelectionRunnable implements Runnable { 227aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout static final int TYPE_INVALID = -1; 228aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout static final int TYPE_INTERNAL_SYNC = 0; 229aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout static final int TYPE_USER_REQUEST = 1; 230aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 231aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private int mPosition; 232aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private int mType; 233aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private boolean mSmooth; 234aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 235aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout SetSelectionRunnable() { 236aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout reset(); 237aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 238aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 239aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout void post(int position, int type, boolean smooth) { 240aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // Posting the set selection, rather than calling it immediately, prevents an issue 241aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // with adapter changes. Example: a row is added before the current selected row; 242aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // first the fast lane view updates its selection, then the rows fragment has that 243aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // new selection propagated immediately; THEN the rows view processes the same adapter 244aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout // change and moves the selection again. 245aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout if (type >= mType) { 246aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mPosition = position; 247aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mType = type; 248aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSmooth = smooth; 249aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mBrowseFrame.removeCallbacks(this); 250aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mBrowseFrame.post(this); 251aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 252aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 253aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 254aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout @Override 255aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout public void run() { 256aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout setSelection(mPosition, mSmooth); 257aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout reset(); 258aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 259aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 260aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private void reset() { 261aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mPosition = -1; 262aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mType = TYPE_INVALID; 263aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSmooth = false; 264aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 265aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout } 266aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout 2671c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata /** 268cabb8eca86d0248274f57008ff66427fec2e927csusnata * Possible set of actions that {@link BrowseSupportFragment} exposes to clients. Custom 269cabb8eca86d0248274f57008ff66427fec2e927csusnata * fragments can interact with {@link BrowseSupportFragment} using this interface. 270cabb8eca86d0248274f57008ff66427fec2e927csusnata */ 271cabb8eca86d0248274f57008ff66427fec2e927csusnata public interface FragmentHost { 272cabb8eca86d0248274f57008ff66427fec2e927csusnata /** 273a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * Fragments are required to invoke this callback once their view is created 274a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * inside {@link Fragment#onViewCreated} method. {@link BrowseSupportFragment} starts the entrance 275cabb8eca86d0248274f57008ff66427fec2e927csusnata * animation only after receiving this callback. Failure to invoke this method 276cabb8eca86d0248274f57008ff66427fec2e927csusnata * will lead to fragment not showing up. 277cabb8eca86d0248274f57008ff66427fec2e927csusnata * 278cabb8eca86d0248274f57008ff66427fec2e927csusnata * @param fragmentAdapter {@link MainFragmentAdapter} used by the current fragment. 279cabb8eca86d0248274f57008ff66427fec2e927csusnata */ 280cabb8eca86d0248274f57008ff66427fec2e927csusnata void notifyViewCreated(MainFragmentAdapter fragmentAdapter); 2816fd4441435b14669deced90a05097dd5fe459acesusnata 2826fd4441435b14669deced90a05097dd5fe459acesusnata /** 283a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * Fragments mapped to {@link PageRow} are required to invoke this callback once their data 284a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * is created for transition, the entrance animation only after receiving this callback. 285a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * Failure to invoke this method will lead to fragment not showing up. 286a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * 287a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu * @param fragmentAdapter {@link MainFragmentAdapter} used by the current fragment. 288a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu */ 289a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu void notifyDataReady(MainFragmentAdapter fragmentAdapter); 290a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 291a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu /** 292a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * Show or hide title view in {@link BrowseSupportFragment} for fragments mapped to 293a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * {@link PageRow}. Otherwise the request is ignored, in that case BrowseSupportFragment is fully 294a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * in control of showing/hiding title view. 295a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * <p> 296a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * When HeadersSupportFragment is visible, BrowseSupportFragment will hide search affordance view if 297a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu * there are other focusable rows above currently focused row. 2986fd4441435b14669deced90a05097dd5fe459acesusnata * 2996fd4441435b14669deced90a05097dd5fe459acesusnata * @param show Boolean indicating whether or not to show the title view. 3006fd4441435b14669deced90a05097dd5fe459acesusnata */ 3016fd4441435b14669deced90a05097dd5fe459acesusnata void showTitleView(boolean show); 302cabb8eca86d0248274f57008ff66427fec2e927csusnata } 303cabb8eca86d0248274f57008ff66427fec2e927csusnata 304cabb8eca86d0248274f57008ff66427fec2e927csusnata /** 305cabb8eca86d0248274f57008ff66427fec2e927csusnata * Default implementation of {@link FragmentHost} that is used only by 306cabb8eca86d0248274f57008ff66427fec2e927csusnata * {@link BrowseSupportFragment}. 307cabb8eca86d0248274f57008ff66427fec2e927csusnata */ 308cabb8eca86d0248274f57008ff66427fec2e927csusnata private final class FragmentHostImpl implements FragmentHost { 3097350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata boolean mShowTitleView = true; 310cabb8eca86d0248274f57008ff66427fec2e927csusnata 31199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas FragmentHostImpl() { 31299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas } 31399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas 314cabb8eca86d0248274f57008ff66427fec2e927csusnata @Override 315cabb8eca86d0248274f57008ff66427fec2e927csusnata public void notifyViewCreated(MainFragmentAdapter fragmentAdapter) { 31689097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.fireEvent(EVT_MAIN_FRAGMENT_VIEW_CREATED); 31789097f67f988ebba714a95e10369665280db0c27Dake Gu if (!mIsPageRow) { 31889097f67f988ebba714a95e10369665280db0c27Dake Gu // If it's not a PageRow: it's a ListRow, so we already have data ready. 31989097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.fireEvent(EVT_SCREEN_DATA_READY); 32089097f67f988ebba714a95e10369665280db0c27Dake Gu } 321a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu } 322a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 323a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu @Override 324a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu public void notifyDataReady(MainFragmentAdapter fragmentAdapter) { 325a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu // If fragment host is not the currently active fragment (in BrowseSupportFragment), then 326a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu // ignore the request. 327a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu if (mMainFragmentAdapter == null || mMainFragmentAdapter.getFragmentHost() != this) { 328a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu return; 329a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu } 330a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 331a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu // We only honor showTitle request for PageRows. 332a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu if (!mIsPageRow) { 333a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu return; 334a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu } 335a471ba40d52cde2d5a0afeded68c9d915f76183bDake Gu 33689097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.fireEvent(EVT_SCREEN_DATA_READY); 337cabb8eca86d0248274f57008ff66427fec2e927csusnata } 3386fd4441435b14669deced90a05097dd5fe459acesusnata 3396fd4441435b14669deced90a05097dd5fe459acesusnata @Override 3406fd4441435b14669deced90a05097dd5fe459acesusnata public void showTitleView(boolean show) { 3417350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata mShowTitleView = show; 342d0fc2e48059f718676a531af06a31849f54c1ca9susnata 343d0fc2e48059f718676a531af06a31849f54c1ca9susnata // If fragment host is not the currently active fragment (in BrowseSupportFragment), then 344d0fc2e48059f718676a531af06a31849f54c1ca9susnata // ignore the request. 345d0fc2e48059f718676a531af06a31849f54c1ca9susnata if (mMainFragmentAdapter == null || mMainFragmentAdapter.getFragmentHost() != this) { 346d0fc2e48059f718676a531af06a31849f54c1ca9susnata return; 347b10ba3b01290ce801180a3d5dc992825af8cb3absusnata } 348d0fc2e48059f718676a531af06a31849f54c1ca9susnata 349d0fc2e48059f718676a531af06a31849f54c1ca9susnata // We only honor showTitle request for PageRows. 350d0fc2e48059f718676a531af06a31849f54c1ca9susnata if (!mIsPageRow) { 351d0fc2e48059f718676a531af06a31849f54c1ca9susnata return; 352d0fc2e48059f718676a531af06a31849f54c1ca9susnata } 353d0fc2e48059f718676a531af06a31849f54c1ca9susnata 3548ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu updateTitleViewVisibility(); 3556fd4441435b14669deced90a05097dd5fe459acesusnata } 356cabb8eca86d0248274f57008ff66427fec2e927csusnata } 357cabb8eca86d0248274f57008ff66427fec2e927csusnata 358cabb8eca86d0248274f57008ff66427fec2e927csusnata /** 35944ece5ceaaee232f9139ccbde40ac4a5e642bdeeChristophe Beyls * Interface that defines the interaction between {@link BrowseSupportFragment} and its main 360fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * content fragment. The key method is {@link MainFragmentAdapter#getFragment()}, 3611c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * it will be used to get the fragment to be shown in the content section. Clients can 36244ece5ceaaee232f9139ccbde40ac4a5e642bdeeChristophe Beyls * provide any implementation of fragment and customize its interaction with 3631c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * {@link BrowseSupportFragment} by overriding the necessary methods. 3641c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * 3651c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * <p> 3661c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * Clients are expected to provide 367fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * an instance of {@link MainFragmentAdapterRegistry} which will be responsible for providing 368fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * implementations of {@link MainFragmentAdapter} for given content types. Currently 3691c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * we support different types of content - {@link ListRow}, {@link PageRow} or any subtype 3701c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * of {@link Row}. We provide an out of the box adapter implementation for any rows other than 371fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * {@link PageRow} - {@link android.support.v17.leanback.app.RowsSupportFragment.MainFragmentAdapter}. 3721c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * 3731c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * <p> 3741c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * {@link PageRow} is intended to give full flexibility to developers in terms of Fragment 375fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * design. Users will have to provide an implementation of {@link MainFragmentAdapter} 376fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * and provide that through {@link MainFragmentAdapterRegistry}. 377fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * {@link MainFragmentAdapter} implementation can supply any fragment and override 3781c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * just those interactions that makes sense. 3791c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata */ 380fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public static class MainFragmentAdapter<T extends Fragment> { 381f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata private boolean mScalingEnabled; 382fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private final T mFragment; 38399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas FragmentHostImpl mFragmentHost; 384fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 385fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public MainFragmentAdapter(T fragment) { 386fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak this.mFragment = fragment; 387fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 388fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 389fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final T getFragment() { 390fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return mFragment; 391fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 3922f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 3932f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 3942f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Returns whether its scrolling. 3952f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 3961c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public boolean isScrolling() { 3971c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return false; 3981c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 3992f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4002f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 4012f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Set the visibility of titles/hovercard of browse rows. 4022f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 4031c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void setExpand(boolean expand) { 4041c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 4052f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4062f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 4072f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * For rows that willing to participate entrance transition, this function 4082f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * hide views if afterTransition is true, show views if afterTransition is false. 4092f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 4101c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void setEntranceTransitionState(boolean state) { 4111c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 4122f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4132f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 4142f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Sets the window alignment and also the pivots for scale operation. 4152f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 4161c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void setAlignment(int windowAlignOffsetFromTop) { 4171c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 4182f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4192f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 4202f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Callback indicating transition prepare start. 4212f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 4221c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public boolean onTransitionPrepare() { 4231c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return false; 4241c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 4252f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4262f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 4272f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Callback indicating transition start. 4282f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 4291c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void onTransitionStart() { 4301c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 4312f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4322f5ebf3f6f7bb6a24856f389e369b247118ba119susnata /** 4332f5ebf3f6f7bb6a24856f389e369b247118ba119susnata * Callback indicating transition end. 4342f5ebf3f6f7bb6a24856f389e369b247118ba119susnata */ 4351c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata public void onTransitionEnd() { 4361c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 437f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata 438f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata /** 439f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * Returns whether row scaling is enabled. 440f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata */ 441f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata public boolean isScalingEnabled() { 442f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata return mScalingEnabled; 443f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata } 444f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata 445f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata /** 446f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * Sets the row scaling property. 447f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata */ 448f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata public void setScalingEnabled(boolean scalingEnabled) { 449f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata this.mScalingEnabled = scalingEnabled; 450f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata } 451cabb8eca86d0248274f57008ff66427fec2e927csusnata 4527350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata /** 4537350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata * Returns the current host interface so that main fragment can interact with 4547350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata * {@link BrowseSupportFragment}. 4557350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata */ 456cabb8eca86d0248274f57008ff66427fec2e927csusnata public final FragmentHost getFragmentHost() { 457cabb8eca86d0248274f57008ff66427fec2e927csusnata return mFragmentHost; 458cabb8eca86d0248274f57008ff66427fec2e927csusnata } 4597350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 4607350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata void setFragmentHost(FragmentHostImpl fragmentHost) { 4617350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata this.mFragmentHost = fragmentHost; 4627350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata } 4632f5ebf3f6f7bb6a24856f389e369b247118ba119susnata } 4642f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 4651c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata /** 466d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Interface to be implemented by all fragments for providing an instance of 467d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * {@link MainFragmentAdapter}. Both {@link RowsSupportFragment} and custom fragment provided 468d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * against {@link PageRow} will need to implement this interface. 469d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 470d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata public interface MainFragmentAdapterProvider { 471d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 472d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Returns an instance of {@link MainFragmentAdapter} that {@link BrowseSupportFragment} 473d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * would use to communicate with the target fragment. 474d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 475d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata MainFragmentAdapter getMainFragmentAdapter(); 476d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 477d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 478d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 47944ece5ceaaee232f9139ccbde40ac4a5e642bdeeChristophe Beyls * Interface to be implemented by {@link RowsSupportFragment} and its subclasses for providing 480d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * an instance of {@link MainFragmentRowsAdapter}. 481d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 482d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata public interface MainFragmentRowsAdapterProvider { 483d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 484d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * Returns an instance of {@link MainFragmentRowsAdapter} that {@link BrowseSupportFragment} 485d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * would use to communicate with the target fragment. 486d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata */ 487d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata MainFragmentRowsAdapter getMainFragmentRowsAdapter(); 488d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 489d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 490d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata /** 491d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * This is used to pass information to {@link RowsSupportFragment} or its subclasses. 492d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * {@link BrowseSupportFragment} uses this interface to pass row based interaction events to 493d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata * the target fragment. 4941c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata */ 495fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public static class MainFragmentRowsAdapter<T extends Fragment> { 496fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private final T mFragment; 497fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 498fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public MainFragmentRowsAdapter(T fragment) { 499fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (fragment == null) { 500fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak throw new IllegalArgumentException("Fragment can't be null"); 501fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 502fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak this.mFragment = fragment; 503fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 504fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 505fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final T getFragment() { 506fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return mFragment; 507fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 508a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 509a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Set the visibility titles/hover of browse rows. 510a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 511a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setAdapter(ObjectAdapter adapter) { 512a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 5131c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 514a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 515a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Sets an item clicked listener on the fragment. 516a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 517a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 518a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 519a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 520a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 521a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Sets an item selection listener. 522a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 523a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 524a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 525a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 526a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 527a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Selects a Row and perform an optional task on the Row. 528a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 529a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setSelectedPosition(int rowPosition, 530a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata boolean smooth, 531a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata final Presenter.ViewHolderTask rowHolderTask) { 532a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 533a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 534a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 535a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata * Selects a Row. 536a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 537a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public void setSelectedPosition(int rowPosition, boolean smooth) { 538a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 539a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 540a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 541181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu * @return The position of selected row. 542a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 543a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata public int getSelectedPosition() { 544a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata return 0; 545a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 546181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu 547181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu /** 548181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu * @param position Position of Row. 549181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu * @return Row ViewHolder. 550181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu */ 551181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu public RowPresenter.ViewHolder findRowViewHolderByPosition(int position) { 552181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu return null; 553181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu } 554a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 5551c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 556a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata private boolean createMainFragment(ObjectAdapter adapter, int position) { 557a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata Object item = null; 558f89c67eeac3938f245c858774cc7c9f87fb7487dDake Gu if (!mCanShowHeaders) { 559f89c67eeac3938f245c858774cc7c9f87fb7487dDake Gu // when header is disabled, we can decide to use RowsSupportFragment even no data. 560f89c67eeac3938f245c858774cc7c9f87fb7487dDake Gu } else if (adapter == null || adapter.size() == 0) { 561fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return false; 562a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } else { 563bb0a680c10b84b83833a59634373140f8bd0750csusnata if (position < 0) { 564bb0a680c10b84b83833a59634373140f8bd0750csusnata position = 0; 565bb0a680c10b84b83833a59634373140f8bd0750csusnata } else if (position >= adapter.size()) { 5661c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata throw new IllegalArgumentException( 5671c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata String.format("Invalid position %d requested", position)); 5681c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 569a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata item = adapter.get(position); 570a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 5711c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 572fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak boolean oldIsPageRow = mIsPageRow; 573f89c67eeac3938f245c858774cc7c9f87fb7487dDake Gu mIsPageRow = mCanShowHeaders && item instanceof PageRow; 574fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak boolean swap; 575fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 576fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragment == null) { 577fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak swap = true; 578a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } else { 579fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (oldIsPageRow) { 580fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak swap = true; 581fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } else { 582fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak swap = mIsPageRow; 583fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 5841c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 585fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 586fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (swap) { 587fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragment = mMainFragmentAdapterRegistry.createFragment(item); 588d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata if (!(mMainFragment instanceof MainFragmentAdapterProvider)) { 589d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata throw new IllegalArgumentException( 590d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata "Fragment must implement MainFragmentAdapterProvider"); 591d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 592d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 593d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentAdapter = ((MainFragmentAdapterProvider)mMainFragment) 594d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentAdapter(); 595cabb8eca86d0248274f57008ff66427fec2e927csusnata mMainFragmentAdapter.setFragmentHost(new FragmentHostImpl()); 596fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (!mIsPageRow) { 597d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata if (mMainFragment instanceof MainFragmentRowsAdapterProvider) { 598d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = ((MainFragmentRowsAdapterProvider)mMainFragment) 599d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentRowsAdapter(); 600d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } else { 601d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = null; 602d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 603fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mIsPageRow = mMainFragmentRowsAdapter == null; 604fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } else { 605fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter = null; 606fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 607fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 608d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata 609fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return swap; 610a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 611a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata 612a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata /** 613fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * Factory class responsible for creating fragment given the current item. {@link ListRow} 61444ece5ceaaee232f9139ccbde40ac4a5e642bdeeChristophe Beyls * should return {@link RowsSupportFragment} or its subclass whereas {@link PageRow} 615fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * can return any fragment class. 616a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata */ 617fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public abstract static class FragmentFactory<T extends Fragment> { 618fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public abstract T createFragment(Object row); 619fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 6201c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 621fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak /** 622fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * FragmentFactory implementation for {@link ListRow}. 623fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak */ 624fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public static class ListRowFragmentFactory extends FragmentFactory<RowsSupportFragment> { 625fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak @Override 626fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public RowsSupportFragment createFragment(Object row) { 627fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return new RowsSupportFragment(); 62880a1d2dfbe5c1f26370cc1753c3ae321f126f5d2Carlos Valdivia } 629fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 6304400ca12ff731a7392715bc3d8ad3539b4c37889susnata 631fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak /** 632fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * Registry class maintaining the mapping of {@link Row} subclasses to {@link FragmentFactory}. 633fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * BrowseRowFragment automatically registers {@link ListRowFragmentFactory} for 634fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * handling {@link ListRow}. Developers can override that and also if they want to 635fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * use custom fragment, they can register a custom {@link FragmentFactory} 636fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * against {@link PageRow}. 637fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak */ 638fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final static class MainFragmentAdapterRegistry { 639abc73958d264e1eed7fd401a18be1d9ede8304ebAurimas Liutikas private final Map<Class, FragmentFactory> mItemToFragmentFactoryMapping = new HashMap<>(); 640cfcb31c4895793dda843faf67d1b769268e3cce8susnata private final static FragmentFactory sDefaultFragmentFactory = new ListRowFragmentFactory(); 641cfcb31c4895793dda843faf67d1b769268e3cce8susnata 642cfcb31c4895793dda843faf67d1b769268e3cce8susnata public MainFragmentAdapterRegistry() { 643cfcb31c4895793dda843faf67d1b769268e3cce8susnata registerFragment(ListRow.class, sDefaultFragmentFactory); 644cfcb31c4895793dda843faf67d1b769268e3cce8susnata } 645fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 646fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public void registerFragment(Class rowClass, FragmentFactory factory) { 647cfcb31c4895793dda843faf67d1b769268e3cce8susnata mItemToFragmentFactoryMapping.put(rowClass, factory); 648fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 649fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 650fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public Fragment createFragment(Object item) { 651f89c67eeac3938f245c858774cc7c9f87fb7487dDake Gu FragmentFactory fragmentFactory = item == null ? sDefaultFragmentFactory : 652f89c67eeac3938f245c858774cc7c9f87fb7487dDake Gu mItemToFragmentFactoryMapping.get(item.getClass()); 653cfcb31c4895793dda843faf67d1b769268e3cce8susnata if (fragmentFactory == null && !(item instanceof PageRow)) { 654cfcb31c4895793dda843faf67d1b769268e3cce8susnata fragmentFactory = sDefaultFragmentFactory; 655cfcb31c4895793dda843faf67d1b769268e3cce8susnata } 656cfcb31c4895793dda843faf67d1b769268e3cce8susnata 657cfcb31c4895793dda843faf67d1b769268e3cce8susnata return fragmentFactory.createFragment(item); 658a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 6591c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 6602f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 66199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas static final String TAG = "BrowseSupportFragment"; 66261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 66361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String LB_HEADERS_BACKSTACK = "lbHeadersBackStack_"; 66461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 66599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas static boolean DEBUG = false; 66661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 66761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is enabled and shown by default. */ 66861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_ENABLED = 1; 66961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 67061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is enabled and hidden by default. */ 67161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_HIDDEN = 2; 67261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 67361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is disabled and will never be shown. */ 67461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_DISABLED = 3; 67561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 6763103f63e99d47573823957f7aa34308555873221Aurimas Liutikas private MainFragmentAdapterRegistry mMainFragmentAdapterRegistry = 6773103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new MainFragmentAdapterRegistry(); 67899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas MainFragmentAdapter mMainFragmentAdapter; 67999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Fragment mMainFragment; 68099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas HeadersSupportFragment mHeadersSupportFragment; 681fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private MainFragmentRowsAdapter mMainFragmentRowsAdapter; 68261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ObjectAdapter mAdapter; 6848ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private PresenterSelector mAdapterPresenter; 6858ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private PresenterSelector mWrappingPresenterSelector; 68661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mHeadersState = HEADERS_ENABLED; 68861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBrandColor = Color.TRANSPARENT; 68961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mBrandColorSet; 69061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 69199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas BrowseFrameLayout mBrowseFrame; 692a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private ScaleFrameLayout mScaleFrameLayout; 69399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas boolean mHeadersBackStackEnabled = true; 69499ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas String mWithHeadersBackStackName; 69599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas boolean mShowingHeaders = true; 69699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas boolean mCanShowHeaders = true; 6978e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing private int mContainerListMarginStart; 69861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mContainerListAlignTop; 699f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata private boolean mMainFragmentScaleEnabled = true; 70099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas OnItemViewSelectedListener mExternalOnItemViewSelectedListener; 70161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemViewClickedListener mOnItemViewClickedListener; 702bb0a680c10b84b83833a59634373140f8bd0750csusnata private int mSelectedPosition = -1; 703f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata private float mScaleFactor; 70499ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas boolean mIsPageRow; 70561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 70661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private PresenterSelector mHeaderPresenterSelector; 707aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout private final SetSelectionRunnable mSetSelectionRunnable = new SetSelectionRunnable(); 70861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 70961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // transition related: 71099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Object mSceneWithHeaders; 71199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Object mSceneWithoutHeaders; 712c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private Object mSceneAfterEntranceTransition; 71399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas Object mHeadersTransition; 71499ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas BackStackListener mBackStackChangedListener; 71599ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas BrowseTransitionListener mBrowseTransitionListener; 71661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 71761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_TITLE = BrowseSupportFragment.class.getCanonicalName() + ".title"; 71861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_HEADERS_STATE = 71961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BrowseSupportFragment.class.getCanonicalName() + ".headersState"; 72061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 72161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 722a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Creates arguments for a browse fragment. 72361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 72461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param args The Bundle to place arguments into, or null if the method 72561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * should return a new Bundle. 72661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param title The title of the BrowseSupportFragment. 72761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headersState The initial state of the headers of the 72861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * BrowseSupportFragment. Must be one of {@link #HEADERS_ENABLED}, {@link 72961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * #HEADERS_HIDDEN}, or {@link #HEADERS_DISABLED}. 73061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @return A Bundle with the given arguments for creating a BrowseSupportFragment. 73161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 73261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static Bundle createArgs(Bundle args, String title, int headersState) { 73361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args == null) { 73461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args = new Bundle(); 73561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 73661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args.putString(ARG_TITLE, title); 73761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args.putInt(ARG_HEADERS_STATE, headersState); 73861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return args; 73961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 74061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 74161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 74261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the brand color for the browse fragment. The brand color is used as 74361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the primary color for UI elements in the browse fragment. For example, 74461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the background color of the headers fragment uses the brand color. 74561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 74661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param color The color to use as the brand color of the fragment. 74761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 74870acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye public void setBrandColor(@ColorInt int color) { 74961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrandColor = color; 75061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrandColorSet = true; 75161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 75261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 75361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setBackgroundColor(mBrandColor); 75461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 75561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 75661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 75761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 75861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the brand color for the browse fragment. 75961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * The default is transparent. 76061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 76170acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye @ColorInt 76261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getBrandColor() { 76361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mBrandColor; 76461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 76561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 76661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 7678ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu * Wrapping app provided PresenterSelector to support InvisibleRowPresenter for SectionRow 7688ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu * DividerRow and PageRow. 7698ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu */ 7708ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private void createAndSetWrapperPresenter() { 7718ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final PresenterSelector adapterPresenter = mAdapter.getPresenterSelector(); 7728ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (adapterPresenter == null) { 7738ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu throw new IllegalArgumentException("Adapter.getPresenterSelector() is null"); 7748ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7758ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (adapterPresenter == mAdapterPresenter) { 7768ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return; 7778ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7788ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu mAdapterPresenter = adapterPresenter; 7798ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 7808ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu Presenter[] presenters = adapterPresenter.getPresenters(); 7818ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Presenter invisibleRowPresenter = new InvisibleRowPresenter(); 7828ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Presenter[] allPresenters = new Presenter[presenters.length + 1]; 7838ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu System.arraycopy(allPresenters, 0, presenters, 0, presenters.length); 7848ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu allPresenters[allPresenters.length - 1] = invisibleRowPresenter; 7858ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu mAdapter.setPresenterSelector(new PresenterSelector() { 7868ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu @Override 7878ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu public Presenter getPresenter(Object item) { 7888ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu Row row = (Row) item; 7898ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (row.isRenderedAsRowView()) { 7908ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return adapterPresenter.getPresenter(item); 7918ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 7928ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return invisibleRowPresenter; 7938ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7948ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 7958ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 7968ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu @Override 7978ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu public Presenter[] getPresenters() { 7988ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return allPresenters; 7998ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 8008ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu }); 8018ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 8028ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 8038ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu /** 80461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the adapter containing the rows for the fragment. 80561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 80661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>The items referenced by the adapter must be be derived from 80761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link Row}. These rows will be used by the rows fragment and the headers 80861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * fragment (if not disabled) to render the browse rows. 80961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 81061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param adapter An ObjectAdapter for the browse rows. All items must 81161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * derive from {@link Row}. 81261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 81361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setAdapter(ObjectAdapter adapter) { 81461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mAdapter = adapter; 8158ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu createAndSetWrapperPresenter(); 816c0ad3d1d9ee64cf0bdb68ac70bfb04cc919c53e6Dake Gu if (getView() == null) { 817c0ad3d1d9ee64cf0bdb68ac70bfb04cc919c53e6Dake Gu return; 818c0ad3d1d9ee64cf0bdb68ac70bfb04cc919c53e6Dake Gu } 819bb0a680c10b84b83833a59634373140f8bd0750csusnata replaceMainFragment(mSelectedPosition); 820bb0a680c10b84b83833a59634373140f8bd0750csusnata 821bb0a680c10b84b83833a59634373140f8bd0750csusnata if (adapter != null) { 822bb0a680c10b84b83833a59634373140f8bd0750csusnata if (mMainFragmentRowsAdapter != null) { 823b3756c53c5be55e8c8a2f6e2cda264407be84881susnata mMainFragmentRowsAdapter.setAdapter(new ListRowDataAdapter(adapter)); 824bb0a680c10b84b83833a59634373140f8bd0750csusnata } 82561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setAdapter(adapter); 82661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 82761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 82861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 829fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public final MainFragmentAdapterRegistry getMainFragmentRegistry() { 830fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak return mMainFragmentAdapterRegistry; 8311c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 832fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 83361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 83461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the adapter containing the rows for the fragment. 83561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 83661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public ObjectAdapter getAdapter() { 83761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mAdapter; 83861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 83961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 84061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 84161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item selection listener. 84261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 84361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 84461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemViewSelectedListener = listener; 84561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 84661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 84761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 84861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns an item selection listener. 84961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 85061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemViewSelectedListener getOnItemViewSelectedListener() { 85161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mExternalOnItemViewSelectedListener; 85261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 85361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 85461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 8551c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * Get RowsSupportFragment if it's bound to BrowseSupportFragment or null if either BrowseSupportFragment has 8561c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * not been created yet or a different fragment is bound to it. 8571c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * 8581c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata * @return RowsSupportFragment if it's bound to BrowseSupportFragment or null otherwise. 8590d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 8600d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public RowsSupportFragment getRowsSupportFragment() { 8611c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata if (mMainFragment instanceof RowsSupportFragment) { 8621c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return (RowsSupportFragment) mMainFragment; 8631c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 8641c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 8651c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return null; 8660d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 8670d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 8680d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 869489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu * @return Current main fragment or null if not created. 870489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu */ 871489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu public Fragment getMainFragment() { 872489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu return mMainFragment; 873489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu } 874489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu 875489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu /** 8760d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * Get currently bound HeadersSupportFragment or null if HeadersSupportFragment has not been created yet. 8770d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @return Currently bound HeadersSupportFragment or null if HeadersSupportFragment has not been created yet. 8780d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 8790d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public HeadersSupportFragment getHeadersSupportFragment() { 8800d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu return mHeadersSupportFragment; 8810d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 8820d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 8830d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 88461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item clicked listener on the fragment. 88561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * OnItemViewClickedListener will override {@link View.OnClickListener} that 88661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}. 887cabb8eca86d0248274f57008ff66427fec2e927csusnata * So in general, developer should choose one of the listeners but not both. 88861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 88961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 89061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOnItemViewClickedListener = listener; 8912aff8659c7362b48f099a13ffad390bf7984dd5aJaewan Kim if (mMainFragmentRowsAdapter != null) { 892fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setOnItemViewClickedListener(listener); 89361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 89461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 89561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 89661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 89761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the item Clicked listener. 89861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 89961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemViewClickedListener getOnItemViewClickedListener() { 90061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mOnItemViewClickedListener; 90161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 90261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 90361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 904a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Starts a headers transition. 90561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 90661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>This method will begin a transition to either show or hide the 90761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * headers, depending on the value of withHeaders. If headers are disabled 90861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * for this browse fragment, this method will throw an exception. 90961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 91061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the headers should transition to being shown, 91161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * false if the transition should result in headers being hidden. 91261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 91361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void startHeadersTransition(boolean withHeaders) { 91461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders) { 91561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalStateException("Cannot start headers transition"); 91661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 91761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (isInHeadersTransition() || mShowingHeaders == withHeaders) { 91861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 91961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 92061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(withHeaders); 92161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 92261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 92361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 92461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if the headers transition is currently running. 92561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 92661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isInHeadersTransition() { 92761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersTransition != null; 92861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 92961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 93061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 93161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if headers are shown. 93261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 93361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isShowingHeaders() { 93461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mShowingHeaders; 93561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 93761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 938a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Sets a listener for browse fragment transitions. 93961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 94061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param listener The listener to call when a browse headers transition 94161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * begins or ends. 94261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 94361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setBrowseTransitionListener(BrowseTransitionListener listener) { 94461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener = listener; 94561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 94661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 94761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 948f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * @deprecated use {@link BrowseSupportFragment#enableMainFragmentScaling(boolean)} instead. 94961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 95061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param enable true to enable row scaling 95161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 952d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette @Deprecated 95361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void enableRowScaling(boolean enable) { 954f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata enableMainFragmentScaling(enable); 955f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata } 956f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata 957f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata /** 958f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * Enables scaling of main fragment when headers are present. For the page/row fragment, 959f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * scaling is enabled only when both this method and 960fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak * {@link MainFragmentAdapter#isScalingEnabled()} are enabled. 961f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * 962f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata * @param enable true to enable row scaling 963f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata */ 964f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata public void enableMainFragmentScaling(boolean enable) { 965f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata mMainFragmentScaleEnabled = enable; 96661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 96761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 96899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas void startHeadersTransitionInternal(final boolean withHeaders) { 96961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getFragmentManager().isDestroyed()) { 97061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 97161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 97269381509eace8e71ba4886e9e1e78cda62b66516Dake Gu if (!isHeadersDataReady()) { 97369381509eace8e71ba4886e9e1e78cda62b66516Dake Gu return; 97469381509eace8e71ba4886e9e1e78cda62b66516Dake Gu } 97561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = withHeaders; 9761c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionPrepare(); 9771c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionStart(); 978a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata onExpandTransitionStart(!withHeaders, new Runnable() { 97961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 98061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 981902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu mHeadersSupportFragment.onTransitionPrepare(); 98261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.onTransitionStart(); 98361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu createHeadersTransition(); 98461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrowseTransitionListener != null) { 98561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener.onHeadersTransitionStart(withHeaders); 98661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9871c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata TransitionHelper.runTransition( 9881c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata withHeaders ? mSceneWithHeaders : mSceneWithoutHeaders, mHeadersTransition); 98961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersBackStackEnabled) { 99061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!withHeaders) { 99161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().beginTransaction() 99261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 99361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 99461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int index = mBackStackChangedListener.mIndexOfHeadersBackStack; 99561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (index >= 0) { 99661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackEntry entry = getFragmentManager().getBackStackEntryAt(index); 99761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().popBackStackImmediate(entry.getId(), 99861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu FragmentManager.POP_BACK_STACK_INCLUSIVE); 99961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 100461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 10060d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu boolean isVerticalScrolling() { 100761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // don't run transition 10081c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return mHeadersSupportFragment.isScrolling() || mMainFragmentAdapter.isScrolling(); 100961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 101061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1011e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout 101261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener = 101361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new BrowseFrameLayout.OnFocusSearchListener() { 101461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 101561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onFocusSearch(View focused, int direction) { 101661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if headers is running transition, focus stays 10175ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout if (mCanShowHeaders && isInHeadersTransition()) { 10185ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout return focused; 10195ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout } 102061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction); 10215ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout 10223103f63e99d47573823957f7aa34308555873221Aurimas Liutikas if (getTitleView() != null && focused != getTitleView() 10233103f63e99d47573823957f7aa34308555873221Aurimas Liutikas && direction == View.FOCUS_UP) { 1024e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout return getTitleView(); 1025e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout } 10263103f63e99d47573823957f7aa34308555873221Aurimas Liutikas if (getTitleView() != null && getTitleView().hasFocus() 10273103f63e99d47573823957f7aa34308555873221Aurimas Liutikas && direction == View.FOCUS_DOWN) { 10283103f63e99d47573823957f7aa34308555873221Aurimas Liutikas return mCanShowHeaders && mShowingHeaders 10293103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? mHeadersSupportFragment.getVerticalGridView() : mMainFragment.getView(); 10305ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout } 10315ae73b45620a3d535b2d279512d5d34603e2bdb1Craig Stout 10328e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing boolean isRtl = ViewCompat.getLayoutDirection(focused) == View.LAYOUT_DIRECTION_RTL; 10338e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing int towardStart = isRtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT; 10348e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing int towardEnd = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT; 1035e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (mCanShowHeaders && direction == towardStart) { 103669381509eace8e71ba4886e9e1e78cda62b66516Dake Gu if (isVerticalScrolling() || mShowingHeaders || !isHeadersDataReady()) { 103761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return focused; 103861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 103961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersSupportFragment.getVerticalGridView(); 10408e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing } else if (direction == towardEnd) { 1041e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout if (isVerticalScrolling()) { 104261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return focused; 1043489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu } else if (mMainFragment != null && mMainFragment.getView() != null) { 1044489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu return mMainFragment.getView(); 104561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1046489c9a861b7cde47efcd5cf6351bc9696786ae41Dake Gu return focused; 10478ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else if (direction == View.FOCUS_DOWN && mShowingHeaders) { 10488ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // disable focus_down moving into PageFragment. 10498ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return focused; 105061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 105161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return null; 105261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 105361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 105461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 105561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 105699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas final boolean isHeadersDataReady() { 105769381509eace8e71ba4886e9e1e78cda62b66516Dake Gu return mAdapter != null && mAdapter.size() != 0; 105869381509eace8e71ba4886e9e1e78cda62b66516Dake Gu } 105969381509eace8e71ba4886e9e1e78cda62b66516Dake Gu 106061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final BrowseFrameLayout.OnChildFocusListener mOnChildFocusListener = 106161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new BrowseFrameLayout.OnChildFocusListener() { 106261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 106361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 106461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 106528fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu if (getChildFragmentManager().isDestroyed()) { 106628fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu return true; 106728fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu } 106861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Make sure not changing focus when requestFocus() is called. 106961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders && mShowingHeaders) { 10703103f63e99d47573823957f7aa34308555873221Aurimas Liutikas if (mHeadersSupportFragment != null && mHeadersSupportFragment.getView() != null 10715d926e60b034b2e4d1404c6ac088a13b9c91ee3eDake Gu && mHeadersSupportFragment.getView().requestFocus( 10725d926e60b034b2e4d1404c6ac088a13b9c91ee3eDake Gu direction, previouslyFocusedRect)) { 107361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return true; 107461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 107561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10763103f63e99d47573823957f7aa34308555873221Aurimas Liutikas if (mMainFragment != null && mMainFragment.getView() != null 10773103f63e99d47573823957f7aa34308555873221Aurimas Liutikas && mMainFragment.getView().requestFocus(direction, previouslyFocusedRect)) { 107861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return true; 107961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1080b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu return getTitleView() != null 1081b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu && getTitleView().requestFocus(direction, previouslyFocusedRect); 10821c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 108361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 108461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 108561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onRequestChildFocus(View child, View focused) { 108628fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu if (getChildFragmentManager().isDestroyed()) { 108728fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu return; 108828fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu } 108961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders || isInHeadersTransition()) return; 109028fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu int childId = child.getId(); 109161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (childId == R.id.browse_container_dock && mShowingHeaders) { 109261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(false); 109361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (childId == R.id.browse_headers_dock && !mShowingHeaders) { 109461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(true); 109561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 109661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 109761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 109861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 109961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 110061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onSaveInstanceState(Bundle outState) { 1101e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout super.onSaveInstanceState(outState); 1102fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak outState.putInt(CURRENT_SELECTED_POSITION, mSelectedPosition); 1103fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak outState.putBoolean(IS_PAGE_ROW, mIsPageRow); 1104fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 110561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBackStackChangedListener != null) { 110661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBackStackChangedListener.save(outState); 110761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 110861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putBoolean(HEADER_SHOW, mShowingHeaders); 110961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 111061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 111161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 111261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 111361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onCreate(Bundle savedInstanceState) { 111461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onCreate(savedInstanceState); 11152452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu final Context context = getContext(); 11162452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu TypedArray ta = context.obtainStyledAttributes(R.styleable.LeanbackTheme); 11178e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing mContainerListMarginStart = (int) ta.getDimension( 11182452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu R.styleable.LeanbackTheme_browseRowsMarginStart, context.getResources() 111946443cb5b092f1d9156342645088eead9da026f6Dake Gu .getDimensionPixelSize(R.dimen.lb_browse_rows_margin_start)); 112061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mContainerListAlignTop = (int) ta.getDimension( 11212452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu R.styleable.LeanbackTheme_browseRowsMarginTop, context.getResources() 112246443cb5b092f1d9156342645088eead9da026f6Dake Gu .getDimensionPixelSize(R.dimen.lb_browse_rows_margin_top)); 112361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ta.recycle(); 112461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 112561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu readArguments(getArguments()); 112661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 112734f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (mCanShowHeaders) { 112834f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (mHeadersBackStackEnabled) { 112934f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mWithHeadersBackStackName = LB_HEADERS_BACKSTACK + this; 113034f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mBackStackChangedListener = new BackStackListener(); 113134f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout getFragmentManager().addOnBackStackChangedListener(mBackStackChangedListener); 113234f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mBackStackChangedListener.load(savedInstanceState); 113334f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } else { 113434f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (savedInstanceState != null) { 113534f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mShowingHeaders = savedInstanceState.getBoolean(HEADER_SHOW); 113634f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 113734f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 113834f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 1139a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1140f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata mScaleFactor = getResources().getFraction(R.fraction.lb_browse_rows_scale, 1, 1); 114161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 114261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 114361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 1144fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak public void onDestroyView() { 1145fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter = null; 1146fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentAdapter = null; 1147fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragment = null; 1148fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mHeadersSupportFragment = null; 1149fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak super.onDestroyView(); 1150fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 1151fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 1152fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak @Override 115361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onDestroy() { 115461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBackStackChangedListener != null) { 115561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().removeOnBackStackChangedListener(mBackStackChangedListener); 115661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 115761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onDestroy(); 115861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 115961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 116050cf9ada93e50e906f20f5edf595234ada196d45Dake Gu /** 116150cf9ada93e50e906f20f5edf595234ada196d45Dake Gu * Creates a new {@link HeadersSupportFragment} instance. Subclass of BrowseSupportFragment may override and 116250cf9ada93e50e906f20f5edf595234ada196d45Dake Gu * return an instance of subclass of HeadersSupportFragment, e.g. when app wants to replace presenter 116350cf9ada93e50e906f20f5edf595234ada196d45Dake Gu * to render HeaderItem. 116450cf9ada93e50e906f20f5edf595234ada196d45Dake Gu * 116550cf9ada93e50e906f20f5edf595234ada196d45Dake Gu * @return A new instance of {@link HeadersSupportFragment} or its subclass. 116650cf9ada93e50e906f20f5edf595234ada196d45Dake Gu */ 116750cf9ada93e50e906f20f5edf595234ada196d45Dake Gu public HeadersSupportFragment onCreateHeadersSupportFragment() { 116850cf9ada93e50e906f20f5edf595234ada196d45Dake Gu return new HeadersSupportFragment(); 116950cf9ada93e50e906f20f5edf595234ada196d45Dake Gu } 117050cf9ada93e50e906f20f5edf595234ada196d45Dake Gu 117161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 117261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onCreateView(LayoutInflater inflater, ViewGroup container, 117361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Bundle savedInstanceState) { 11747350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 1175a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata if (getChildFragmentManager().findFragmentById(R.id.scale_frame) == null) { 117650cf9ada93e50e906f20f5edf595234ada196d45Dake Gu mHeadersSupportFragment = onCreateHeadersSupportFragment(); 1177bb0a680c10b84b83833a59634373140f8bd0750csusnata 1178a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata createMainFragment(mAdapter, mSelectedPosition); 1179bb0a680c10b84b83833a59634373140f8bd0750csusnata FragmentTransaction ft = getChildFragmentManager().beginTransaction() 1180bb0a680c10b84b83833a59634373140f8bd0750csusnata .replace(R.id.browse_headers_dock, mHeadersSupportFragment); 1181bb0a680c10b84b83833a59634373140f8bd0750csusnata 1182bb0a680c10b84b83833a59634373140f8bd0750csusnata if (mMainFragment != null) { 1183bb0a680c10b84b83833a59634373140f8bd0750csusnata ft.replace(R.id.scale_frame, mMainFragment); 1184bb0a680c10b84b83833a59634373140f8bd0750csusnata } else { 1185bb0a680c10b84b83833a59634373140f8bd0750csusnata // Empty adapter used to guard against lazy adapter loading. When this 1186bb0a680c10b84b83833a59634373140f8bd0750csusnata // fragment is instantiated, mAdapter might not have the data or might not 1187bb0a680c10b84b83833a59634373140f8bd0750csusnata // have been set. In either of those cases mFragmentAdapter will be null. 1188bb0a680c10b84b83833a59634373140f8bd0750csusnata // This way we can maintain the invariant that mMainFragmentAdapter is never 1189bb0a680c10b84b83833a59634373140f8bd0750csusnata // null and it avoids doing null checks all over the code. 1190bb0a680c10b84b83833a59634373140f8bd0750csusnata mMainFragmentAdapter = new MainFragmentAdapter(null); 1191cabb8eca86d0248274f57008ff66427fec2e927csusnata mMainFragmentAdapter.setFragmentHost(new FragmentHostImpl()); 1192bb0a680c10b84b83833a59634373140f8bd0750csusnata } 1193bb0a680c10b84b83833a59634373140f8bd0750csusnata 1194bb0a680c10b84b83833a59634373140f8bd0750csusnata ft.commit(); 119561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 119661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment = (HeadersSupportFragment) getChildFragmentManager() 1197fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak .findFragmentById(R.id.browse_headers_dock); 1198fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragment = getChildFragmentManager().findFragmentById(R.id.scale_frame); 1199d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentAdapter = ((MainFragmentAdapterProvider)mMainFragment) 1200d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentAdapter(); 1201dc1492d3655550b7a9c861aae1bd538410c7324dDake Gu mMainFragmentAdapter.setFragmentHost(new FragmentHostImpl()); 1202fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 12033103f63e99d47573823957f7aa34308555873221Aurimas Liutikas mIsPageRow = savedInstanceState != null 1204b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu && savedInstanceState.getBoolean(IS_PAGE_ROW, false); 1205fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak 12063103f63e99d47573823957f7aa34308555873221Aurimas Liutikas mSelectedPosition = savedInstanceState != null 12073103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? savedInstanceState.getInt(CURRENT_SELECTED_POSITION, 0) : 0; 12087350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 1209fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (!mIsPageRow) { 1210d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata if (mMainFragment instanceof MainFragmentRowsAdapterProvider) { 1211d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = ((MainFragmentRowsAdapterProvider) mMainFragment) 1212d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata .getMainFragmentRowsAdapter(); 1213d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } else { 1214d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata mMainFragmentRowsAdapter = null; 1215d78de5e10e8426beff2ec22a3e3e0967a6b3d557susnata } 1216fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } else { 1217fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter = null; 1218fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak } 121961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 122061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 122161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setHeadersGone(!mCanShowHeaders); 122261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeaderPresenterSelector != null) { 122361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setPresenterSelector(mHeaderPresenterSelector); 122461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 122561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setAdapter(mAdapter); 12268df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu mHeadersSupportFragment.setOnHeaderViewSelectedListener(mHeaderViewSelectedListener); 122761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setOnHeaderClickedListener(mHeaderClickedListener); 12282f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 122961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View root = inflater.inflate(R.layout.lb_browse_fragment, container, false); 123061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1231684f4a94f6f55b2abc5ed2677dfdfc9501dd6407susnata getProgressBarManager().setRootView((ViewGroup)root); 1232684f4a94f6f55b2abc5ed2677dfdfc9501dd6407susnata 123361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame); 123461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame.setOnChildFocusListener(mOnChildFocusListener); 1235e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener); 123661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1237a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu installTitleView(inflater, mBrowseFrame, savedInstanceState); 1238a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu 1239a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout = (ScaleFrameLayout) root.findViewById(R.id.scale_frame); 1240a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setPivotX(0); 1241a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setPivotY(mContainerListAlignTop); 1242a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1243a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata setupMainFragment(); 1244a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 124561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrandColorSet) { 124661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setBackgroundColor(mBrandColor); 124761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 124861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 12498403619efebe94666c0615c3fc85080a303acf80Dake Gu mSceneWithHeaders = TransitionHelper.createScene(mBrowseFrame, new Runnable() { 125061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 125161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 125261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(true); 125361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 125461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 12558403619efebe94666c0615c3fc85080a303acf80Dake Gu mSceneWithoutHeaders = TransitionHelper.createScene(mBrowseFrame, new Runnable() { 125661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 125761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 125861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(false); 125961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 126061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 12618403619efebe94666c0615c3fc85080a303acf80Dake Gu mSceneAfterEntranceTransition = TransitionHelper.createScene(mBrowseFrame, new Runnable() { 1262c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 1263c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void run() { 1264c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setEntranceTransitionEndState(); 1265c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1266c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu }); 1267d0fc2e48059f718676a531af06a31849f54c1ca9susnata 126861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return root; 126961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 127061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 12711c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata private void setupMainFragment() { 1272fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragmentRowsAdapter != null) { 127335d7a6c31606ed4ca38deda3cacae080a95c95c9susnata if (mAdapter != null) { 127435d7a6c31606ed4ca38deda3cacae080a95c95c9susnata mMainFragmentRowsAdapter.setAdapter(new ListRowDataAdapter(mAdapter)); 127535d7a6c31606ed4ca38deda3cacae080a95c95c9susnata } 12763eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu mMainFragmentRowsAdapter.setOnItemViewSelectedListener( 12773eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu new MainFragmentItemViewSelectedListener(mMainFragmentRowsAdapter)); 1278fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setOnItemViewClickedListener(mOnItemViewClickedListener); 1279a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 12801c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 12811c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 128299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas void createHeadersTransition() { 12832452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu mHeadersTransition = TransitionHelper.loadTransition(getContext(), 12843103f63e99d47573823957f7aa34308555873221Aurimas Liutikas mShowingHeaders 12853103f63e99d47573823957f7aa34308555873221Aurimas Liutikas ? R.transition.lb_browse_headers_in : R.transition.lb_browse_headers_out); 128661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 12878403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.addTransitionListener(mHeadersTransition, new TransitionListener() { 128861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 128961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onTransitionStart(Object transition) { 129061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 129161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 129261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onTransitionEnd(Object transition) { 129361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransition = null; 129454bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mMainFragmentAdapter != null) { 129554bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu mMainFragmentAdapter.onTransitionEnd(); 129654bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (!mShowingHeaders && mMainFragment != null) { 129754bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu View mainFragmentView = mMainFragment.getView(); 129854bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mainFragmentView != null && !mainFragmentView.hasFocus()) { 129954bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu mainFragmentView.requestFocus(); 130054bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu } 130161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 130254bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu } 130354bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mHeadersSupportFragment != null) { 130454bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu mHeadersSupportFragment.onTransitionEnd(); 130554bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (mShowingHeaders) { 130654bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu VerticalGridView headerGridView = mHeadersSupportFragment.getVerticalGridView(); 130754bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu if (headerGridView != null && !headerGridView.hasFocus()) { 130854bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu headerGridView.requestFocus(); 130954bab13ae9de4dd00002792bebf9531ede3c12e2Dake Gu } 131061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1311d0fc2e48059f718676a531af06a31849f54c1ca9susnata } 13126fd4441435b14669deced90a05097dd5fe459acesusnata 13137350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata // Animate TitleView once header animation is complete. 13148ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu updateTitleViewVisibility(); 1315d0fc2e48059f718676a531af06a31849f54c1ca9susnata 131661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrowseTransitionListener != null) { 131761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener.onHeadersTransitionStop(mShowingHeaders); 131861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 131961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 132061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 132161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 132261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 13238ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu void updateTitleViewVisibility() { 13248ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (!mShowingHeaders) { 13258ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean showTitleView; 13268ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mIsPageRow && mMainFragmentAdapter != null) { 13278ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // page fragment case: 13288ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitleView = mMainFragmentAdapter.mFragmentHost.mShowTitleView; 13298ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 13308ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // regular row view case: 13318ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitleView = isFirstRowWithContent(mSelectedPosition); 13328ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13338ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (showTitleView) { 1334a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu showTitle(TitleViewAdapter.FULL_VIEW_VISIBLE); 13358ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 13368ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitle(false); 13378ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13388ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 13398ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu // when HeaderFragment is showing, showBranding and showSearch are slightly different 13408ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean showBranding; 13418ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean showSearch; 13428ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mIsPageRow && mMainFragmentAdapter != null) { 13438ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showBranding = mMainFragmentAdapter.mFragmentHost.mShowTitleView; 13448ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 13458ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showBranding = isFirstRowWithContent(mSelectedPosition); 13468ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13478ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showSearch = isFirstRowWithContentOrPageRow(mSelectedPosition); 13488ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu int flags = 0; 1349a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu if (showBranding) flags |= TitleViewAdapter.BRANDING_VIEW_VISIBLE; 1350a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu if (showSearch) flags |= TitleViewAdapter.SEARCH_VIEW_VISIBLE; 13518ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (flags != 0) { 13528ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitle(flags); 13538ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } else { 13548ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu showTitle(false); 13558ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13568ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13578ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13588ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 13598ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean isFirstRowWithContentOrPageRow(int rowPosition) { 13608ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAdapter == null || mAdapter.size() == 0) { 13618ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 13628ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13638ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu for (int i = 0; i < mAdapter.size(); i++) { 13648ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Row row = (Row) mAdapter.get(i); 13658ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (row.isRenderedAsRowView() || row instanceof PageRow) { 13668ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return rowPosition == i; 13678ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13688ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13698ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 13708ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13718ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 13728ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu boolean isFirstRowWithContent(int rowPosition) { 13738ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAdapter == null || mAdapter.size() == 0) { 13748ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 13758ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13768ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu for (int i = 0; i < mAdapter.size(); i++) { 13778ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu final Row row = (Row) mAdapter.get(i); 13788ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (row.isRenderedAsRowView()) { 13798ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return rowPosition == i; 13808ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13818ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13828ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu return true; 13838ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 13848ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 138561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 138661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the {@link PresenterSelector} used to render the row headers. 138761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 138861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headerPresenterSelector The PresenterSelector that will determine 138961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the Presenter for each row header. 139061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 139161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setHeaderPresenterSelector(PresenterSelector headerPresenterSelector) { 139261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeaderPresenterSelector = headerPresenterSelector; 139361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 139461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setPresenterSelector(mHeaderPresenterSelector); 139561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 139661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 139761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1398c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void setHeadersOnScreen(boolean onScreen) { 1399c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu MarginLayoutParams lp; 1400c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu View containerList; 140161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList = mHeadersSupportFragment.getView(); 140261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu lp = (MarginLayoutParams) containerList.getLayoutParams(); 14038e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing lp.setMarginStart(onScreen ? 0 : -mContainerListMarginStart); 140461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList.setLayoutParams(lp); 1405c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 140661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 140799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas void showHeaders(boolean show) { 1408c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (DEBUG) Log.v(TAG, "showHeaders " + show); 1409c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mHeadersSupportFragment.setHeadersEnabled(show); 1410c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(show); 1411a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata expandMainFragment(!show); 1412a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1413a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1414a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private void expandMainFragment(boolean expand) { 1415a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata MarginLayoutParams params = (MarginLayoutParams) mScaleFrameLayout.getLayoutParams(); 1416c1ec7d7eff002329b245a4edb1b87da2f3b5e006Dake Gu params.setMarginStart(!expand ? mContainerListMarginStart : 0); 1417a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setLayoutParams(params); 1418a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mMainFragmentAdapter.setExpand(expand); 1419a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1420a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata setMainFragmentAlignment(); 1421f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata final float scaleFactor = !expand 1422bb0a680c10b84b83833a59634373140f8bd0750csusnata && mMainFragmentScaleEnabled 1423bb0a680c10b84b83833a59634373140f8bd0750csusnata && mMainFragmentAdapter.isScalingEnabled() ? mScaleFactor : 1; 1424a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setLayoutScaleY(scaleFactor); 1425a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mScaleFrameLayout.setChildScale(scaleFactor); 142661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 142761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 142861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private HeadersSupportFragment.OnHeaderClickedListener mHeaderClickedListener = 142961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new HeadersSupportFragment.OnHeaderClickedListener() { 143061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 1431729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu public void onHeaderClicked(RowHeaderPresenter.ViewHolder viewHolder, Row row) { 143261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders || !mShowingHeaders || isInHeadersTransition()) { 143361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 143461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 143561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(false); 14361c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragment.getView().requestFocus(); 143761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 143861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 143961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 14403eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu class MainFragmentItemViewSelectedListener implements OnItemViewSelectedListener { 14413eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu MainFragmentRowsAdapter mMainFragmentRowsAdapter; 14423eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu 14433eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu public MainFragmentItemViewSelectedListener(MainFragmentRowsAdapter fragmentRowsAdapter) { 14443eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu mMainFragmentRowsAdapter = fragmentRowsAdapter; 14453eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu } 14463eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu 144761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 144861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 144961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu RowPresenter.ViewHolder rowViewHolder, Row row) { 14503eb709dbe85f06b69cf1b683a2c1fe7109a85a9aDake Gu int position = mMainFragmentRowsAdapter.getSelectedPosition(); 145161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "row selected position " + position); 145261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu onRowSelected(position); 145361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mExternalOnItemViewSelectedListener != null) { 145461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemViewSelectedListener.onItemSelected(itemViewHolder, item, 145561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu rowViewHolder, row); 145661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 145761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 145861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 145961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 14608df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu private HeadersSupportFragment.OnHeaderViewSelectedListener mHeaderViewSelectedListener = 14618df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu new HeadersSupportFragment.OnHeaderViewSelectedListener() { 146261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 14638df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu public void onHeaderSelected(RowHeaderPresenter.ViewHolder viewHolder, Row row) { 14640d841b3454f896da58deb506ca22730bfd04f34fDake Gu int position = mHeadersSupportFragment.getSelectedPosition(); 146561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "header selected position " + position); 146661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu onRowSelected(position); 146761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 146861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 146961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 147099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas void onRowSelected(int position) { 147161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (position != mSelectedPosition) { 1472aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSetSelectionRunnable.post( 1473aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout position, SetSelectionRunnable.TYPE_INTERNAL_SYNC, true); 147461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 147561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 147661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 147799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas void setSelection(int position, boolean smooth) { 14781c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata if (position == NO_POSITION) { 14791c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata return; 148061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14811c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 1482e5bf7f32e6f2957e41fc7794b49ed10108171261Dake Gu mSelectedPosition = position; 1483e5bf7f32e6f2957e41fc7794b49ed10108171261Dake Gu if (mHeadersSupportFragment == null || mMainFragmentAdapter == null) { 1484e5bf7f32e6f2957e41fc7794b49ed10108171261Dake Gu // onDestroyView() called 1485e5bf7f32e6f2957e41fc7794b49ed10108171261Dake Gu return; 1486e5bf7f32e6f2957e41fc7794b49ed10108171261Dake Gu } 14871c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mHeadersSupportFragment.setSelectedPosition(position, smooth); 1488bb0a680c10b84b83833a59634373140f8bd0750csusnata replaceMainFragment(position); 1489bb0a680c10b84b83833a59634373140f8bd0750csusnata 1490bb0a680c10b84b83833a59634373140f8bd0750csusnata if (mMainFragmentRowsAdapter != null) { 1491bb0a680c10b84b83833a59634373140f8bd0750csusnata mMainFragmentRowsAdapter.setSelectedPosition(position, smooth); 1492bb0a680c10b84b83833a59634373140f8bd0750csusnata } 14937350fc450e5850b7a3dddff6d63fb87bd24886ddsusnata 14948ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu updateTitleViewVisibility(); 1495bb0a680c10b84b83833a59634373140f8bd0750csusnata } 14963faa5780307cf10ff0e4a1d89a9ba099cdad2e15susnata 1497bb0a680c10b84b83833a59634373140f8bd0750csusnata private void replaceMainFragment(int position) { 1498a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata if (createMainFragment(mAdapter, position)) { 1499041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu swapToMainFragment(); 1500a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata expandMainFragment(!(mCanShowHeaders && mShowingHeaders)); 15011c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata setupMainFragment(); 15021c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 150361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 150461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1505041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu private void swapToMainFragment() { 1506041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu final VerticalGridView gridView = mHeadersSupportFragment.getVerticalGridView(); 15073f19c1616ed2749a70ecc764dccb467ec96aa1f4Dake Gu if (isShowingHeaders() && gridView != null 15083f19c1616ed2749a70ecc764dccb467ec96aa1f4Dake Gu && gridView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { 1509041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu // if user is scrolling HeadersSupportFragment, swap to empty fragment and wait scrolling 1510041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu // finishes. 1511041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu getChildFragmentManager().beginTransaction() 1512041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu .replace(R.id.scale_frame, new Fragment()).commit(); 1513041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu gridView.addOnScrollListener(new RecyclerView.OnScrollListener() { 1514694edde99dc3782374977dab6d9aa34a16c13337Dake Gu @SuppressWarnings("ReferenceEquality") 1515041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu @Override 1516041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 1517041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu if (newState == RecyclerView.SCROLL_STATE_IDLE) { 1518041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu gridView.removeOnScrollListener(this); 1519041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu FragmentManager fm = getChildFragmentManager(); 1520041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu Fragment currentFragment = fm.findFragmentById(R.id.scale_frame); 1521041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu if (currentFragment != mMainFragment) { 1522041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu fm.beginTransaction().replace(R.id.scale_frame, mMainFragment).commit(); 1523041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 1524041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 1525041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 1526041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu }); 1527041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } else { 1528041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu // Otherwise swap immediately 1529041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu getChildFragmentManager().beginTransaction() 1530041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu .replace(R.id.scale_frame, mMainFragment).commit(); 1531041a037dbeb68c17322e62e729ec5ece6c7f5b20Dake Gu } 15321c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata } 15331c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 15343f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu /** 15353f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu * Sets the selected row position with smooth animation. 15363f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu */ 15373f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu public void setSelectedPosition(int position) { 15383f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu setSelectedPosition(position, true); 15393f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu } 15403f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu 15413f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu /** 15420d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * Gets position of currently selected row. 15430d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @return Position of currently selected row. 15440d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 15450d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public int getSelectedPosition() { 15460d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu return mSelectedPosition; 15470d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 15480d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 15490d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 1550181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu * @return selected row ViewHolder inside fragment created by {@link MainFragmentRowsAdapter}. 1551181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu */ 1552181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu public RowPresenter.ViewHolder getSelectedRowViewHolder() { 1553181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu if (mMainFragmentRowsAdapter != null) { 1554181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu int rowPos = mMainFragmentRowsAdapter.getSelectedPosition(); 1555181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu return mMainFragmentRowsAdapter.findRowViewHolderByPosition(rowPos); 1556181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu } 1557181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu return null; 1558181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu } 1559181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu 1560181c8847d5a1169e26755ed690131333b7fff7e9Dake Gu /** 15613f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu * Sets the selected row position. 15623f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu */ 15633f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu public void setSelectedPosition(int position, boolean smooth) { 1564aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout mSetSelectionRunnable.post( 1565aca6f4e4d28935fdc8f8d2a74cd41dc88c8b9e80Craig Stout position, SetSelectionRunnable.TYPE_USER_REQUEST, smooth); 15663f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu } 15673f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu 15680d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu /** 15690d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * Selects a Row and perform an optional task on the Row. For example 15700d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * <code>setSelectedPosition(10, true, new ListRowPresenterSelectItemViewHolderTask(5))</code> 15710d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * scrolls to 11th row and selects 6th item on that row. The method will be ignored if 15720d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * RowsSupportFragment has not been created (i.e. before {@link #onCreateView(LayoutInflater, 15730d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * ViewGroup, Bundle)}). 15740d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * 15750d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @param rowPosition Which row to select. 15760d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @param smooth True to scroll to the row, false for no animation. 15770d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * @param rowHolderTask Optional task to perform on the Row. When the task is not null, headers 15780d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu * fragment will be collapsed. 15790d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu */ 15800d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu public void setSelectedPosition(int rowPosition, boolean smooth, 1581cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu final Presenter.ViewHolderTask rowHolderTask) { 1582fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragmentAdapterRegistry == null) { 15830d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu return; 15840d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 15850d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu if (rowHolderTask != null) { 15860d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu startHeadersTransition(false); 15870d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 1588fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak if (mMainFragmentRowsAdapter != null) { 1589fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mMainFragmentRowsAdapter.setSelectedPosition(rowPosition, smooth, rowHolderTask); 1590a9cab85f79e3993c3d7c4f5e0246f8492bcc2a48susnata } 15910d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu } 15920d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu 159361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 159461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onStart() { 159561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onStart(); 15962f5ebf3f6f7bb6a24856f389e369b247118ba119susnata mHeadersSupportFragment.setAlignment(mContainerListAlignTop); 1597a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata setMainFragmentAlignment(); 159861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1599b21aa0b72a6800f694a3b2ba513a187deb28f252Dake Gu if (mCanShowHeaders && mShowingHeaders && mHeadersSupportFragment != null 1600b21aa0b72a6800f694a3b2ba513a187deb28f252Dake Gu && mHeadersSupportFragment.getView() != null) { 160161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.getView().requestFocus(); 1602b21aa0b72a6800f694a3b2ba513a187deb28f252Dake Gu } else if ((!mCanShowHeaders || !mShowingHeaders) && mMainFragment != null 1603b21aa0b72a6800f694a3b2ba513a187deb28f252Dake Gu && mMainFragment.getView() != null) { 16041c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragment.getView().requestFocus(); 160561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16061c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 160761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders) { 160861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(mShowingHeaders); 160961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16101c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata 161189097f67f988ebba714a95e10369665280db0c27Dake Gu mStateMachine.fireEvent(EVT_HEADER_VIEW_CREATED); 161261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 161361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1614a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private void onExpandTransitionStart(boolean expand, final Runnable callback) { 1615a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata if (expand) { 1616a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata callback.run(); 1617a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata return; 1618a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1619a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata // Run a "pre" layout when we go non-expand, in order to get the initial 1620a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata // positions of added rows. 1621fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak new ExpandPreLayout(callback, mMainFragmentAdapter, getView()).execute(); 1622a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1623a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1624a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private void setMainFragmentAlignment() { 1625a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata int alignOffset = mContainerListAlignTop; 1626f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata if (mMainFragmentScaleEnabled 1627f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata && mMainFragmentAdapter.isScalingEnabled() 1628f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata && mShowingHeaders) { 1629f7a4099b29d7739616dd9d7e466b48dfda4b32f2susnata alignOffset = (int) (alignOffset / mScaleFactor + 0.5f); 1630a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1631a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mMainFragmentAdapter.setAlignment(alignOffset); 1632a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1633a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 163461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 1635a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Enables/disables headers transition on back key support. This is enabled by 163661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * default. The BrowseSupportFragment will add a back stack entry when headers are 163761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * showing. Running a headers transition when the back key is pressed only 163861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * works when the headers state is {@link #HEADERS_ENABLED} or 163961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #HEADERS_HIDDEN}. 164061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 164161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * NOTE: If an Activity has its own onBackPressed() handling, you must 164261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * disable this feature. You may use {@link #startHeadersTransition(boolean)} 164361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * and {@link BrowseTransitionListener} in your own back stack handling. 164461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 164561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public final void setHeadersTransitionOnBackEnabled(boolean headersBackStackEnabled) { 164661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersBackStackEnabled = headersBackStackEnabled; 164761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 164861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 164961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 165061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if headers transition on back key support is enabled. 165161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 165261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public final boolean isHeadersTransitionOnBackEnabled() { 165361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersBackStackEnabled; 165461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 165561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 165661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void readArguments(Bundle args) { 165761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args == null) { 165861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 165961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 166061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args.containsKey(ARG_TITLE)) { 166161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setTitle(args.getString(ARG_TITLE)); 166261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 166361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args.containsKey(ARG_HEADERS_STATE)) { 166461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setHeadersState(args.getInt(ARG_HEADERS_STATE)); 166561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 166661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 166761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 166861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 166961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the state for the headers column in the browse fragment. Must be one 167061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of {@link #HEADERS_ENABLED}, {@link #HEADERS_HIDDEN}, or 167161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #HEADERS_DISABLED}. 167261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 167361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headersState The state of the headers for the browse fragment. 167461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 167561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setHeadersState(int headersState) { 167661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headersState < HEADERS_ENABLED || headersState > HEADERS_DISABLED) { 167761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalArgumentException("Invalid headers state: " + headersState); 167861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 167961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "setHeadersState " + headersState); 168061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 168161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headersState != mHeadersState) { 168261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersState = headersState; 168361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu switch (headersState) { 168461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_ENABLED: 168561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = true; 168661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = true; 168761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 168861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_HIDDEN: 168961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = true; 169061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = false; 169161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 169261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_DISABLED: 169361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = false; 169461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = false; 169561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 169661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu default: 169761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Log.w(TAG, "Unknown headers state: " + headersState); 169861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 169961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 170061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 170161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setHeadersGone(!mCanShowHeaders); 170261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 170361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 170461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 170561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 170661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 170761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the state of the headers column in the browse fragment. 170861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 170961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getHeadersState() { 171061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersState; 171161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1712c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 17133f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 17143f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected Object createEntranceTransition() { 17152452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu return TransitionHelper.loadTransition(getContext(), 17163f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu R.transition.lb_browse_entrance_transition); 1717c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1718c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 17193f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 17203f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected void runEntranceTransition(Object entranceTransition) { 17218403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.runTransition(mSceneAfterEntranceTransition, entranceTransition); 1722c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1723c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 17243f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 1725902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu protected void onEntranceTransitionPrepare() { 1726902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu mHeadersSupportFragment.onTransitionPrepare(); 1727a5a85434f936023043f074fb86eaa6d48f7f6411Dake Gu mMainFragmentAdapter.setEntranceTransitionState(false); 17281c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionPrepare(); 1729902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu } 1730902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu 1731902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu @Override 17323f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected void onEntranceTransitionStart() { 17333f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu mHeadersSupportFragment.onTransitionStart(); 17341c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.onTransitionStart(); 1735c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1736c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 17373f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu @Override 17383f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu protected void onEntranceTransitionEnd() { 1739b082c7277cff057bdff19e411e345c3d6fea2e12susnata if (mMainFragmentAdapter != null) { 1740b082c7277cff057bdff19e411e345c3d6fea2e12susnata mMainFragmentAdapter.onTransitionEnd(); 1741b082c7277cff057bdff19e411e345c3d6fea2e12susnata } 1742b082c7277cff057bdff19e411e345c3d6fea2e12susnata 1743b082c7277cff057bdff19e411e345c3d6fea2e12susnata if (mHeadersSupportFragment != null) { 1744b082c7277cff057bdff19e411e345c3d6fea2e12susnata mHeadersSupportFragment.onTransitionEnd(); 1745b082c7277cff057bdff19e411e345c3d6fea2e12susnata } 1746c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1747c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 17483f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu void setSearchOrbViewOnScreen(boolean onScreen) { 1749a373804d10f93a9488adc35cf6ce44dce09b3778Dake Gu View searchOrbView = getTitleViewAdapter().getSearchAffordanceView(); 1750b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata if (searchOrbView != null) { 1751b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata MarginLayoutParams lp = (MarginLayoutParams) searchOrbView.getLayoutParams(); 1752b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata lp.setMarginStart(onScreen ? 0 : -mContainerListMarginStart); 1753b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata searchOrbView.setLayoutParams(lp); 1754b92376f5be24ddee5c6cd7c23b7c7e8e5c2cda68susnata } 1755c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1756c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1757c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void setEntranceTransitionStartState() { 1758c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(false); 1759c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setSearchOrbViewOnScreen(false); 176089097f67f988ebba714a95e10369665280db0c27Dake Gu // NOTE that mMainFragmentAdapter.setEntranceTransitionState(false) will be called 176189097f67f988ebba714a95e10369665280db0c27Dake Gu // in onEntranceTransitionPrepare() because mMainFragmentAdapter is still the dummy 176289097f67f988ebba714a95e10369665280db0c27Dake Gu // one when setEntranceTransitionStartState() is called. 1763c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1764c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1765c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void setEntranceTransitionEndState() { 1766c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(mShowingHeaders); 1767c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setSearchOrbViewOnScreen(true); 17681c3ce0fa10ec24e4edd5e5ea909b4d4357534b53susnata mMainFragmentAdapter.setEntranceTransitionState(true); 1769c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1770a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1771dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu private class ExpandPreLayout implements ViewTreeObserver.OnPreDrawListener { 1772a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1773a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private final View mView; 1774a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private final Runnable mCallback; 1775a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata private int mState; 1776fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak private MainFragmentAdapter mainFragmentAdapter; 1777a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1778a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata final static int STATE_INIT = 0; 1779a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata final static int STATE_FIRST_DRAW = 1; 1780a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata final static int STATE_SECOND_DRAW = 2; 1781a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1782fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak ExpandPreLayout(Runnable callback, MainFragmentAdapter adapter, View view) { 1783fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak mView = view; 1784a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mCallback = callback; 1785a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mainFragmentAdapter = adapter; 1786a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1787a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1788a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata void execute() { 1789a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mView.getViewTreeObserver().addOnPreDrawListener(this); 1790a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mainFragmentAdapter.setExpand(false); 17912dda16536f0cc543f52abf53b18d6c1327031142Dake Gu // always trigger onPreDraw even adapter setExpand() does nothing. 17922dda16536f0cc543f52abf53b18d6c1327031142Dake Gu mView.invalidate(); 1793a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mState = STATE_INIT; 1794a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1795a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata 1796a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata @Override 1797a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata public boolean onPreDraw() { 17982452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu if (getView() == null || getContext() == null) { 1799dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu mView.getViewTreeObserver().removeOnPreDrawListener(this); 1800dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu return true; 1801dee82957d1100c2b65e6850769abd3ff00f1ec95Dake Gu } 1802a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata if (mState == STATE_INIT) { 1803a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mainFragmentAdapter.setExpand(true); 18042dda16536f0cc543f52abf53b18d6c1327031142Dake Gu // always trigger onPreDraw even adapter setExpand() does nothing. 18052dda16536f0cc543f52abf53b18d6c1327031142Dake Gu mView.invalidate(); 1806a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mState = STATE_FIRST_DRAW; 1807a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } else if (mState == STATE_FIRST_DRAW) { 1808a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mCallback.run(); 1809a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mView.getViewTreeObserver().removeOnPreDrawListener(this); 1810a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata mState = STATE_SECOND_DRAW; 1811a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1812a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata return false; 1813a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 1814a9f6062bd2dd02b3de253b57c69302893bf1f2e3susnata } 181561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu} 1816