BrowseSupportFragment.java revision 3595aa0cbdaa8e754365ca94a0b9eb8fc52b9796
16193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu/* This file is auto-generated from BrowseFragment.java. DO NOT MODIFY. */ 26193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu 361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/* 461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Copyright (C) 2014 The Android Open Source Project 561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * in compliance with the License. You may obtain a copy of the License at 861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * http://www.apache.org/licenses/LICENSE-2.0 1061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 1161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License 1261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * or implied. See the License for the specific language governing permissions and limitations under 1461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the License. 1561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 1661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gupackage android.support.v17.leanback.app; 1761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.R; 1961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.transition.TransitionHelper; 2061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.transition.TransitionListener; 2161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.BrowseFrameLayout; 2261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.HorizontalGridView; 2361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.ItemBridgeAdapter; 2461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemViewClickedListener; 2561905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemViewSelectedListener; 2661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.Presenter; 2761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.PresenterSelector; 2861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.RowPresenter; 2961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.TitleView; 3061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.VerticalGridView; 3161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.Row; 3261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.ObjectAdapter; 3361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemSelectedListener; 3461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.OnItemClickedListener; 3561905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.SearchOrbView; 3661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.util.Log; 3761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v4.app.FragmentActivity; 3861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v4.app.Fragment; 3961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v4.app.FragmentManager; 4061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v4.app.FragmentManager.BackStackEntry; 4161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.content.Context; 4261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.content.res.TypedArray; 4361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.os.Bundle; 4461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.LayoutInflater; 4561905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.View; 4661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.View.OnClickListener; 4761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup; 4861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup.MarginLayoutParams; 49c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Guimport android.view.ViewTreeObserver; 5061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.graphics.Color; 5161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.graphics.Rect; 5261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.graphics.drawable.Drawable; 5361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 5461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport static android.support.v7.widget.RecyclerView.NO_POSITION; 5561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 5661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/** 5761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A fragment for creating Leanback browse screens. It is composed of a 5861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * RowsSupportFragment and a HeadersSupportFragment. 5961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 6061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A BrowseSupportFragment renders the elements of its {@link ObjectAdapter} as a set 6161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of rows in a vertical list. The elements in this adapter must be subclasses 6261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of {@link Row}. 6361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 6461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * The HeadersSupportFragment can be set to be either shown or hidden by default, or 6561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * may be disabled entirely. See {@link #setHeadersState} for details. 6661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 6761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * By default the BrowseSupportFragment includes support for returning to the headers 6861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * when the user presses Back. For Activities that customize {@link 696193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu * android.support.v4.app.FragmentActivity#onBackPressed()}, you must disable this default Back key support by 7061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * calling {@link #setHeadersTransitionOnBackEnabled(boolean)} with false and 7161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * use {@link BrowseSupportFragment.BrowseTransitionListener} and 7261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #startHeadersTransition(boolean)}. 7361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 7461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gupublic class BrowseSupportFragment extends Fragment { 7561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 7661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for saving header show/hide status when backstack is used: 7761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String HEADER_STACK_INDEX = "headerStackIndex"; 7861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for saving header show/hide status when backstack is not used: 7961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String HEADER_SHOW = "headerShow"; 8061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // BUNDLE attribute for title is showing 8161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static final String TITLE_SHOW = "titleShow"; 8261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 8361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final class BackStackListener implements FragmentManager.OnBackStackChangedListener { 8461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mLastEntryCount; 8561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mIndexOfHeadersBackStack; 8661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 8761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackListener() { 8861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLastEntryCount = getFragmentManager().getBackStackEntryCount(); 8961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = -1; 9061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 9261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void load(Bundle savedInstanceState) { 9361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (savedInstanceState != null) { 9461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = savedInstanceState.getInt(HEADER_STACK_INDEX, -1); 9561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = mIndexOfHeadersBackStack == -1; 9661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 9761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingHeaders) { 9861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().beginTransaction() 9961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 10061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 10461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void save(Bundle outState) { 10561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putInt(HEADER_STACK_INDEX, mIndexOfHeadersBackStack); 10661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 10761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 10861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 10961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 11061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onBackStackChanged() { 11161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getFragmentManager() == null) { 11261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Log.w(TAG, "getFragmentManager() is null, stack:", new Exception()); 11361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 11461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 11561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int count = getFragmentManager().getBackStackEntryCount(); 11661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if backstack is growing and last pushed entry is "headers" backstack, 11761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // remember the index of the entry. 11861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (count > mLastEntryCount) { 11961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackEntry entry = getFragmentManager().getBackStackEntryAt(count - 1); 12061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mWithHeadersBackStackName.equals(entry.getName())) { 12161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = count - 1; 12261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 12361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (count < mLastEntryCount) { 12461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if popped "headers" backstack, initiate the show header transition if needed 12561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mIndexOfHeadersBackStack >= count) { 12661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mIndexOfHeadersBackStack = -1; 12761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingHeaders) { 12861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(true); 12961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 13061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 13161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 13261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLastEntryCount = count; 13361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 13461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 13561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 13661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 13761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Listener for transitions between browse headers and rows. 13861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 13961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static class BrowseTransitionListener { 14061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 14161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Callback when headers transition starts. 14261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 14361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the transition will result in headers 14461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * being shown, false otherwise. 14561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 14661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeadersTransitionStart(boolean withHeaders) { 14761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 14961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Callback when headers transition stops. 15061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 15161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the transition will result in headers 15261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * being shown, false otherwise. 15361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 15461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeadersTransitionStop(boolean withHeaders) { 15561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 15661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 15761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 15861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String TAG = "BrowseSupportFragment"; 15961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 16061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String LB_HEADERS_BACKSTACK = "lbHeadersBackStack_"; 16161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 16261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static boolean DEBUG = false; 16361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 16461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is enabled and shown by default. */ 16561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_ENABLED = 1; 16661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 16761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is enabled and hidden by default. */ 16861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_HIDDEN = 2; 16961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 17061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** The headers fragment is disabled and will never be shown. */ 17161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int HEADERS_DISABLED = 3; 17261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 17361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final float SLIDE_DISTANCE_FACTOR = 2; 17461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 17561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private RowsSupportFragment mRowsSupportFragment; 17661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private HeadersSupportFragment mHeadersSupportFragment; 17761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 17861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ObjectAdapter mAdapter; 17961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 18061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private String mTitle; 18161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Drawable mBadgeDrawable; 18261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mHeadersState = HEADERS_ENABLED; 18361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBrandColor = Color.TRANSPARENT; 18461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mBrandColorSet; 18561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 18661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private BrowseFrameLayout mBrowseFrame; 18761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private TitleView mTitleView; 18861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mShowingTitle = true; 18961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mHeadersBackStackEnabled = true; 19061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private String mWithHeadersBackStackName; 19161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mShowingHeaders = true; 19261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mCanShowHeaders = true; 19361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mContainerListMarginLeft; 19461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mContainerListAlignTop; 19561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mRowScaleEnabled = true; 19661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private SearchOrbView.Colors mSearchAffordanceColors; 19761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mSearchAffordanceColorSet; 19861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemSelectedListener mExternalOnItemSelectedListener; 19961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnClickListener mExternalOnSearchClickedListener; 20061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemClickedListener mOnItemClickedListener; 20161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemViewSelectedListener mExternalOnItemViewSelectedListener; 20261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemViewClickedListener mOnItemViewClickedListener; 20361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mSelectedPosition = -1; 20461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 20561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private PresenterSelector mHeaderPresenterSelector; 20661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 20761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // transition related: 20861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance(); 20961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mReparentHeaderId = View.generateViewId(); 21061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mSceneWithTitle; 21161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mSceneWithoutTitle; 21261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mSceneWithHeaders; 21361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mSceneWithoutHeaders; 214c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private Object mSceneAfterEntranceTransition; 21561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mTitleUpTransition; 21661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mTitleDownTransition; 21761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private Object mHeadersTransition; 218c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private Object mEntranceTransition; 21961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mHeadersTransitionStartDelay; 22061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mHeadersTransitionDuration; 22161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private BackStackListener mBackStackChangedListener; 22261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private BrowseTransitionListener mBrowseTransitionListener; 22361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 224c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private boolean mEntranceTransitionEnabled = false; 225c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private boolean mStartEntranceTransitionPending = false; 226c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 22761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_TITLE = BrowseSupportFragment.class.getCanonicalName() + ".title"; 22861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_BADGE_URI = BrowseSupportFragment.class.getCanonicalName() + ".badge"; 22961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String ARG_HEADERS_STATE = 23061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BrowseSupportFragment.class.getCanonicalName() + ".headersState"; 23161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 23261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 23361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Create arguments for a browse fragment. 23461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 23561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param args The Bundle to place arguments into, or null if the method 23661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * should return a new Bundle. 23761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param title The title of the BrowseSupportFragment. 23861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headersState The initial state of the headers of the 23961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * BrowseSupportFragment. Must be one of {@link #HEADERS_ENABLED}, {@link 24061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * #HEADERS_HIDDEN}, or {@link #HEADERS_DISABLED}. 24161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @return A Bundle with the given arguments for creating a BrowseSupportFragment. 24261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 24361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static Bundle createArgs(Bundle args, String title, int headersState) { 24461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args == null) { 24561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args = new Bundle(); 24661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 24761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args.putString(ARG_TITLE, title); 24861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu args.putInt(ARG_HEADERS_STATE, headersState); 24961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return args; 25061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 25161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 25261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 25361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the brand color for the browse fragment. The brand color is used as 25461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the primary color for UI elements in the browse fragment. For example, 25561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the background color of the headers fragment uses the brand color. 25661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 25761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param color The color to use as the brand color of the fragment. 25861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 25961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setBrandColor(int color) { 26061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrandColor = color; 26161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrandColorSet = true; 26261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 26361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 26461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setBackgroundColor(mBrandColor); 26561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 26661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 26761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 26861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 26961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the brand color for the browse fragment. 27061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * The default is transparent. 27161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 27261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getBrandColor() { 27361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mBrandColor; 27461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 27561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 27661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 27761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the adapter containing the rows for the fragment. 27861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 27961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>The items referenced by the adapter must be be derived from 28061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link Row}. These rows will be used by the rows fragment and the headers 28161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * fragment (if not disabled) to render the browse rows. 28261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 28361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param adapter An ObjectAdapter for the browse rows. All items must 28461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * derive from {@link Row}. 28561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 28661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setAdapter(ObjectAdapter adapter) { 28761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mAdapter = adapter; 28861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRowsSupportFragment != null) { 28961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setAdapter(adapter); 29061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setAdapter(adapter); 29161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 29261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 29361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 29461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 29561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the adapter containing the rows for the fragment. 29661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 29761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public ObjectAdapter getAdapter() { 29861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mAdapter; 29961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 30061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 30161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 30261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item selection listener. This listener will be called when an 30361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * item or row is selected by a user. 30461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 30561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param listener The listener to call when an item or row is selected. 30661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @deprecated Use {@link #setOnItemViewSelectedListener(OnItemViewSelectedListener)} 30761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 30861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemSelectedListener(OnItemSelectedListener listener) { 30961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemSelectedListener = listener; 31061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 31161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 31261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 31361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item selection listener. 31461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 31561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 31661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemViewSelectedListener = listener; 31761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 31861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 31961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 32061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns an item selection listener. 32161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 32261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemViewSelectedListener getOnItemViewSelectedListener() { 32361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mExternalOnItemViewSelectedListener; 32461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 32561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 32661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 32761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item clicked listener on the fragment. 32861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 32961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>OnItemClickedListener will override {@link View.OnClickListener} that 33061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * an item presenter may set during 33161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link Presenter#onCreateViewHolder(ViewGroup)}. So in general, you 33261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * should choose to use an {@link OnItemClickedListener} or a 33361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link View.OnClickListener} on your item views, but not both. 33461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 33561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param listener The listener to call when an item is clicked. 33661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @deprecated Use {@link #setOnItemViewClickedListener(OnItemViewClickedListener)} 33761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 33861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemClickedListener(OnItemClickedListener listener) { 33961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOnItemClickedListener = listener; 34061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRowsSupportFragment != null) { 34161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setOnItemClickedListener(listener); 34261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 34361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 34461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 34561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 34661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the item clicked listener. 34761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @deprecated Use {@link #getOnItemViewClickedListener()} 34861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 34961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemClickedListener getOnItemClickedListener() { 35061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mOnItemClickedListener; 35161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 35261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 35361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 35461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets an item clicked listener on the fragment. 35561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * OnItemViewClickedListener will override {@link View.OnClickListener} that 35661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}. 35761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * So in general, developer should choose one of the listeners but not both. 35861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 35961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 36061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOnItemViewClickedListener = listener; 36161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRowsSupportFragment != null) { 36261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setOnItemViewClickedListener(listener); 36361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 36461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 36561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 36661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 36761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the item Clicked listener. 36861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 36961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnItemViewClickedListener getOnItemViewClickedListener() { 37061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mOnItemViewClickedListener; 37161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 37261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 37361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 37461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets a click listener for the search affordance. 37561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 37661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>The presence of a listener will change the visibility of the search 37761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * affordance in the fragment title. When set to non-null, the title will 37861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * contain an element that a user may click to begin a search. 37961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 38061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>The listener's {@link View.OnClickListener#onClick onClick} method 38161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * will be invoked when the user clicks on the search element. 38261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 38361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param listener The listener to call when the search element is clicked. 38461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 38561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setOnSearchClickedListener(View.OnClickListener listener) { 38661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnSearchClickedListener = listener; 38761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mTitleView != null) { 38861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setOnSearchClickedListener(listener); 38961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 39061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 39161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 39261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 39361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the {@link SearchOrbView.Colors} used to draw the search affordance. 39461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 39561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setSearchAffordanceColors(SearchOrbView.Colors colors) { 39661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSearchAffordanceColors = colors; 39761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSearchAffordanceColorSet = true; 39861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mTitleView != null) { 39961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setSearchAffordanceColors(mSearchAffordanceColors); 40061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 40161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 40261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 40361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 40461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the {@link SearchOrbView.Colors} used to draw the search affordance. 40561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 40661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public SearchOrbView.Colors getSearchAffordanceColors() { 40761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mSearchAffordanceColorSet) { 40861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mSearchAffordanceColors; 40961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 41061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mTitleView == null) { 41161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalStateException("Fragment views not yet created"); 41261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 41361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mTitleView.getSearchAffordanceColors(); 41461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 41561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 41661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 41761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the color used to draw the search affordance. 41861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A default brighter color will be set by the framework. 41961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 42061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param color The color to use for the search affordance. 42161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 42261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setSearchAffordanceColor(int color) { 42361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setSearchAffordanceColors(new SearchOrbView.Colors(color)); 42461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 42561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 42661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 42761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the color used to draw the search affordance. 42861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 42961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getSearchAffordanceColor() { 43061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return getSearchAffordanceColors().color; 43161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 43261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 43361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 43461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Start a headers transition. 43561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 43661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p>This method will begin a transition to either show or hide the 43761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * headers, depending on the value of withHeaders. If headers are disabled 43861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * for this browse fragment, this method will throw an exception. 43961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 44061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param withHeaders True if the headers should transition to being shown, 44161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * false if the transition should result in headers being hidden. 44261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 44361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void startHeadersTransition(boolean withHeaders) { 44461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders) { 44561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalStateException("Cannot start headers transition"); 44661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 44761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (isInHeadersTransition() || mShowingHeaders == withHeaders) { 44861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 44961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 45061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(withHeaders); 45161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 45261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 45361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 45461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if the headers transition is currently running. 45561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 45661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isInHeadersTransition() { 45761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersTransition != null; 45861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 45961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 46061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 46161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if headers are shown. 46261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 46361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isShowingHeaders() { 46461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mShowingHeaders; 46561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 46661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 46761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 46861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Set a listener for browse fragment transitions. 46961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 47061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param listener The listener to call when a browse headers transition 47161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * begins or ends. 47261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 47361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setBrowseTransitionListener(BrowseTransitionListener listener) { 47461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener = listener; 47561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 47661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 47761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 47861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Enables scaling of rows when headers are present. 47961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * By default enabled to increase density. 48061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 48161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param enable true to enable row scaling 48261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 48361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void enableRowScaling(boolean enable) { 48461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowScaleEnabled = enable; 48561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRowsSupportFragment != null) { 48661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.enableRowScaling(mRowScaleEnabled); 48761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 48861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 48961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 49061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void startHeadersTransitionInternal(final boolean withHeaders) { 49161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getFragmentManager().isDestroyed()) { 49261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 49361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 49461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = withHeaders; 49561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.onExpandTransitionStart(!withHeaders, new Runnable() { 49661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 49761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 49861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.onTransitionStart(); 49961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu createHeadersTransition(); 50061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrowseTransitionListener != null) { 50161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener.onHeadersTransitionStart(withHeaders); 50261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 50361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.runTransition(withHeaders ? mSceneWithHeaders : mSceneWithoutHeaders, 50461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransition); 50561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersBackStackEnabled) { 50661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!withHeaders) { 50761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().beginTransaction() 50861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .addToBackStack(mWithHeadersBackStackName).commit(); 50961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 51061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int index = mBackStackChangedListener.mIndexOfHeadersBackStack; 51161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (index >= 0) { 51261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu BackStackEntry entry = getFragmentManager().getBackStackEntryAt(index); 51361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().popBackStackImmediate(entry.getId(), 51461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu FragmentManager.POP_BACK_STACK_INCLUSIVE); 51561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 51661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 51761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 51861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 51961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 52061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 52161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 52261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean isVerticalScrolling() { 52361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // don't run transition 52461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersSupportFragment.getVerticalGridView().getScrollState() 52561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu != HorizontalGridView.SCROLL_STATE_IDLE 52661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu || mRowsSupportFragment.getVerticalGridView().getScrollState() 52761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu != HorizontalGridView.SCROLL_STATE_IDLE; 52861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 52961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 53061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener = 53161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new BrowseFrameLayout.OnFocusSearchListener() { 53261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 53361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onFocusSearch(View focused, int direction) { 53461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // If headers fragment is disabled, just return null. 53561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders) return null; 53661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 53761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final View searchOrbView = mTitleView.getSearchAffordanceView(); 53861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // if headers is running transition, focus stays 53961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (isInHeadersTransition()) return focused; 54061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction); 54161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (direction == View.FOCUS_LEFT) { 54261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (isVerticalScrolling() || mShowingHeaders) { 54361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return focused; 54461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 54561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersSupportFragment.getVerticalGridView(); 54661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (direction == View.FOCUS_RIGHT) { 54761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (isVerticalScrolling() || !mShowingHeaders) { 54861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return focused; 54961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 55061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mRowsSupportFragment.getVerticalGridView(); 55161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (focused == searchOrbView && direction == View.FOCUS_DOWN) { 55261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mShowingHeaders ? mHeadersSupportFragment.getVerticalGridView() : 55361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.getVerticalGridView(); 55461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 55561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (focused != searchOrbView && searchOrbView.getVisibility() == View.VISIBLE 55661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu && direction == View.FOCUS_UP) { 55761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return searchOrbView; 55861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 55961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 56061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return null; 56161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 56261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 56361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 56461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 56561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final BrowseFrameLayout.OnChildFocusListener mOnChildFocusListener = 56661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new BrowseFrameLayout.OnChildFocusListener() { 56761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 56861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 56961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 57028fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu if (getChildFragmentManager().isDestroyed()) { 57128fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu return true; 57228fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu } 57361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Make sure not changing focus when requestFocus() is called. 57461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders && mShowingHeaders) { 57561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment.getView().requestFocus(direction, previouslyFocusedRect)) { 57661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return true; 57761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 57861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 57961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRowsSupportFragment.getView().requestFocus(direction, previouslyFocusedRect)) { 58061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return true; 58161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 58261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mTitleView.requestFocus(direction, previouslyFocusedRect); 58361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 58461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 58561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 58661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onRequestChildFocus(View child, View focused) { 58728fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu if (getChildFragmentManager().isDestroyed()) { 58828fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu return; 58928fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu } 59061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders || isInHeadersTransition()) return; 59128fe4119471dcc0ccd752c331d6420fcf363f5a5Dake Gu int childId = child.getId(); 59261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (childId == R.id.browse_container_dock && mShowingHeaders) { 59361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(false); 59461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (childId == R.id.browse_headers_dock && !mShowingHeaders) { 59561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(true); 59661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 59761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 59861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 59961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 60161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onSaveInstanceState(Bundle outState) { 60261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBackStackChangedListener != null) { 60361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBackStackChangedListener.save(outState); 60461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 60561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putBoolean(HEADER_SHOW, mShowingHeaders); 60661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 60761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu outState.putBoolean(TITLE_SHOW, mShowingTitle); 60861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 60961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 61061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 61161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onCreate(Bundle savedInstanceState) { 61261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onCreate(savedInstanceState); 61361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu TypedArray ta = getActivity().obtainStyledAttributes(R.styleable.LeanbackTheme); 61461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mContainerListMarginLeft = (int) ta.getDimension( 61561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu R.styleable.LeanbackTheme_browseRowsMarginStart, 0); 61661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mContainerListAlignTop = (int) ta.getDimension( 61761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu R.styleable.LeanbackTheme_browseRowsMarginTop, 0); 61861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ta.recycle(); 61961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 62061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransitionStartDelay = getResources() 62161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .getInteger(R.integer.lb_browse_headers_transition_delay); 62261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransitionDuration = getResources() 62361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .getInteger(R.integer.lb_browse_headers_transition_duration); 62461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 62561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu readArguments(getArguments()); 62661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 62734f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (mCanShowHeaders) { 62834f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (mHeadersBackStackEnabled) { 62934f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mWithHeadersBackStackName = LB_HEADERS_BACKSTACK + this; 63034f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mBackStackChangedListener = new BackStackListener(); 63134f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout getFragmentManager().addOnBackStackChangedListener(mBackStackChangedListener); 63234f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mBackStackChangedListener.load(savedInstanceState); 63334f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } else { 63434f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout if (savedInstanceState != null) { 63534f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout mShowingHeaders = savedInstanceState.getBoolean(HEADER_SHOW); 63634f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 63734f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 63834f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout } 63934f3ee7e818a20939ef49abf5509bcfaea5c3db0Craig Stout 64061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 64161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 64261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 64361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onDestroy() { 64461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBackStackChangedListener != null) { 64561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getFragmentManager().removeOnBackStackChangedListener(mBackStackChangedListener); 64661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 64761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onDestroy(); 64861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 64961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 65061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 65161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onCreateView(LayoutInflater inflater, ViewGroup container, 65261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Bundle savedInstanceState) { 65361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getChildFragmentManager().findFragmentById(R.id.browse_container_dock) == null) { 65461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment = new RowsSupportFragment(); 65561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment = new HeadersSupportFragment(); 65661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getChildFragmentManager().beginTransaction() 65761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .replace(R.id.browse_headers_dock, mHeadersSupportFragment) 65861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .replace(R.id.browse_container_dock, mRowsSupportFragment).commit(); 65961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 66061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment = (HeadersSupportFragment) getChildFragmentManager() 66161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .findFragmentById(R.id.browse_headers_dock); 66261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment = (RowsSupportFragment) getChildFragmentManager() 66361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu .findFragmentById(R.id.browse_container_dock); 66461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 66561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 66661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setHeadersGone(!mCanShowHeaders); 66761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 66861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setAdapter(mAdapter); 66961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeaderPresenterSelector != null) { 67061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setPresenterSelector(mHeaderPresenterSelector); 67161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 67261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setAdapter(mAdapter); 67361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 67461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.enableRowScaling(mRowScaleEnabled); 67561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setOnItemSelectedListener(mRowSelectedListener); 67661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setOnItemViewSelectedListener(mRowViewSelectedListener); 67761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setOnItemSelectedListener(mHeaderSelectedListener); 67861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setOnHeaderClickedListener(mHeaderClickedListener); 67961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setOnItemClickedListener(mOnItemClickedListener); 68061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setOnItemViewClickedListener(mOnItemViewClickedListener); 68161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View root = inflater.inflate(R.layout.lb_browse_fragment, container, false); 68361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame); 68561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener); 68661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame.setOnChildFocusListener(mOnChildFocusListener); 68761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView = (TitleView) root.findViewById(R.id.browse_title_group); 68961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setTitle(mTitle); 69061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setBadgeDrawable(mBadgeDrawable); 69161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mSearchAffordanceColorSet) { 69261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setSearchAffordanceColors(mSearchAffordanceColors); 69361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 69461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mExternalOnSearchClickedListener != null) { 69561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setOnSearchClickedListener(mExternalOnSearchClickedListener); 69661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 69761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 69861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrandColorSet) { 69961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setBackgroundColor(mBrandColor); 70061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 70161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 70261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSceneWithTitle = sTransitionHelper.createScene(mBrowseFrame, new Runnable() { 70361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 70461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 70561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setVisibility(View.VISIBLE); 70661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 70761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 70861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSceneWithoutTitle = sTransitionHelper.createScene(mBrowseFrame, new Runnable() { 70961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 71061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 71161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setVisibility(View.INVISIBLE); 71261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 71361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 71461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSceneWithHeaders = sTransitionHelper.createScene(mBrowseFrame, new Runnable() { 71561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 71661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 71761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(true); 71861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 71961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 72061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSceneWithoutHeaders = sTransitionHelper.createScene(mBrowseFrame, new Runnable() { 72161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 72261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 72361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(false); 72461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 72561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 726c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mSceneAfterEntranceTransition = sTransitionHelper.createScene(mBrowseFrame, new Runnable() { 727c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 728c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void run() { 729c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setEntranceTransitionEndState(); 730c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 731c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu }); 73261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleUpTransition = TitleTransitionHelper.createTransitionTitleUp(sTransitionHelper); 73361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleDownTransition = TitleTransitionHelper.createTransitionTitleDown(sTransitionHelper); 73461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 73561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.browse_headers, true); 73661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.browse_headers, true); 73761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.container_list, true); 73861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.container_list, true); 73961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 74061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (savedInstanceState != null) { 74161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingTitle = savedInstanceState.getBoolean(TITLE_SHOW); 74261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 74361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setVisibility(mShowingTitle ? View.VISIBLE: View.INVISIBLE); 74461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 74561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return root; 74661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 74761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 748c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 749c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void onViewCreated(View view, Bundle savedInstanceState) { 750c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu super.onViewCreated(view, savedInstanceState); 751c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (mStartEntranceTransitionPending) { 752c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mStartEntranceTransitionPending = false; 753c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu startEntranceTransition(); 754c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 755c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 756c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 75761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void createHeadersTransition() { 75861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransition = sTransitionHelper.createTransitionSet(false); 75961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.excludeChildren(mHeadersTransition, R.id.browse_title_group, true); 76061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Object changeBounds = sTransitionHelper.createChangeBounds(false); 76161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Object fadeIn = sTransitionHelper.createFadeTransition(TransitionHelper.FADE_IN); 76261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Object fadeOut = sTransitionHelper.createFadeTransition(TransitionHelper.FADE_OUT); 76361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Object scale = sTransitionHelper.createScale(); 76461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (TransitionHelper.systemSupportsTransitions()) { 76561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Context context = getView().getContext(); 76661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setInterpolator(changeBounds, 76761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.createDefaultInterpolator(context)); 76861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setInterpolator(fadeIn, 76961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.createDefaultInterpolator(context)); 77061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setInterpolator(fadeOut, 77161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.createDefaultInterpolator(context)); 77261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setInterpolator(scale, 77361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.createDefaultInterpolator(context)); 77461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 77561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 77661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setDuration(fadeOut, mHeadersTransitionDuration); 77761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.addTransition(mHeadersTransition, fadeOut); 77861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 77961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mShowingHeaders) { 78061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setStartDelay(changeBounds, mHeadersTransitionStartDelay); 78161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setStartDelay(scale, mHeadersTransitionStartDelay); 78261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 78361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setDuration(changeBounds, mHeadersTransitionDuration); 78461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.addTransition(mHeadersTransition, changeBounds); 7853595aa0cbdaa8e754365ca94a0b9eb8fc52b9796Dake Gu sTransitionHelper.addTarget(scale, mRowsSupportFragment.getScaleView()); 78661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setDuration(scale, mHeadersTransitionDuration); 78761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.addTransition(mHeadersTransition, scale); 78861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 78961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setDuration(fadeIn, mHeadersTransitionDuration); 79061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setStartDelay(fadeIn, mHeadersTransitionStartDelay); 79161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.addTransition(mHeadersTransition, fadeIn); 79261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 79361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.setTransitionListener(mHeadersTransition, new TransitionListener() { 79461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 79561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onTransitionStart(Object transition) { 79661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 79761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 79861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onTransitionEnd(Object transition) { 79961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersTransition = null; 80061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.onTransitionEnd(); 80161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.onTransitionEnd(); 80261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mShowingHeaders) { 80361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu VerticalGridView headerGridView = mHeadersSupportFragment.getVerticalGridView(); 80461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headerGridView != null && !headerGridView.hasFocus()) { 80561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu headerGridView.requestFocus(); 80661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 80761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 80861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu VerticalGridView rowsGridView = mRowsSupportFragment.getVerticalGridView(); 80961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (rowsGridView != null && !rowsGridView.hasFocus()) { 81061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu rowsGridView.requestFocus(); 81161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 81261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 81361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBrowseTransitionListener != null) { 81461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseTransitionListener.onHeadersTransitionStop(mShowingHeaders); 81561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 81661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 81761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }); 81861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 81961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 82061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 82161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the {@link PresenterSelector} used to render the row headers. 82261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 82361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headerPresenterSelector The PresenterSelector that will determine 82461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the Presenter for each row header. 82561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 82661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setHeaderPresenterSelector(PresenterSelector headerPresenterSelector) { 82761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeaderPresenterSelector = headerPresenterSelector; 82861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 82961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setPresenterSelector(mHeaderPresenterSelector); 83061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 83161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 83261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 833c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void setRowsAlignedLeft(boolean alignLeft) { 83461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu MarginLayoutParams lp; 83561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View containerList; 83661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList = mRowsSupportFragment.getView(); 83761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu lp = (MarginLayoutParams) containerList.getLayoutParams(); 838c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu lp.leftMargin = alignLeft ? 0 : mContainerListMarginLeft; 83961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList.setLayoutParams(lp); 840c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 84161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 842c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void setHeadersOnScreen(boolean onScreen) { 843c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu MarginLayoutParams lp; 844c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu View containerList; 84561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList = mHeadersSupportFragment.getView(); 84661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu lp = (MarginLayoutParams) containerList.getLayoutParams(); 847c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu lp.leftMargin = onScreen ? 0 : -mContainerListMarginLeft; 84861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu containerList.setLayoutParams(lp); 849c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 85061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 851c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void showHeaders(boolean show) { 852c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (DEBUG) Log.v(TAG, "showHeaders " + show); 853c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mHeadersSupportFragment.setHeadersEnabled(show); 854c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(show); 855c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setRowsAlignedLeft(!show); 85661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setExpand(!show); 85761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 85861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 85961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private HeadersSupportFragment.OnHeaderClickedListener mHeaderClickedListener = 86061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new HeadersSupportFragment.OnHeaderClickedListener() { 86161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 86261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onHeaderClicked() { 86361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mCanShowHeaders || !mShowingHeaders || isInHeadersTransition()) { 86461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 86561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 86661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startHeadersTransitionInternal(false); 86761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.getVerticalGridView().requestFocus(); 86861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 86961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 87061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 87161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemViewSelectedListener mRowViewSelectedListener = new OnItemViewSelectedListener() { 87261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 87361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 87461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu RowPresenter.ViewHolder rowViewHolder, Row row) { 87561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int position = mRowsSupportFragment.getVerticalGridView().getSelectedPosition(); 87661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "row selected position " + position); 87761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu onRowSelected(position); 87861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mExternalOnItemViewSelectedListener != null) { 87961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemViewSelectedListener.onItemSelected(itemViewHolder, item, 88061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu rowViewHolder, row); 88161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 88261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 88361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 88461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 88561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemSelectedListener mRowSelectedListener = new OnItemSelectedListener() { 88661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 88761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onItemSelected(Object item, Row row) { 88861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mExternalOnItemSelectedListener != null) { 88961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mExternalOnItemSelectedListener.onItemSelected(item, row); 89061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 89161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 89261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 89361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 89461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnItemSelectedListener mHeaderSelectedListener = new OnItemSelectedListener() { 89561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 89661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onItemSelected(Object item, Row row) { 89761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int position = mHeadersSupportFragment.getVerticalGridView().getSelectedPosition(); 89861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "header selected position " + position); 89961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu onRowSelected(position); 90061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 90161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 90261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 90361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void onRowSelected(int position) { 90461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (position != mSelectedPosition) { 90561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSetSelectionRunnable.mPosition = position; 90661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBrowseFrame.getHandler().post(mSetSelectionRunnable); 90761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 90861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getAdapter() == null || getAdapter().size() == 0 || position == 0) { 90961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mShowingTitle) { 91061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.runTransition(mSceneWithTitle, mTitleDownTransition); 91161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingTitle = true; 91261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 91361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (mShowingTitle) { 91461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleUpTransition); 91561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingTitle = false; 91661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 91761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 91861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 91961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 92061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private class SetSelectionRunnable implements Runnable { 92161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int mPosition; 92261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 92361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void run() { 92461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setSelection(mPosition); 92561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 92661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 92761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 92861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final SetSelectionRunnable mSetSelectionRunnable = new SetSelectionRunnable(); 92961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 93061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void setSelection(int position) { 93161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (position != NO_POSITION) { 93261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setSelectedPosition(position); 93361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setSelectedPosition(position); 93461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mSelectedPosition = position; 93661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 93761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 93861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 93961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onStart() { 94061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onStart(); 94161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setWindowAlignmentFromTop(mContainerListAlignTop); 94261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setItemAlignment(); 94361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setWindowAlignmentFromTop(mContainerListAlignTop); 94461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.setItemAlignment(); 94561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 9463595aa0cbdaa8e754365ca94a0b9eb8fc52b9796Dake Gu mRowsSupportFragment.setScalePivots(0, mContainerListAlignTop); 94761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 94861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders && mShowingHeaders && mHeadersSupportFragment.getView() != null) { 94961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.getView().requestFocus(); 95061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if ((!mCanShowHeaders || !mShowingHeaders) 95161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu && mRowsSupportFragment.getView() != null) { 95261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRowsSupportFragment.getView().requestFocus(); 95361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 95461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mCanShowHeaders) { 95561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu showHeaders(mShowingHeaders); 95661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 957c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (mEntranceTransitionEnabled) { 958c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setEntranceTransitionStartState(); 959c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 96061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 96161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 96261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 96361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Enable/disable headers transition on back key support. This is enabled by 96461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * default. The BrowseSupportFragment will add a back stack entry when headers are 96561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * showing. Running a headers transition when the back key is pressed only 96661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * works when the headers state is {@link #HEADERS_ENABLED} or 96761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #HEADERS_HIDDEN}. 96861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * <p> 96961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * NOTE: If an Activity has its own onBackPressed() handling, you must 97061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * disable this feature. You may use {@link #startHeadersTransition(boolean)} 97161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * and {@link BrowseTransitionListener} in your own back stack handling. 97261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 97361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public final void setHeadersTransitionOnBackEnabled(boolean headersBackStackEnabled) { 97461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersBackStackEnabled = headersBackStackEnabled; 97561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 97661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 97761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 97861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if headers transition on back key support is enabled. 97961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 98061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public final boolean isHeadersTransitionOnBackEnabled() { 98161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersBackStackEnabled; 98261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 98361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 98461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void readArguments(Bundle args) { 98561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args == null) { 98661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 98761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 98861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args.containsKey(ARG_TITLE)) { 98961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setTitle(args.getString(ARG_TITLE)); 99061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 99161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (args.containsKey(ARG_HEADERS_STATE)) { 99261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setHeadersState(args.getInt(ARG_HEADERS_STATE)); 99361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 99461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 99561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 99661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 99761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the drawable displayed in the browse fragment title. 99861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 99961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param drawable The Drawable to display in the browse fragment title. 100061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 100161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setBadgeDrawable(Drawable drawable) { 100261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBadgeDrawable != drawable) { 100361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBadgeDrawable = drawable; 100461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mTitleView != null) { 100561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setBadgeDrawable(drawable); 100661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 100961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 101061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 101161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the badge drawable used in the fragment title. 101261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 101361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public Drawable getBadgeDrawable() { 101461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mBadgeDrawable; 101561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 101661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 101761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 101861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets a title for the browse fragment. 101961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 102061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param title The title of the browse fragment. 102161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 102261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setTitle(String title) { 102361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitle = title; 102461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mTitleView != null) { 102561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mTitleView.setTitle(title); 102661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 102761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 102861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 102961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 103061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the title for the browse fragment. 103161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 103261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public String getTitle() { 103361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mTitle; 103461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 103561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 103661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 103761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the state for the headers column in the browse fragment. Must be one 103861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * of {@link #HEADERS_ENABLED}, {@link #HEADERS_HIDDEN}, or 103961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * {@link #HEADERS_DISABLED}. 104061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 104161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param headersState The state of the headers for the browse fragment. 104261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 104361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setHeadersState(int headersState) { 104461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headersState < HEADERS_ENABLED || headersState > HEADERS_DISABLED) { 104561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalArgumentException("Invalid headers state: " + headersState); 104661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 104761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "setHeadersState " + headersState); 104861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 104961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (headersState != mHeadersState) { 105061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersState = headersState; 105161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu switch (headersState) { 105261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_ENABLED: 105361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = true; 105461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = true; 105561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 105661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_HIDDEN: 105761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = true; 105861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = false; 105961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 106061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case HEADERS_DISABLED: 106161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mCanShowHeaders = false; 106261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowingHeaders = false; 106361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 106461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu default: 106561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Log.w(TAG, "Unknown headers state: " + headersState); 106661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 106761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 106861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHeadersSupportFragment != null) { 106961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHeadersSupportFragment.setHeadersGone(!mCanShowHeaders); 107061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 107161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 107261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 107361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 107461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 107561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the state of the headers column in the browse fragment. 107661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 107761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getHeadersState() { 107861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mHeadersState; 107961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 1080c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1081c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu /** 1082c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * Enable or disable entrance transition. Typically this is set in onCreate() 1083c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * when savedInstance is null. When the entrance transition is enabled, the 1084c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * fragment is initially having headers and content hidden. 1085c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * When data of rows are ready, you must call startEntranceTransition() to kick off 1086c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * the transition. 1087c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu */ 1088c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void setEntranceTransitionEnabled(boolean runEntranceTransition) { 1089c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mEntranceTransitionEnabled = runEntranceTransition; 1090c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1091c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1092c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu /** 1093c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * Return true if entrance transition is enabled and not started yet. 1094c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu */ 1095c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public boolean isEntranceTransitionEnabled() { 1096c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu return mEntranceTransitionEnabled; 1097c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1098c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1099c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu /** 1100c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * Starts entrance transition if setEntranceTransitionEnabled(true) is called 1101c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * and entrance transition is not started yet. 1102c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * When fragment finishes loading data of rows, it should call startEntranceTransition() 1103c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * to execute the entrance transition. Calling startEntranceTransition() multiple 1104c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu * times is safe. 1105c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu */ 1106c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void startEntranceTransition() { 1107c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (!mEntranceTransitionEnabled || mEntranceTransition != null) { 1108c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu return; 1109c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1110c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu // if view is not created yet, delay until onViewCreated() 1111c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (getView() == null) { 1112c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mStartEntranceTransitionPending = true; 1113c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu return; 1114c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1115c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu // wait till views get their initial position before start transition 1116c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu final View view = getView(); 1117c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu view.getViewTreeObserver().addOnPreDrawListener( 1118c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu new ViewTreeObserver.OnPreDrawListener() { 1119c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 1120c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public boolean onPreDraw() { 1121c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu view.getViewTreeObserver().removeOnPreDrawListener(this); 1122c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu createEntranceTransition(); 1123c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mEntranceTransitionEnabled = false; 1124c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu sTransitionHelper.runTransition(mSceneAfterEntranceTransition, 1125c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mEntranceTransition); 1126c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu return false; 1127c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1128c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu }); 1129c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu view.invalidate(); 1130c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1131c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1132c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void createEntranceTransition() { 1133c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mEntranceTransition = sTransitionHelper.loadTransition(getActivity(), 1134c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu R.transition.lb_browse_entrance_transition); 1135c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu if (mEntranceTransition == null) { 1136c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu return; 1137c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1138c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu sTransitionHelper.setTransitionListener(mEntranceTransition, new TransitionListener() { 1139c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 1140c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void onTransitionStart(Object transition) { 1141c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mHeadersSupportFragment.onTransitionStart(); 1142c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mRowsSupportFragment.onTransitionStart(); 1143c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1144c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 1145c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu public void onTransitionEnd(Object transition) { 1146c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mRowsSupportFragment.onTransitionEnd(); 1147c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mHeadersSupportFragment.onTransitionEnd(); 1148c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mEntranceTransition = null; 1149c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1150c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu }); 1151c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1152c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1153c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu private void setSearchOrbViewOnScreen(boolean onScreen) { 1154c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu View searchOrbView = mTitleView.getSearchAffordanceView(); 1155c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu MarginLayoutParams lp = (MarginLayoutParams) searchOrbView.getLayoutParams(); 1156c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu lp.leftMargin = onScreen ? 0 : -mContainerListMarginLeft; 1157c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu searchOrbView.setLayoutParams(lp); 1158c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1159c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1160c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void setEntranceTransitionStartState() { 1161c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(false); 1162c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setSearchOrbViewOnScreen(false); 1163c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mRowsSupportFragment.setViewsVisible(false); 1164c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1165c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 1166c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu void setEntranceTransitionEndState() { 1167c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setHeadersOnScreen(mShowingHeaders); 1168c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu setSearchOrbViewOnScreen(true); 1169c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu mRowsSupportFragment.setViewsVisible(true); 1170c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 1171c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu 117261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu} 117361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1174