147520b68e50572a9775a662410c5aff8300c8784Craig Stout/* 247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Copyright (C) 2014 The Android Open Source Project 347520b68e50572a9775a662410c5aff8300c8784Craig Stout * 447520b68e50572a9775a662410c5aff8300c8784Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 547520b68e50572a9775a662410c5aff8300c8784Craig Stout * in compliance with the License. You may obtain a copy of the License at 647520b68e50572a9775a662410c5aff8300c8784Craig Stout * 747520b68e50572a9775a662410c5aff8300c8784Craig Stout * http://www.apache.org/licenses/LICENSE-2.0 847520b68e50572a9775a662410c5aff8300c8784Craig Stout * 947520b68e50572a9775a662410c5aff8300c8784Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License 1047520b68e50572a9775a662410c5aff8300c8784Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1147520b68e50572a9775a662410c5aff8300c8784Craig Stout * or implied. See the License for the specific language governing permissions and limitations under 1247520b68e50572a9775a662410c5aff8300c8784Craig Stout * the License. 1347520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 1447520b68e50572a9775a662410c5aff8300c8784Craig Stoutpackage android.support.v17.leanback.widget; 1547520b68e50572a9775a662410c5aff8300c8784Craig Stout 16892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.content.Context; 179240e796bc63422c28f2707840bd99c48573279bDake Guimport android.content.res.TypedArray; 18892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.support.v17.leanback.R; 19f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stoutimport android.support.v17.leanback.system.Settings; 20afb203b71421cb0d477d4d470e852cc9647dde48Dake Guimport android.support.v17.leanback.transition.TransitionHelper; 21cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Guimport android.support.v7.widget.RecyclerView; 224cd4cce277571385f4d1a56d5348578c38368cbeCraig Stoutimport android.util.Log; 2360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.view.KeyEvent; 2447520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.View; 2547520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.ViewGroup; 2647520b68e50572a9775a662410c5aff8300c8784Craig Stout 27bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stoutimport java.util.HashMap; 28bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 2947520b68e50572a9775a662410c5aff8300c8784Craig Stout/** 307aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * ListRowPresenter renders {@link ListRow} using a 31cb13a318e577e14461eb008071dddf762847de42Dake Gu * {@link HorizontalGridView} hosted in a {@link ListRowView}. 327aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * 337aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Hover card</h3> 3447520b68e50572a9775a662410c5aff8300c8784Craig Stout * Optionally, {@link #setHoverCardPresenterSelector(PresenterSelector)} can be used to 3547520b68e50572a9775a662410c5aff8300c8784Craig Stout * display a view for the currently focused list item below the rendered 3647520b68e50572a9775a662410c5aff8300c8784Craig Stout * list. This view is known as a hover card. 377aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * 387aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Selection animation</h3> 39a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * ListRowPresenter disables {@link RowPresenter}'s default dimming effect and draws 40a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * a dim overlay on each view individually. A subclass may override and disable 417aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #isUsingDefaultListSelectEffect()} and write its own dim effect in 427aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #onSelectLevelChanged(RowPresenter.ViewHolder)}. 43dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * 44dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * <h3>Shadow</h3> 45a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * ListRowPresenter applies a default shadow to each child view. Call 46a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link #setShadowEnabled(boolean)} to disable shadows. A subclass may override and return 47dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * false in {@link #isUsingDefaultShadow()} and replace with its own shadow implementation. 4847520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 4947520b68e50572a9775a662410c5aff8300c8784Craig Stoutpublic class ListRowPresenter extends RowPresenter { 5047520b68e50572a9775a662410c5aff8300c8784Craig Stout 5147520b68e50572a9775a662410c5aff8300c8784Craig Stout private static final String TAG = "ListRowPresenter"; 5247520b68e50572a9775a662410c5aff8300c8784Craig Stout private static final boolean DEBUG = false; 5347520b68e50572a9775a662410c5aff8300c8784Craig Stout 54bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout private static final int DEFAULT_RECYCLED_POOL_SIZE = 24; 55bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 56a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 57a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * ViewHolder for the ListRowPresenter. 58a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 5947520b68e50572a9775a662410c5aff8300c8784Craig Stout public static class ViewHolder extends RowPresenter.ViewHolder { 6047520b68e50572a9775a662410c5aff8300c8784Craig Stout final ListRowPresenter mListRowPresenter; 6147520b68e50572a9775a662410c5aff8300c8784Craig Stout final HorizontalGridView mGridView; 6271fddded48048acfa744ac352166770c91a1c2b1Dake Gu ItemBridgeAdapter mItemBridgeAdapter; 6347520b68e50572a9775a662410c5aff8300c8784Craig Stout final HorizontalHoverCardSwitcher mHoverCardViewSwitcher = new HorizontalHoverCardSwitcher(); 64e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingTop; 65e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingBottom; 66e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingLeft; 67e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingRight; 6847520b68e50572a9775a662410c5aff8300c8784Craig Stout 6947520b68e50572a9775a662410c5aff8300c8784Craig Stout public ViewHolder(View rootView, HorizontalGridView gridView, ListRowPresenter p) { 7047520b68e50572a9775a662410c5aff8300c8784Craig Stout super(rootView); 7147520b68e50572a9775a662410c5aff8300c8784Craig Stout mGridView = gridView; 7247520b68e50572a9775a662410c5aff8300c8784Craig Stout mListRowPresenter = p; 73e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingTop = mGridView.getPaddingTop(); 74e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingBottom = mGridView.getPaddingBottom(); 75e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingLeft = mGridView.getPaddingLeft(); 76e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingRight = mGridView.getPaddingRight(); 7747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 7847520b68e50572a9775a662410c5aff8300c8784Craig Stout 7960f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu /** 8060f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * Gets ListRowPresenter that creates this ViewHolder. 8160f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * @return ListRowPresenter that creates this ViewHolder. 8260f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu */ 8347520b68e50572a9775a662410c5aff8300c8784Craig Stout public final ListRowPresenter getListRowPresenter() { 8447520b68e50572a9775a662410c5aff8300c8784Craig Stout return mListRowPresenter; 8547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 8647520b68e50572a9775a662410c5aff8300c8784Craig Stout 8760f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu /** 8860f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * Gets HorizontalGridView that shows a list of items. 8960f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * @return HorizontalGridView that shows a list of items. 9060f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu */ 9147520b68e50572a9775a662410c5aff8300c8784Craig Stout public final HorizontalGridView getGridView() { 9247520b68e50572a9775a662410c5aff8300c8784Craig Stout return mGridView; 9347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 949de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout 9560f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu /** 9660f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * Gets ItemBridgeAdapter that creates the list of items. 9760f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * @return ItemBridgeAdapter that creates the list of items. 9860f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu */ 999de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout public final ItemBridgeAdapter getBridgeAdapter() { 1009de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout return mItemBridgeAdapter; 1019de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout } 10260f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu 10360f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu /** 10460f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * Gets selected item position in adapter. 10560f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * @return Selected item position in adapter. 10660f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu */ 10760f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu public int getSelectedPosition() { 10860f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu return mGridView.getSelectedPosition(); 10960f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu } 11060f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu 11160f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu /** 11260f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * Gets ViewHolder at a position in adapter. Returns null if the item does not exist 11360f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * or the item is not bound to a view. 11460f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * @param position Position of the item in adapter. 11560f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu * @return ViewHolder bounds to the item. 11660f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu */ 11760f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu public Presenter.ViewHolder getItemViewHolder(int position) { 11860f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder) mGridView 11960f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu .findViewHolderForAdapterPosition(position); 12060f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu if (ibvh == null) { 12160f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu return null; 12260f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu } 12360f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu return ibvh.getViewHolder(); 12460f531e3d9667db9afe091f5a7979410eb7a0b48Dake Gu } 12547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 12647520b68e50572a9775a662410c5aff8300c8784Craig Stout 127cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 128cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * A task on the ListRowPresenter.ViewHolder that can select an item by position in the 129cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * HorizontalGridView and perform an optional item task on it. 130cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 131cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public static class SelectItemViewHolderTask extends Presenter.ViewHolderTask { 132cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 133cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu private int mItemPosition; 134cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu private boolean mSmoothScroll = true; 135cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu private Presenter.ViewHolderTask mItemTask; 136cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 137cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public SelectItemViewHolderTask(int itemPosition) { 138cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu setItemPosition(itemPosition); 139cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 140cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 141cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 142cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * Sets the adapter position of item to select. 143cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * @param itemPosition Position of the item in adapter. 144cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 145cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public void setItemPosition(int itemPosition) { 146cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu mItemPosition = itemPosition; 147cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 148cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 149cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 150cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * Returns the adapter position of item to select. 151cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * @return The adapter position of item to select. 152cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 153cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public int getItemPosition() { 154cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu return mItemPosition; 155cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 156cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 157cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 158cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * Sets smooth scrolling to the item or jump to the item without scrolling. By default it is 159cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * true. 160cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * @param smoothScroll True for smooth scrolling to the item, false otherwise. 161cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 162cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public void setSmoothScroll(boolean smoothScroll) { 163cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu mSmoothScroll = smoothScroll; 164cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 165cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 166cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 167cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * Returns true if smooth scrolling to the item false otherwise. By default it is true. 168cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * @return True for smooth scrolling to the item, false otherwise. 169cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 170cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public boolean isSmoothScroll() { 171cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu return mSmoothScroll; 172cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 173cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 174cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 175cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * Returns optional task to run when the item is selected, null for no task. 176cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * @return Optional task to run when the item is selected, null for no task. 177cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 178cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public Presenter.ViewHolderTask getItemTask() { 179cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu return mItemTask; 180cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 181cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 182cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu /** 183cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * Sets task to run when the item is selected, null for no task. 184cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu * @param itemTask Optional task to run when the item is selected, null for no task. 185cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu */ 186cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public void setItemTask(Presenter.ViewHolderTask itemTask) { 187cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu mItemTask = itemTask; 188cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 189cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 190cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu @Override 191cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public void run(Presenter.ViewHolder holder) { 192cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu if (holder instanceof ListRowPresenter.ViewHolder) { 193cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu HorizontalGridView gridView = ((ListRowPresenter.ViewHolder) holder).getGridView(); 194cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu android.support.v17.leanback.widget.ViewHolderTask task = null; 195cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu if (mItemTask != null) { 196cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu task = new android.support.v17.leanback.widget.ViewHolderTask() { 197cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu final Presenter.ViewHolderTask itemTask = mItemTask; 198cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu @Override 199cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu public void run(RecyclerView.ViewHolder rvh) { 200cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder) rvh; 201cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu itemTask.run(ibvh.getViewHolder()); 202cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 203cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu }; 204cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 205cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu if (isSmoothScroll()) { 206cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu gridView.setSelectedPositionSmooth(mItemPosition, task); 207cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } else { 208cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu gridView.setSelectedPosition(mItemPosition, task); 209cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 210cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 211cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 212cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu } 213cff6e470de4a0b2ed1dec944bdc848bd26f852f6Dake Gu 21471fddded48048acfa744ac352166770c91a1c2b1Dake Gu class ListRowPresenterItemBridgeAdapter extends ItemBridgeAdapter { 21571fddded48048acfa744ac352166770c91a1c2b1Dake Gu ListRowPresenter.ViewHolder mRowViewHolder; 21671fddded48048acfa744ac352166770c91a1c2b1Dake Gu 21771fddded48048acfa744ac352166770c91a1c2b1Dake Gu ListRowPresenterItemBridgeAdapter(ListRowPresenter.ViewHolder rowViewHolder) { 21871fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder = rowViewHolder; 21971fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 22071fddded48048acfa744ac352166770c91a1c2b1Dake Gu 22171fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 222254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu protected void onCreate(ItemBridgeAdapter.ViewHolder viewHolder) { 223afb203b71421cb0d477d4d470e852cc9647dde48Dake Gu if (viewHolder.itemView instanceof ViewGroup) { 2248403619efebe94666c0615c3fc85080a303acf80Dake Gu TransitionHelper.setTransitionGroup((ViewGroup) viewHolder.itemView, true); 225afb203b71421cb0d477d4d470e852cc9647dde48Dake Gu } 226254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu if (mShadowOverlayHelper != null) { 227254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu mShadowOverlayHelper.onViewCreated(viewHolder.itemView); 228254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu } 229254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu } 230254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu 231254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu @Override 23271fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onBind(final ItemBridgeAdapter.ViewHolder viewHolder) { 23371fddded48048acfa744ac352166770c91a1c2b1Dake Gu // Only when having an OnItemClickListner, we will attach the OnClickListener. 2343a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout if (mRowViewHolder.getOnItemViewClickedListener() != null) { 23571fddded48048acfa744ac352166770c91a1c2b1Dake Gu viewHolder.mHolder.view.setOnClickListener(new View.OnClickListener() { 23671fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 23771fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onClick(View v) { 23871fddded48048acfa744ac352166770c91a1c2b1Dake Gu ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 23971fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder.mGridView.getChildViewHolder(viewHolder.itemView); 2403a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout if (mRowViewHolder.getOnItemViewClickedListener() != null) { 2413a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout mRowViewHolder.getOnItemViewClickedListener().onItemClicked(viewHolder.mHolder, 24271fddded48048acfa744ac352166770c91a1c2b1Dake Gu ibh.mItem, mRowViewHolder, (ListRow) mRowViewHolder.mRow); 24371fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 24471fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 24571fddded48048acfa744ac352166770c91a1c2b1Dake Gu }); 24671fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 24771fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 24871fddded48048acfa744ac352166770c91a1c2b1Dake Gu 24971fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 25071fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onUnbind(ItemBridgeAdapter.ViewHolder viewHolder) { 2513a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout if (mRowViewHolder.getOnItemViewClickedListener() != null) { 25271fddded48048acfa744ac352166770c91a1c2b1Dake Gu viewHolder.mHolder.view.setOnClickListener(null); 25371fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 25471fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 25571fddded48048acfa744ac352166770c91a1c2b1Dake Gu 25671fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 25771fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) { 258254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu if (mShadowOverlayHelper != null && mShadowOverlayHelper.needsOverlay()) { 25971fddded48048acfa744ac352166770c91a1c2b1Dake Gu int dimmedColor = mRowViewHolder.mColorDimmer.getPaint().getColor(); 26085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu mShadowOverlayHelper.setOverlayColor(viewHolder.itemView, dimmedColor); 26171fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 26271fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder.syncActivatedStatus(viewHolder.itemView); 26371fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 26471fddded48048acfa744ac352166770c91a1c2b1Dake Gu 26571fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 26671fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onAddPresenter(Presenter presenter, int type) { 26771fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder.getGridView().getRecycledViewPool().setMaxRecycledViews( 26871fddded48048acfa744ac352166770c91a1c2b1Dake Gu type, getRecycledPoolSize(presenter)); 26971fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 27071fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 27171fddded48048acfa744ac352166770c91a1c2b1Dake Gu 272b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata private int mNumRows = 1; 273a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn private int mRowHeight; 274a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn private int mExpandedRowHeight; 27547520b68e50572a9775a662410c5aff8300c8784Craig Stout private PresenterSelector mHoverCardPresenterSelector; 27641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield private int mFocusZoomFactor; 27741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield private boolean mUseFocusDimmer; 278892181367d658f347d00ea5e091aa31f086b2a20Dake Gu private boolean mShadowEnabled = true; 2799240e796bc63422c28f2707840bd99c48573279bDake Gu private int mBrowseRowsFadingEdgeLength = -1; 2804f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout private boolean mRoundedCornersEnabled = true; 28185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu private boolean mKeepChildForeground = true; 282bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout private HashMap<Presenter, Integer> mRecycledPoolSize = new HashMap<Presenter, Integer>(); 283254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu private ShadowOverlayHelper mShadowOverlayHelper; 28485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu private ItemBridgeAdapter.Wrapper mShadowOverlayWrapper; 285b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 2864cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static int sSelectedRowTopPadding; 2874cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static int sExpandedSelectedRowTopPadding; 2884cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static int sExpandedRowNoHovercardBottomPadding; 2894cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 290b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 291b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Constructs a ListRowPresenter with defaults. 29241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * Uses {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} for focus zooming and 29341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * disabled dimming on focus. 294b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 295b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public ListRowPresenter() { 296739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout this(FocusHighlight.ZOOM_FACTOR_MEDIUM); 297b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 298b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 299b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 300b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Constructs a ListRowPresenter with the given parameters. 301b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * 30241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * @param focusZoomFactor Controls the zoom factor used when an item view is focused. One of 303739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_NONE}, 304739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_SMALL}, 305575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_XSMALL}, 306739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_MEDIUM}, 307739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_LARGE} 30841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * Dimming on focus defaults to disabled. 309b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 31041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield public ListRowPresenter(int focusZoomFactor) { 31141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield this(focusZoomFactor, false); 31241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield } 31341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield 31441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield /** 31541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * Constructs a ListRowPresenter with the given parameters. 31641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * 31741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * @param focusZoomFactor Controls the zoom factor used when an item view is focused. One of 31841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * {@link FocusHighlight#ZOOM_FACTOR_NONE}, 31941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * {@link FocusHighlight#ZOOM_FACTOR_SMALL}, 32041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * {@link FocusHighlight#ZOOM_FACTOR_XSMALL}, 32141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * {@link FocusHighlight#ZOOM_FACTOR_MEDIUM}, 32241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * {@link FocusHighlight#ZOOM_FACTOR_LARGE} 32341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * @param useFocusDimmer determines if the FocusHighlighter will use the dimmer 32441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield */ 32541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield public ListRowPresenter(int focusZoomFactor, boolean useFocusDimmer) { 32641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield if (!FocusHighlightHelper.isValidZoomIndex(focusZoomFactor)) { 327575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout throw new IllegalArgumentException("Unhandled zoom factor"); 328575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout } 32941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield mFocusZoomFactor = focusZoomFactor; 33041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield mUseFocusDimmer = useFocusDimmer; 331b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 332b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 333b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 334f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Sets the row height for rows created by this Presenter. Rows 335a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * created before calling this method will not be updated. 336a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * 337f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * @param rowHeight Row height in pixels, or WRAP_CONTENT, or 0 338f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * to use the default height. 339a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 340a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public void setRowHeight(int rowHeight) { 341a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn mRowHeight = rowHeight; 342a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 343a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 344a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 345f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Returns the row height for list rows created by this Presenter. 346a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 347a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public int getRowHeight() { 348a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn return mRowHeight; 349a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 350a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 351a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 352f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Sets the expanded row height for rows created by this Presenter. 353f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * If not set, expanded rows have the same height as unexpanded 354a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * rows. 355a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * 356f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * @param rowHeight The row height in to use when the row is expanded, 357f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * in pixels, or WRAP_CONTENT, or 0 to use the default. 358a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 359a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public void setExpandedRowHeight(int rowHeight) { 360a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn mExpandedRowHeight = rowHeight; 361a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 362a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 363a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 364f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Returns the expanded row height for rows created by this Presenter. 365a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 366a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public int getExpandedRowHeight() { 367f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout return mExpandedRowHeight != 0 ? mExpandedRowHeight : mRowHeight; 368a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 369a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 370a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 371b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Returns the zoom factor used for focus highlighting. 372b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 37341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield public final int getFocusZoomFactor() { 37441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield return mFocusZoomFactor; 37541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield } 376a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout 37741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield /** 37841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * Returns the zoom factor used for focus highlighting. 37941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * @deprecated use {@link #getFocusZoomFactor} instead. 38041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield */ 381a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout @Deprecated 382a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout public final int getZoomFactor() { 38341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield return mFocusZoomFactor; 38441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield } 38541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield 38641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield /** 38741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield * Returns true if the focus dimmer is used for focus highlighting; false otherwise. 38841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield */ 38941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield public final boolean isFocusDimmerUsed() { 39041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield return mUseFocusDimmer; 391b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 39247520b68e50572a9775a662410c5aff8300c8784Craig Stout 393b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata /** 394b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata * Sets the numbers of rows for rendering the list of items. By default, it is 395b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata * set to 1. 396b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata */ 397b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata public void setNumRows(int numRows) { 398b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata this.mNumRows = numRows; 399b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata } 400b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata 40147520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 40247520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) { 40347520b68e50572a9775a662410c5aff8300c8784Craig Stout super.initializeRowViewHolder(holder); 40447520b68e50572a9775a662410c5aff8300c8784Craig Stout final ViewHolder rowViewHolder = (ViewHolder) holder; 405254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu Context context = holder.view.getContext(); 406254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu if (mShadowOverlayHelper == null) { 40785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu mShadowOverlayHelper = new ShadowOverlayHelper.Builder() 40885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .needsOverlay(needsDefaultListSelectEffect()) 40985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .needsShadow(needsDefaultShadow()) 41085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .needsRoundedCorner(areChildRoundedCornersEnabled()) 41185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .preferZOrder(isUsingZOrder(context)) 41285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .keepForegroundDrawable(mKeepChildForeground) 41385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .options(createShadowOverlayOptions()) 41485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu .build(context); 41585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu if (mShadowOverlayHelper.needsWrapper()) { 41685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu mShadowOverlayWrapper = new ItemBridgeAdapterShadowOverlayWrapper( 41785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu mShadowOverlayHelper); 41885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu } 419cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 420254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu rowViewHolder.mItemBridgeAdapter = new ListRowPresenterItemBridgeAdapter(rowViewHolder); 421254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu // set wrapper if needed 42285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu rowViewHolder.mItemBridgeAdapter.setWrapper(mShadowOverlayWrapper); 423254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu mShadowOverlayHelper.prepareParentForShadow(rowViewHolder.mGridView); 424254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu 42546e7de54775fc37dc51041629c79249e6dae3242Dake Gu FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter, 42641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield mFocusZoomFactor, mUseFocusDimmer); 427254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu rowViewHolder.mGridView.setFocusDrawingOrderEnabled(mShadowOverlayHelper.getShadowType() 428254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu == ShadowOverlayHelper.SHADOW_STATIC); 42947520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mGridView.setOnChildSelectedListener( 43047520b68e50572a9775a662410c5aff8300c8784Craig Stout new OnChildSelectedListener() { 43147520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 43247520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onChildSelected(ViewGroup parent, View view, int position, long id) { 4330246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu selectChildView(rowViewHolder, view, true); 43447520b68e50572a9775a662410c5aff8300c8784Craig Stout } 43547520b68e50572a9775a662410c5aff8300c8784Craig Stout }); 43660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout rowViewHolder.mGridView.setOnUnhandledKeyListener( 43760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout new BaseGridView.OnUnhandledKeyListener() { 43860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout @Override 43960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout public boolean onUnhandledKey(KeyEvent event) { 44060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (rowViewHolder.getOnKeyListener() != null && 44160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout rowViewHolder.getOnKeyListener().onKey( 44260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout rowViewHolder.view, event.getKeyCode(), event)) { 44360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout return true; 44460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 44560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout return false; 44647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 44747520b68e50572a9775a662410c5aff8300c8784Craig Stout }); 448b9fd330aaaede57fd2ff0ac1289429aab7a3cf42susnata rowViewHolder.mGridView.setNumRows(mNumRows); 44947520b68e50572a9775a662410c5aff8300c8784Craig Stout } 45047520b68e50572a9775a662410c5aff8300c8784Craig Stout 451cb13a318e577e14461eb008071dddf762847de42Dake Gu final boolean needsDefaultListSelectEffect() { 452cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return isUsingDefaultListSelectEffect() && getSelectEffectEnabled(); 453cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 454cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 45547520b68e50572a9775a662410c5aff8300c8784Craig Stout /** 456bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout * Sets the recycled pool size for the given presenter. 457bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout */ 458bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout public void setRecycledPoolSize(Presenter presenter, int size) { 459bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout mRecycledPoolSize.put(presenter, size); 460bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout } 461bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 462bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout /** 463bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout * Returns the recycled pool size for the given presenter. 464bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout */ 465bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout public int getRecycledPoolSize(Presenter presenter) { 466bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout return mRecycledPoolSize.containsKey(presenter) ? mRecycledPoolSize.get(presenter) : 467bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout DEFAULT_RECYCLED_POOL_SIZE; 468bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout } 469bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 470bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout /** 471a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Sets the {@link PresenterSelector} used for showing a select object in a hover card. 47247520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 47347520b68e50572a9775a662410c5aff8300c8784Craig Stout public final void setHoverCardPresenterSelector(PresenterSelector selector) { 47447520b68e50572a9775a662410c5aff8300c8784Craig Stout mHoverCardPresenterSelector = selector; 47547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 47647520b68e50572a9775a662410c5aff8300c8784Craig Stout 47747520b68e50572a9775a662410c5aff8300c8784Craig Stout /** 478a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Returns the {@link PresenterSelector} used for showing a select object in a hover card. 47947520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 48047520b68e50572a9775a662410c5aff8300c8784Craig Stout public final PresenterSelector getHoverCardPresenterSelector() { 48147520b68e50572a9775a662410c5aff8300c8784Craig Stout return mHoverCardPresenterSelector; 48247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 48347520b68e50572a9775a662410c5aff8300c8784Craig Stout 48447520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 48547520b68e50572a9775a662410c5aff8300c8784Craig Stout * Perform operations when a child of horizontal grid view is selected. 48647520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 4870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu private void selectChildView(ViewHolder rowViewHolder, View view, boolean fireEvent) { 48847520b68e50572a9775a662410c5aff8300c8784Craig Stout if (view != null) { 4890d841b3454f896da58deb506ca22730bfd04f34fDake Gu if (rowViewHolder.mSelected) { 4903173fdc69a928880a271036570c235f874b86f65butterfield@google.com ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 4913173fdc69a928880a271036570c235f874b86f65butterfield@google.com rowViewHolder.mGridView.getChildViewHolder(view); 4923173fdc69a928880a271036570c235f874b86f65butterfield@google.com 4933173fdc69a928880a271036570c235f874b86f65butterfield@google.com if (mHoverCardPresenterSelector != null) { 4943a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout rowViewHolder.mHoverCardViewSwitcher.select( 4953a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout rowViewHolder.mGridView, view, ibh.mItem); 4963173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 4970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu if (fireEvent && rowViewHolder.getOnItemViewSelectedListener() != null) { 4983a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout rowViewHolder.getOnItemViewSelectedListener().onItemSelected( 4993a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout ibh.mHolder, ibh.mItem, rowViewHolder, rowViewHolder.mRow); 5003173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 5013173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 5023173fdc69a928880a271036570c235f874b86f65butterfield@google.com } else { 50347520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 50447520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mHoverCardViewSwitcher.unselect(); 50547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 5060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu if (fireEvent && rowViewHolder.getOnItemViewSelectedListener() != null) { 5073a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout rowViewHolder.getOnItemViewSelectedListener().onItemSelected( 5083a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout null, null, rowViewHolder, rowViewHolder.mRow); 5099de363b8db05106b03d115c266859fe200d41db7Dake Gu } 51047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 51147520b68e50572a9775a662410c5aff8300c8784Craig Stout } 51247520b68e50572a9775a662410c5aff8300c8784Craig Stout 5134cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static void initStatics(Context context) { 5144cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (sSelectedRowTopPadding == 0) { 5154cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sSelectedRowTopPadding = context.getResources().getDimensionPixelSize( 5164cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout R.dimen.lb_browse_selected_row_top_padding); 5174cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sExpandedSelectedRowTopPadding = context.getResources().getDimensionPixelSize( 5184cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout R.dimen.lb_browse_expanded_selected_row_top_padding); 5194cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sExpandedRowNoHovercardBottomPadding = context.getResources().getDimensionPixelSize( 5204cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout R.dimen.lb_browse_expanded_row_no_hovercard_bottom_padding); 5214cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5224cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5234cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 5244cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private int getSpaceUnderBaseline(ListRowPresenter.ViewHolder vh) { 5254cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout RowHeaderPresenter.ViewHolder headerViewHolder = vh.getHeaderViewHolder(); 5264cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (headerViewHolder != null) { 5274cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (getHeaderPresenter() != null) { 5284cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return getHeaderPresenter().getSpaceUnderBaseline(headerViewHolder); 5294cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5304cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return headerViewHolder.view.getPaddingBottom(); 5314cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5324cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return 0; 5334cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5344cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 5354cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private void setVerticalPadding(ListRowPresenter.ViewHolder vh) { 5364cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout int paddingTop, paddingBottom; 5373146269a82645438b55a41c679047e3be36e65dfCraig Stout // Note: sufficient bottom padding needed for card shadows. 5384cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (vh.isExpanded()) { 5394cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout int headerSpaceUnderBaseline = getSpaceUnderBaseline(vh); 5404cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (DEBUG) Log.v(TAG, "headerSpaceUnderBaseline " + headerSpaceUnderBaseline); 5414cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout paddingTop = (vh.isSelected() ? sExpandedSelectedRowTopPadding : vh.mPaddingTop) - 5424cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout headerSpaceUnderBaseline; 5434cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout paddingBottom = mHoverCardPresenterSelector == null ? 5444cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sExpandedRowNoHovercardBottomPadding : vh.mPaddingBottom; 5454cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } else if (vh.isSelected()) { 5463146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingTop = sSelectedRowTopPadding - vh.mPaddingBottom; 5473146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingBottom = sSelectedRowTopPadding; 5484cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } else { 5493146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingTop = 0; 5503146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingBottom = vh.mPaddingBottom; 5514cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5524cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout vh.getGridView().setPadding(vh.mPaddingLeft, paddingTop, vh.mPaddingRight, 5534cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout paddingBottom); 5544cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 5554cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 55647520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 55747520b68e50572a9775a662410c5aff8300c8784Craig Stout protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { 5584cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout initStatics(parent.getContext()); 559cb13a318e577e14461eb008071dddf762847de42Dake Gu ListRowView rowView = new ListRowView(parent.getContext()); 5609240e796bc63422c28f2707840bd99c48573279bDake Gu setupFadingEffect(rowView); 561f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout if (mRowHeight != 0) { 562a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn rowView.getGridView().setRowHeight(mRowHeight); 563a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 56447520b68e50572a9775a662410c5aff8300c8784Craig Stout return new ViewHolder(rowView, rowView.getGridView(), this); 56547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 56647520b68e50572a9775a662410c5aff8300c8784Craig Stout 567cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield /** 568cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield * Dispatch item selected event using current selected item in the {@link HorizontalGridView}. 569cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield * The method should only be called from onRowViewSelected(). 570cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield */ 571cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield @Override 572cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield protected void dispatchItemSelectedListener(RowPresenter.ViewHolder holder, boolean selected) { 573cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield ViewHolder vh = (ViewHolder)holder; 574cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield ItemBridgeAdapter.ViewHolder itemViewHolder = (ItemBridgeAdapter.ViewHolder) 575cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield vh.mGridView.findViewHolderForPosition(vh.mGridView.getSelectedPosition()); 576cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield if (itemViewHolder == null) { 577cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield super.dispatchItemSelectedListener(holder, selected); 578cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield return; 579cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 580cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield 581cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield if (selected) { 5823a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout if (holder.getOnItemViewSelectedListener() != null) { 5833a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout holder.getOnItemViewSelectedListener().onItemSelected( 584cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield itemViewHolder.getViewHolder(), itemViewHolder.mItem, vh, vh.getRow()); 585cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 586cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 587cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 588cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield 58947520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 59047520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void onRowViewSelected(RowPresenter.ViewHolder holder, boolean selected) { 5912f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu super.onRowViewSelected(holder, selected); 5924cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout ViewHolder vh = (ViewHolder) holder; 5934cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout setVerticalPadding(vh); 5944cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout updateFooterViewSwitcher(vh); 59547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 59647520b68e50572a9775a662410c5aff8300c8784Craig Stout 59747520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 59847520b68e50572a9775a662410c5aff8300c8784Craig Stout * Show or hide hover card when row selection or expanded state is changed. 59947520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 60047520b68e50572a9775a662410c5aff8300c8784Craig Stout private void updateFooterViewSwitcher(ViewHolder vh) { 60147520b68e50572a9775a662410c5aff8300c8784Craig Stout if (vh.mExpanded && vh.mSelected) { 60247520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 60347520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mHoverCardViewSwitcher.init((ViewGroup) vh.view, 60447520b68e50572a9775a662410c5aff8300c8784Craig Stout mHoverCardPresenterSelector); 60547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 60602e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 60702e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu vh.mGridView.findViewHolderForPosition( 60802e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu vh.mGridView.getSelectedPosition()); 6090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu selectChildView(vh, ibh == null ? null : ibh.itemView, false); 61047520b68e50572a9775a662410c5aff8300c8784Craig Stout } else { 61147520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 6122f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu vh.mHoverCardViewSwitcher.unselect(); 61347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 61447520b68e50572a9775a662410c5aff8300c8784Craig Stout } 61547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 61647520b68e50572a9775a662410c5aff8300c8784Craig Stout 6179240e796bc63422c28f2707840bd99c48573279bDake Gu private void setupFadingEffect(ListRowView rowView) { 6189240e796bc63422c28f2707840bd99c48573279bDake Gu // content is completely faded at 1/2 padding of left, fading length is 1/2 of padding. 6199240e796bc63422c28f2707840bd99c48573279bDake Gu HorizontalGridView gridView = rowView.getGridView(); 6209240e796bc63422c28f2707840bd99c48573279bDake Gu if (mBrowseRowsFadingEdgeLength < 0) { 6219240e796bc63422c28f2707840bd99c48573279bDake Gu TypedArray ta = gridView.getContext() 6229240e796bc63422c28f2707840bd99c48573279bDake Gu .obtainStyledAttributes(R.styleable.LeanbackTheme); 6239240e796bc63422c28f2707840bd99c48573279bDake Gu mBrowseRowsFadingEdgeLength = (int) ta.getDimension( 6249240e796bc63422c28f2707840bd99c48573279bDake Gu R.styleable.LeanbackTheme_browseRowsFadingEdgeLength, 0); 6259240e796bc63422c28f2707840bd99c48573279bDake Gu ta.recycle(); 62647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 6279240e796bc63422c28f2707840bd99c48573279bDake Gu gridView.setFadingLeftEdgeLength(mBrowseRowsFadingEdgeLength); 62847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 62947520b68e50572a9775a662410c5aff8300c8784Craig Stout 63047520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 63147520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) { 63247520b68e50572a9775a662410c5aff8300c8784Craig Stout super.onRowViewExpanded(holder, expanded); 63347520b68e50572a9775a662410c5aff8300c8784Craig Stout ViewHolder vh = (ViewHolder) holder; 634a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn if (getRowHeight() != getExpandedRowHeight()) { 635a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn int newHeight = expanded ? getExpandedRowHeight() : getRowHeight(); 636a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn vh.getGridView().setRowHeight(newHeight); 637a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 6384cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout setVerticalPadding(vh); 63947520b68e50572a9775a662410c5aff8300c8784Craig Stout updateFooterViewSwitcher(vh); 64047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 64147520b68e50572a9775a662410c5aff8300c8784Craig Stout 64247520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 643cb13a318e577e14461eb008071dddf762847de42Dake Gu protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) { 644cb13a318e577e14461eb008071dddf762847de42Dake Gu super.onBindRowViewHolder(holder, item); 645cb13a318e577e14461eb008071dddf762847de42Dake Gu ViewHolder vh = (ViewHolder) holder; 64647520b68e50572a9775a662410c5aff8300c8784Craig Stout ListRow rowItem = (ListRow) item; 64747520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mItemBridgeAdapter.setAdapter(rowItem.getAdapter()); 64847520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mGridView.setAdapter(vh.mItemBridgeAdapter); 649ac30644710e427c77b9d1f20ae385590bdac6c60Dake Gu vh.mGridView.setContentDescription(rowItem.getContentDescription()); 65047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 65147520b68e50572a9775a662410c5aff8300c8784Craig Stout 65247520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 653cb13a318e577e14461eb008071dddf762847de42Dake Gu protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) { 6545358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout ViewHolder vh = (ViewHolder) holder; 6555358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout vh.mGridView.setAdapter(null); 6565358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout vh.mItemBridgeAdapter.clear(); 657cb13a318e577e14461eb008071dddf762847de42Dake Gu super.onUnbindRowViewHolder(holder); 65847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 65947520b68e50572a9775a662410c5aff8300c8784Craig Stout 660cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 661cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * ListRowPresenter overrides the default select effect of {@link RowPresenter} 662cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * and return false. 663cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 664cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu @Override 665cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public final boolean isUsingDefaultSelectEffect() { 666cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return false; 667cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 668cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 669cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 670cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Returns true so that default select effect is applied to each individual 671cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * child of {@link HorizontalGridView}. Subclass may return false to disable 672cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * the default implementation. 673cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * @see #onSelectLevelChanged(RowPresenter.ViewHolder) 674cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 675cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public boolean isUsingDefaultListSelectEffect() { 676cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return true; 677cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 678cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 679cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 680dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * Returns true if SDK >= 18, where default shadow 681892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * is applied to each individual child of {@link HorizontalGridView}. 682892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Subclass may return false to disable. 683892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 684892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public boolean isUsingDefaultShadow() { 685254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu return ShadowOverlayHelper.supportsShadow(); 686892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 687892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 688892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 6890fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled 6900fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu * on each child of horizontal list. If subclass returns false in isUsingDefaultShadow() 6910fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false. 6920fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu */ 693f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout public boolean isUsingZOrder(Context context) { 694254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu return !Settings.getInstance(context).preferStaticShadows(); 6950fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu } 6960fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu 6970fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu /** 698a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Enables or disables child shadow. 699892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * This is not only for enable/disable default shadow implementation but also subclass must 700892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * respect this flag. 701892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 702892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public final void setShadowEnabled(boolean enabled) { 703892181367d658f347d00ea5e091aa31f086b2a20Dake Gu mShadowEnabled = enabled; 704892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 705892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 706892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 707892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Returns true if child shadow is enabled. 708892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * This is not only for enable/disable default shadow implementation but also subclass must 709892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * respect this flag. 710892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 711892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public final boolean getShadowEnabled() { 712892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return mShadowEnabled; 713892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 714892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 7154f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout /** 7164f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout * Enables or disabled rounded corners on children of this row. 7174f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout * Supported on Android SDK >= L. 7184f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout */ 7194f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout public final void enableChildRoundedCorners(boolean enable) { 7204f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout mRoundedCornersEnabled = enable; 7214f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout } 7224f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout 7234f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout /** 7244f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout * Returns true if rounded corners are enabled for children of this row. 7254f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout */ 7264f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout public final boolean areChildRoundedCornersEnabled() { 7274f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout return mRoundedCornersEnabled; 7284f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout } 7294f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout 730892181367d658f347d00ea5e091aa31f086b2a20Dake Gu final boolean needsDefaultShadow() { 731892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return isUsingDefaultShadow() && getShadowEnabled(); 732892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 733892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 73485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu /** 73585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * When ListRowPresenter applies overlay color on the child, it may change child's foreground 73685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * Drawable. If application uses child's foreground for other purposes such as ripple effect, 73785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * it needs tell ListRowPresenter to keep the child's foreground. The default value is true. 73885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * 73985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * @param keep true if keep foreground of child of this row, false ListRowPresenter might change 74085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * the foreground of the child. 74185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu */ 74285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu public final void setKeepChildForeground(boolean keep) { 74385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu mKeepChildForeground = keep; 74485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu } 74585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu 74685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu /** 747ce4c2014042fe6e4723bab30741039848adcf4beDake Gu * Returns true if keeps foreground of child of this row, false otherwise. When 748ce4c2014042fe6e4723bab30741039848adcf4beDake Gu * ListRowPresenter applies overlay color on the child, it may change child's foreground 749ce4c2014042fe6e4723bab30741039848adcf4beDake Gu * Drawable. If application uses child's foreground for other purposes such as ripple effect, 750ce4c2014042fe6e4723bab30741039848adcf4beDake Gu * it needs tell ListRowPresenter to keep the child's foreground. The default value is true. 75185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * 75285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * @return true if keeps foreground of child of this row, false otherwise. 75385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu */ 75485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu public final boolean isKeepChildForeground() { 75585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu return mKeepChildForeground; 75685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu } 75785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu 75885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu /** 75985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * Create ShadowOverlayHelper Options. Subclass may override. 76085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * e.g. 76185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * <code> 76285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * return new ShadowOverlayHelper.Options().roundedCornerRadius(10); 76385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * </code> 76485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * 76585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * @return The options to be used for shadow, overlay and rouded corner. 76685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu */ 76785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu protected ShadowOverlayHelper.Options createShadowOverlayOptions() { 76885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu return ShadowOverlayHelper.Options.DEFAULT; 769892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 770892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 771892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 772cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Applies select level to header and draw a default color dim over each child 773cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * of {@link HorizontalGridView}. 774cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * <p> 775cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Subclass may override this method. A subclass 776cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * needs to call super.onSelectLevelChanged() for applying header select level 777cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * and optionally applying a default select level to each child view of 778cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * {@link HorizontalGridView} if {@link #isUsingDefaultListSelectEffect()} 779cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * is true. Subclass may override {@link #isUsingDefaultListSelectEffect()} to return 780cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * false and deal with the individual item select level by itself. 781cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * </p> 782cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 783cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu @Override 784cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) { 785cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu super.onSelectLevelChanged(holder); 786254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu if (mShadowOverlayHelper != null && mShadowOverlayHelper.needsOverlay()) { 787cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu ViewHolder vh = (ViewHolder) holder; 788892181367d658f347d00ea5e091aa31f086b2a20Dake Gu int dimmedColor = vh.mColorDimmer.getPaint().getColor(); 78985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu for (int i = 0, count = vh.mGridView.getChildCount(); i < count; i++) { 79085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu mShadowOverlayHelper.setOverlayColor(vh.mGridView.getChildAt(i), dimmedColor); 791cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 7929240e796bc63422c28f2707840bd99c48573279bDake Gu if (vh.mGridView.getFadingLeftEdge()) { 7939240e796bc63422c28f2707840bd99c48573279bDake Gu vh.mGridView.invalidate(); 7949240e796bc63422c28f2707840bd99c48573279bDake Gu } 795cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 796cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 797cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 798709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu @Override 799709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu public void freeze(RowPresenter.ViewHolder holder, boolean freeze) { 800709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu ViewHolder vh = (ViewHolder) holder; 801709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu vh.mGridView.setScrollEnabled(!freeze); 802709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu } 803709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu 804c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 8053f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu public void setEntranceTransitionState(RowPresenter.ViewHolder holder, 8063f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu boolean afterEntrance) { 8073f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu super.setEntranceTransitionState(holder, afterEntrance); 808c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu ((ViewHolder) holder).mGridView.setChildrenVisibility( 8093f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu afterEntrance? View.VISIBLE : View.INVISIBLE); 810c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 81147520b68e50572a9775a662410c5aff8300c8784Craig Stout} 812