DetailsOverviewRowPresenter.java revision 37eb0e53ba5363bbe15314c7d19d4b2d6024a5aa
1a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn/*
2a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * Copyright (C) 2014 The Android Open Source Project
3a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn *
4a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * in compliance with the License. You may obtain a copy of the License at
6a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn *
7a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * http://www.apache.org/licenses/LICENSE-2.0
8a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn *
9a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * Unless required by applicable law or agreed to in writing, software distributed under the License
10a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * or implied. See the License for the specific language governing permissions and limitations under
12a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * the License.
13a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn */
14a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournpackage android.support.v17.leanback.widget;
15a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
164121f22713bbed467a977ec0d867ef53989ff374Dake Guimport android.app.Activity;
17d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stoutimport android.content.Context;
18e23ea69ec54eb70d17239ba671fcd75563780553Craig Stoutimport android.graphics.Bitmap;
19d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stoutimport android.graphics.Color;
207728d53c5c50e8ed807e8f4a189e34684de04800Craig Stoutimport android.graphics.drawable.Drawable;
21e23ea69ec54eb70d17239ba671fcd75563780553Craig Stoutimport android.graphics.drawable.BitmapDrawable;
22a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.support.v17.leanback.R;
232e0c922430f8c285b4325da52d69c09451069c93Craig Stoutimport android.support.v7.widget.RecyclerView;
242e0c922430f8c285b4325da52d69c09451069c93Craig Stoutimport android.util.Log;
25d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stoutimport android.util.TypedValue;
26a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.view.LayoutInflater;
27a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.view.View;
28a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.view.ViewGroup;
29a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.widget.FrameLayout;
30a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.widget.ImageView;
31a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
32a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport java.util.Collection;
33a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
34a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn/**
3580d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn * A DetailsOverviewRowPresenter renders a {@link DetailsOverviewRow} to display an
36a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn * overview of an item. Typically this row will be the first row in a fragment
3780d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn * such as the {@link android.support.v17.leanback.app.DetailsFragment
3818c8048f17940359b8bce99cb46d24337bff8997Dake Gu * DetailsFragment}.  View created by DetailsOverviewRowPresenter is made in three parts:
3918c8048f17940359b8bce99cb46d24337bff8997Dake Gu * ImageView on the left, action list view on the bottom and a customizable detailed
4018c8048f17940359b8bce99cb46d24337bff8997Dake Gu * description view on the right.
41a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn *
4218c8048f17940359b8bce99cb46d24337bff8997Dake Gu * <p>The detailed description is rendered using a {@link Presenter} passed in
4318c8048f17940359b8bce99cb46d24337bff8997Dake Gu * {@link #DetailsOverviewRowPresenter(Presenter)}.  User can access detailed description
4418c8048f17940359b8bce99cb46d24337bff8997Dake Gu * ViewHolder from {@link ViewHolder#mDetailsDescriptionViewHolder}.
4518c8048f17940359b8bce99cb46d24337bff8997Dake Gu * </p>
4618c8048f17940359b8bce99cb46d24337bff8997Dake Gu *
4718c8048f17940359b8bce99cb46d24337bff8997Dake Gu * <p>
4818c8048f17940359b8bce99cb46d24337bff8997Dake Gu * To participate in activity transition, call {@link #setSharedElementEnterTransition(Activity,
4918c8048f17940359b8bce99cb46d24337bff8997Dake Gu * String)} during Activity's onCreate().
5018c8048f17940359b8bce99cb46d24337bff8997Dake Gu * </p>
5118c8048f17940359b8bce99cb46d24337bff8997Dake Gu *
5218c8048f17940359b8bce99cb46d24337bff8997Dake Gu * <p>
5318c8048f17940359b8bce99cb46d24337bff8997Dake Gu * Because transition support and layout are fully controlled by DetailsOverviewRowPresenter,
5418c8048f17940359b8bce99cb46d24337bff8997Dake Gu * developer can not override DetailsOverviewRowPresenter.ViewHolder for adding/replacing views
5518c8048f17940359b8bce99cb46d24337bff8997Dake Gu * of DetailsOverviewRowPresenter.  If developer wants more customization beyond replacing
5618c8048f17940359b8bce99cb46d24337bff8997Dake Gu * detailed description , he/she should write a new presenter class for row object.
5718c8048f17940359b8bce99cb46d24337bff8997Dake Gu * </p>
58a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn */
59a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournpublic class DetailsOverviewRowPresenter extends RowPresenter {
60a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
61a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    private static final String TAG = "DetailsOverviewRowPresenter";
62a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    private static final boolean DEBUG = false;
63a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
642e0c922430f8c285b4325da52d69c09451069c93Craig Stout    private static final int MORE_ACTIONS_FADE_MS = 100;
652e0c922430f8c285b4325da52d69c09451069c93Craig Stout
6680d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn    /**
6780d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * A ViewHolder for the DetailsOverviewRow.
6880d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     */
69cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    public final class ViewHolder extends RowPresenter.ViewHolder {
70b34a2372153298ebdc3e148e1c1f3b3924efab08Dake Gu        final ViewGroup mOverviewView;
71a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        final ImageView mImageView;
724121f22713bbed467a977ec0d867ef53989ff374Dake Gu        final ViewGroup mRightPanel;
73a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        final FrameLayout mDetailsDescriptionFrame;
74a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        final HorizontalGridView mActionsRow;
7518c8048f17940359b8bce99cb46d24337bff8997Dake Gu        public final Presenter.ViewHolder mDetailsDescriptionViewHolder;
7683118b72d02074ee35f07ad0253579565c16882bCraig Stout        int mNumItems;
7783118b72d02074ee35f07ad0253579565c16882bCraig Stout        boolean mShowMoreRight;
7883118b72d02074ee35f07ad0253579565c16882bCraig Stout        boolean mShowMoreLeft;
79cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        final ItemBridgeAdapter mActionBridgeAdapter = new ItemBridgeAdapter();
80a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
81cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        void bind(ObjectAdapter adapter) {
82cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            mActionBridgeAdapter.setAdapter(adapter);
8337eb0e53ba5363bbe15314c7d19d4b2d6024a5aaDake Gu            mActionsRow.setAdapter(mActionBridgeAdapter);
84cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            mNumItems = mActionBridgeAdapter.getItemCount();
852e0c922430f8c285b4325da52d69c09451069c93Craig Stout
8683118b72d02074ee35f07ad0253579565c16882bCraig Stout            mShowMoreRight = false;
8783118b72d02074ee35f07ad0253579565c16882bCraig Stout            mShowMoreLeft = true;
8883118b72d02074ee35f07ad0253579565c16882bCraig Stout            showMoreLeft(false);
8983118b72d02074ee35f07ad0253579565c16882bCraig Stout        }
9083118b72d02074ee35f07ad0253579565c16882bCraig Stout
91819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout        final View.OnLayoutChangeListener mLayoutChangeListener =
92819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                new View.OnLayoutChangeListener() {
93819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout
94819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout            @Override
95819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout            public void onLayoutChange(View v, int left, int top, int right,
96819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                    int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
97819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                if (DEBUG) Log.v(TAG, "onLayoutChange " + v);
98819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                checkFirstAndLastPosition(false);
99819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout            }
100819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout        };
101819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout
102cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        final OnChildSelectedListener mChildSelectedListener = new OnChildSelectedListener() {
103cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            @Override
104cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
105cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                dispatchItemSelection(view);
106cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
107cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        };
108cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
109cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        void dispatchItemSelection(View view) {
110cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            if (!isSelected()) {
111cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                return;
112cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
113cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder) (view != null ?
114cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    mActionsRow.getChildViewHolder(view) :
115cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    mActionsRow.findViewHolderForPosition(mActionsRow.getSelectedPosition()));
116cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            if (ibvh == null) {
117cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemSelectedListener() != null) {
118cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    getOnItemSelectedListener().onItemSelected(null, getRow());
119cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
120cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemViewSelectedListener() != null) {
121cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    getOnItemViewSelectedListener().onItemSelected(null, null,
122cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            ViewHolder.this, getRow());
123cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
124cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            } else {
125cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemSelectedListener() != null) {
126cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    getOnItemSelectedListener().onItemSelected(ibvh.getItem(), getRow());
127cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
128cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemViewSelectedListener() != null) {
129cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    getOnItemViewSelectedListener().onItemSelected(ibvh.getViewHolder(), ibvh.getItem(),
130cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            ViewHolder.this, getRow());
131cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
132cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
133cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        };
134cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
13583118b72d02074ee35f07ad0253579565c16882bCraig Stout        final ItemBridgeAdapter.AdapterListener mAdapterListener =
13683118b72d02074ee35f07ad0253579565c16882bCraig Stout                new ItemBridgeAdapter.AdapterListener() {
1372e0c922430f8c285b4325da52d69c09451069c93Craig Stout
13883118b72d02074ee35f07ad0253579565c16882bCraig Stout            @Override
139cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            public void onBind(final ItemBridgeAdapter.ViewHolder ibvh) {
140cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemViewClickedListener() != null || getOnItemClickedListener() != null
141cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                        || mActionClickedListener != null) {
142cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    ibvh.getPresenter().setOnClickListener(
143cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            ibvh.getViewHolder(), new View.OnClickListener() {
144cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                @Override
145cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                public void onClick(View v) {
146cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    if (getOnItemViewClickedListener() != null) {
147cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                        getOnItemViewClickedListener().onItemClicked(ibvh.getViewHolder(),
148cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                                ibvh.getItem(), ViewHolder.this, getRow());
149cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    }
150cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    if (mActionClickedListener != null) {
151cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                        mActionClickedListener.onActionClicked((Action) ibvh.getItem());
152cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    }
153cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                }
154cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            });
155cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
156cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
157cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            @Override
158cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            public void onUnbind(final ItemBridgeAdapter.ViewHolder ibvh) {
159cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemViewClickedListener() != null || getOnItemClickedListener() != null
160cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                        || mActionClickedListener != null) {
161cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    ibvh.getPresenter().setOnClickListener(ibvh.getViewHolder(), null);
162cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
163cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
164cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            @Override
16583118b72d02074ee35f07ad0253579565c16882bCraig Stout            public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
166819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                // Remove first to ensure we don't add ourselves more than once.
167819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                viewHolder.itemView.removeOnLayoutChangeListener(mLayoutChangeListener);
168819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                viewHolder.itemView.addOnLayoutChangeListener(mLayoutChangeListener);
16983118b72d02074ee35f07ad0253579565c16882bCraig Stout            }
17083118b72d02074ee35f07ad0253579565c16882bCraig Stout            @Override
17183118b72d02074ee35f07ad0253579565c16882bCraig Stout            public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
172819b4e55bcf37847548a55c5dac0dfa8323975f6Craig Stout                viewHolder.itemView.removeOnLayoutChangeListener(mLayoutChangeListener);
17383118b72d02074ee35f07ad0253579565c16882bCraig Stout                checkFirstAndLastPosition(false);
1742e0c922430f8c285b4325da52d69c09451069c93Craig Stout            }
17583118b72d02074ee35f07ad0253579565c16882bCraig Stout        };
17683118b72d02074ee35f07ad0253579565c16882bCraig Stout
17783118b72d02074ee35f07ad0253579565c16882bCraig Stout        final RecyclerView.OnScrollListener mScrollListener =
17883118b72d02074ee35f07ad0253579565c16882bCraig Stout                new RecyclerView.OnScrollListener() {
1792e0c922430f8c285b4325da52d69c09451069c93Craig Stout
1802e0c922430f8c285b4325da52d69c09451069c93Craig Stout            @Override
181cef7b4942bacc862ea4eac66952e9f7aba027d18Yigit Boyar            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
1822e0c922430f8c285b4325da52d69c09451069c93Craig Stout            }
1832e0c922430f8c285b4325da52d69c09451069c93Craig Stout            @Override
184cef7b4942bacc862ea4eac66952e9f7aba027d18Yigit Boyar            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
18583118b72d02074ee35f07ad0253579565c16882bCraig Stout                checkFirstAndLastPosition(true);
1862e0c922430f8c285b4325da52d69c09451069c93Craig Stout            }
18783118b72d02074ee35f07ad0253579565c16882bCraig Stout        };
18883118b72d02074ee35f07ad0253579565c16882bCraig Stout
18983118b72d02074ee35f07ad0253579565c16882bCraig Stout        private int getViewCenter(View view) {
19083118b72d02074ee35f07ad0253579565c16882bCraig Stout            return (view.getRight() - view.getLeft()) / 2;
19183118b72d02074ee35f07ad0253579565c16882bCraig Stout        }
19283118b72d02074ee35f07ad0253579565c16882bCraig Stout
19383118b72d02074ee35f07ad0253579565c16882bCraig Stout        private void checkFirstAndLastPosition(boolean fromScroll) {
19483118b72d02074ee35f07ad0253579565c16882bCraig Stout            RecyclerView.ViewHolder viewHolder;
1952e0c922430f8c285b4325da52d69c09451069c93Craig Stout
19683118b72d02074ee35f07ad0253579565c16882bCraig Stout            viewHolder = mActionsRow.findViewHolderForPosition(mNumItems - 1);
19783118b72d02074ee35f07ad0253579565c16882bCraig Stout            boolean showRight = (viewHolder == null ||
19883118b72d02074ee35f07ad0253579565c16882bCraig Stout                    viewHolder.itemView.getRight() > mActionsRow.getWidth());
19983118b72d02074ee35f07ad0253579565c16882bCraig Stout
20083118b72d02074ee35f07ad0253579565c16882bCraig Stout            viewHolder = mActionsRow.findViewHolderForPosition(0);
20183118b72d02074ee35f07ad0253579565c16882bCraig Stout            boolean showLeft = (viewHolder == null || viewHolder.itemView.getLeft() < 0);
20283118b72d02074ee35f07ad0253579565c16882bCraig Stout
20383118b72d02074ee35f07ad0253579565c16882bCraig Stout            if (DEBUG) Log.v(TAG, "checkFirstAndLast fromScroll " + fromScroll +
20483118b72d02074ee35f07ad0253579565c16882bCraig Stout                    " showRight " + showRight + " showLeft " + showLeft);
20583118b72d02074ee35f07ad0253579565c16882bCraig Stout
20683118b72d02074ee35f07ad0253579565c16882bCraig Stout            showMoreRight(showRight);
20783118b72d02074ee35f07ad0253579565c16882bCraig Stout            showMoreLeft(showLeft);
20883118b72d02074ee35f07ad0253579565c16882bCraig Stout        }
20983118b72d02074ee35f07ad0253579565c16882bCraig Stout
21083118b72d02074ee35f07ad0253579565c16882bCraig Stout        private void showMoreLeft(boolean show) {
21183118b72d02074ee35f07ad0253579565c16882bCraig Stout            if (show != mShowMoreLeft) {
21283118b72d02074ee35f07ad0253579565c16882bCraig Stout                mActionsRow.setFadingLeftEdge(show);
21383118b72d02074ee35f07ad0253579565c16882bCraig Stout                mShowMoreLeft = show;
2142e0c922430f8c285b4325da52d69c09451069c93Craig Stout            }
21583118b72d02074ee35f07ad0253579565c16882bCraig Stout        }
2162e0c922430f8c285b4325da52d69c09451069c93Craig Stout
21783118b72d02074ee35f07ad0253579565c16882bCraig Stout        private void showMoreRight(boolean show) {
21883118b72d02074ee35f07ad0253579565c16882bCraig Stout            if (show != mShowMoreRight) {
21983118b72d02074ee35f07ad0253579565c16882bCraig Stout                mActionsRow.setFadingRightEdge(show);
22083118b72d02074ee35f07ad0253579565c16882bCraig Stout                mShowMoreRight = show;
2212e0c922430f8c285b4325da52d69c09451069c93Craig Stout            }
2222e0c922430f8c285b4325da52d69c09451069c93Craig Stout        }
2232e0c922430f8c285b4325da52d69c09451069c93Craig Stout
22480d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn        /**
22580d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn         * Constructor for the ViewHolder.
22680d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn         *
22780d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn         * @param rootView The root View that this view holder will be attached
22880d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn         *        to.
22980d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn         */
23018c8048f17940359b8bce99cb46d24337bff8997Dake Gu        public ViewHolder(View rootView, Presenter detailsPresenter) {
231a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            super(rootView);
232b34a2372153298ebdc3e148e1c1f3b3924efab08Dake Gu            mOverviewView = (ViewGroup) rootView.findViewById(R.id.details_overview);
233a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            mImageView = (ImageView) rootView.findViewById(R.id.details_overview_image);
2344121f22713bbed467a977ec0d867ef53989ff374Dake Gu            mRightPanel = (ViewGroup) rootView.findViewById(R.id.details_overview_right_panel);
235a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            mDetailsDescriptionFrame =
2364121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    (FrameLayout) mRightPanel.findViewById(R.id.details_overview_description);
23770c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn            mActionsRow =
2384121f22713bbed467a977ec0d867ef53989ff374Dake Gu                    (HorizontalGridView) mRightPanel.findViewById(R.id.details_overview_actions);
2392e0c922430f8c285b4325da52d69c09451069c93Craig Stout            mActionsRow.setOnScrollListener(mScrollListener);
240cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            mActionsRow.setAdapter(mActionBridgeAdapter);
241cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            mActionsRow.setOnChildSelectedListener(mChildSelectedListener);
2422e0c922430f8c285b4325da52d69c09451069c93Craig Stout
2432e0c922430f8c285b4325da52d69c09451069c93Craig Stout            final int fadeLength = rootView.getResources().getDimensionPixelSize(
2442e0c922430f8c285b4325da52d69c09451069c93Craig Stout                    R.dimen.lb_details_overview_actions_fade_size);
2452e0c922430f8c285b4325da52d69c09451069c93Craig Stout            mActionsRow.setFadingRightEdgeLength(fadeLength);
2462e0c922430f8c285b4325da52d69c09451069c93Craig Stout            mActionsRow.setFadingLeftEdgeLength(fadeLength);
24718c8048f17940359b8bce99cb46d24337bff8997Dake Gu            mDetailsDescriptionViewHolder =
24818c8048f17940359b8bce99cb46d24337bff8997Dake Gu                    detailsPresenter.onCreateViewHolder(mDetailsDescriptionFrame);
24918c8048f17940359b8bce99cb46d24337bff8997Dake Gu            mDetailsDescriptionFrame.addView(mDetailsDescriptionViewHolder.view);
250cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
251cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            mActionBridgeAdapter.setAdapterListener(mAdapterListener);
252a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        }
253a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
254a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
255c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout    private static float sShadowZ;
256c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout
257a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    private final Presenter mDetailsPresenter;
25870c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    private final ActionPresenterSelector mActionPresenterSelector;
259cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    private OnActionClickedListener mActionClickedListener;
260cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
261d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    private int mBackgroundColor = Color.TRANSPARENT;
262d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    private boolean mBackgroundColorSet;
263d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    private boolean mIsStyleLarge = true;
264a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
2654121f22713bbed467a977ec0d867ef53989ff374Dake Gu    private DetailsOverviewSharedElementHelper mSharedElementHelper;
2664121f22713bbed467a977ec0d867ef53989ff374Dake Gu
267a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    /**
26880d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * Constructor for a DetailsOverviewRowPresenter.
26980d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     *
27080d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * @param detailsPresenter The {@link Presenter} used to render the detailed
27180d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     *        description of the row.
272a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn     */
273a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    public DetailsOverviewRowPresenter(Presenter detailsPresenter) {
274d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        setHeaderPresenter(null);
275a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        setSelectEffectEnabled(false);
276a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        mDetailsPresenter = detailsPresenter;
277e652714f2fcc876de6f168b28dd03bfc22e1cb96Tim Kilbourn        mActionPresenterSelector = new ActionPresenterSelector();
278a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
279a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
28070c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    /**
28180d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * Sets the listener for Action click events.
28270c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn     */
28370c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    public void setOnActionClickedListener(OnActionClickedListener listener) {
284cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mActionClickedListener = listener;
28570c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    }
28670c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn
28770c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    /**
28880d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * Gets the listener for Action click events.
28970c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn     */
29070c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    public OnActionClickedListener getOnActionClickedListener() {
291cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        return mActionClickedListener;
29270c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn    }
29370c858a5ca5b7ed9862e2edfa43912faecf42f96Tim Kilbourn
294d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    /**
29580d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * Sets the background color.  If not set, a default from the theme will be used.
296d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout     */
297d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    public void setBackgroundColor(int color) {
298d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        mBackgroundColor = color;
299d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        mBackgroundColorSet = true;
300d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    }
301d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
302d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    /**
30380d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * Returns the background color.  If no background color was set, transparent
30480d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * is returned.
305d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout     */
306d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    public int getBackgroundColor() {
307d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        return mBackgroundColor;
308d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    }
309d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
310d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    /**
31180d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * Sets the layout style to be large or small. This affects the height of
31280d04d2265fe28800fcbc7e8cc7d6d229a7913d8Tim Kilbourn     * the overview, including the text description. The default is large.
313d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout     */
314d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    public void setStyleLarge(boolean large) {
315d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        mIsStyleLarge = large;
316d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    }
317d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
318d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    /**
319d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout     * Returns true if the layout style is large.
320d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout     */
321d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    public boolean isStyleLarge() {
322d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        return mIsStyleLarge;
323d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    }
324d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
3259de363b8db05106b03d115c266859fe200d41db7Dake Gu    /**
3264121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * Set enter transition of target activity (typically a DetailActivity) to be
3274121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * transiting into overview row created by this presenter.
3284121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * <p>
3294121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * It assumes shared element passed from calling activity is an ImageView;
3304121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * the shared element transits to overview image on the left of detail
3314121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * overview row, while bounds of overview row grows and reveals text
3324121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * and buttons on the right.
3334121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * <p>
3344121f22713bbed467a977ec0d867ef53989ff374Dake Gu     * The method must be invoked in target Activity's onCreate().
3359de363b8db05106b03d115c266859fe200d41db7Dake Gu     */
3364121f22713bbed467a977ec0d867ef53989ff374Dake Gu    public final void setSharedElementEnterTransition(Activity activity,
3374121f22713bbed467a977ec0d867ef53989ff374Dake Gu            String sharedElementName) {
3384121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (mSharedElementHelper == null) {
3394121f22713bbed467a977ec0d867ef53989ff374Dake Gu            mSharedElementHelper = new DetailsOverviewSharedElementHelper();
3404121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
3414121f22713bbed467a977ec0d867ef53989ff374Dake Gu        mSharedElementHelper.setSharedElementEnterTransition(activity, sharedElementName);
3429de363b8db05106b03d115c266859fe200d41db7Dake Gu    }
3439de363b8db05106b03d115c266859fe200d41db7Dake Gu
344d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    private int getDefaultBackgroundColor(Context context) {
345d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        TypedValue outValue = new TypedValue();
346056561d81012983d2d27b8665c4aeabb427174cbTim Kilbourn        context.getTheme().resolveAttribute(R.attr.defaultBrandColor, outValue, true);
347d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        return context.getResources().getColor(outValue.resourceId);
348d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    }
349d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
350cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    protected void onRowViewSelected(RowPresenter.ViewHolder vh, boolean selected) {
351cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        super.onRowViewSelected(vh, selected);
352cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        if (selected) {
353cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            ((ViewHolder) vh).dispatchItemSelection(null);
354cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        }
355cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    }
356cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
357a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    @Override
358a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
359a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        View v = LayoutInflater.from(parent.getContext())
360a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            .inflate(R.layout.lb_details_overview, parent, false);
36118c8048f17940359b8bce99cb46d24337bff8997Dake Gu        ViewHolder vh = new ViewHolder(v, mDetailsPresenter);
362a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
36350ea3557b75826b3f51480715df1973472e345c4Craig Stout        initDetailsOverview(vh);
364d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
365a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        return vh;
366a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
367a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
368e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout    private int getCardHeight(Context context) {
369d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout        int resId = mIsStyleLarge ? R.dimen.lb_details_overview_height_large :
370d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout            R.dimen.lb_details_overview_height_small;
371e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        return context.getResources().getDimensionPixelSize(resId);
372e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout    }
373d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
374e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout    private void initDetailsOverview(ViewHolder vh) {
3754f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        final View overview = vh.mOverviewView;
37650ea3557b75826b3f51480715df1973472e345c4Craig Stout        ViewGroup.LayoutParams lp = overview.getLayoutParams();
377e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        lp.height = getCardHeight(overview.getContext());
37850ea3557b75826b3f51480715df1973472e345c4Craig Stout        overview.setLayoutParams(lp);
379d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
380c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout        if (sShadowZ == 0) {
381c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout            sShadowZ = overview.getResources().getDimensionPixelSize(
382c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout                    R.dimen.lb_details_overview_z);
383c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout        }
384c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout        ShadowHelper.getInstance().setZ(overview, sShadowZ);
385d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout    }
386d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1Craig Stout
3877728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout    private static int getNonNegativeWidth(Drawable drawable) {
3887728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        final int width = (drawable == null) ? 0 : drawable.getIntrinsicWidth();
3897728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        return (width > 0 ? width : 0);
3907728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout    }
3917728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout
3927728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout    private static int getNonNegativeHeight(Drawable drawable) {
3937728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        final int height = (drawable == null) ? 0 : drawable.getIntrinsicHeight();
3947728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        return (height > 0 ? height : 0);
3957728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout    }
3967728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout
397a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    @Override
398cb13a318e577e14461eb008071dddf762847de42Dake Gu    protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) {
399cb13a318e577e14461eb008071dddf762847de42Dake Gu        super.onBindRowViewHolder(holder, item);
400a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
401a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        DetailsOverviewRow row = (DetailsOverviewRow) item;
402a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        ViewHolder vh = (ViewHolder) holder;
403e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout
404e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        ViewGroup.MarginLayoutParams layoutParams =
405e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout                (ViewGroup.MarginLayoutParams) vh.mImageView.getLayoutParams();
406e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        final int cardHeight = getCardHeight(vh.mImageView.getContext());
407e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        final int verticalMargin = vh.mImageView.getResources().getDimensionPixelSize(
408e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout                R.dimen.lb_details_overview_image_margin_vertical);
409e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        final int horizontalMargin = vh.mImageView.getResources().getDimensionPixelSize(
410e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout                R.dimen.lb_details_overview_image_margin_horizontal);
4117728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        final int drawableWidth = getNonNegativeWidth(row.getImageDrawable());
4127728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        final int drawableHeight = getNonNegativeHeight(row.getImageDrawable());
4137728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout
414e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        boolean scaleImage = row.isImageScaleUpAllowed();
415e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        boolean useMargin = false;
416e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout
4177728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout        if (row.getImageDrawable() != null) {
4187728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            boolean landscape = false;
4197728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout
4207728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            // If large style and landscape image we always use margin.
4217728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            if (drawableWidth > drawableHeight) {
4227728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                landscape = true;
4237728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                if (mIsStyleLarge) {
4247728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                    useMargin = true;
4257728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                }
426e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            }
4277728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            // If long dimension bigger than the card height we scale down.
4287728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            if ((landscape && drawableWidth > cardHeight) ||
4297728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                    (!landscape && drawableHeight > cardHeight)) {
430e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout                scaleImage = true;
431e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            }
4327728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            // If we're not scaling to fit the card height then we always use margin.
4337728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            if (!scaleImage) {
4347728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                useMargin = true;
4357728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            }
4367728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            // If using margin than may need to scale down.
4377728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            if (useMargin && !scaleImage) {
4387728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                if (landscape && drawableWidth > cardHeight - horizontalMargin) {
4397728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                    scaleImage = true;
4407728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                } else if (!landscape && drawableHeight > cardHeight - 2 * verticalMargin) {
4417728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                    scaleImage = true;
4427728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout                }
4437728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            }
444e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        }
445e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout
4464f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        final int bgColor = mBackgroundColorSet ? mBackgroundColor :
4474f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout            getDefaultBackgroundColor(vh.mOverviewView.getContext());
4484f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
449e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        if (useMargin) {
450e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            layoutParams.leftMargin = horizontalMargin;
451e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            layoutParams.topMargin = layoutParams.bottomMargin = verticalMargin;
4524f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout            RoundedRectHelper.getInstance().setRoundedRectBackground(vh.mOverviewView, bgColor);
45372a2146f4c3e6dbb84a5f9f92e7ab42d142dab04Dake Gu            vh.mRightPanel.setBackground(null);
454836443f4a3b69eb7a88ffeb65a39e11439dee55eDake Gu            vh.mImageView.setBackground(null);
455e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        } else {
456e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            layoutParams.leftMargin = layoutParams.topMargin = layoutParams.bottomMargin = 0;
4574f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout            vh.mRightPanel.setBackgroundColor(bgColor);
4584f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout            vh.mImageView.setBackgroundColor(bgColor);
4594f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout            RoundedRectHelper.getInstance().setRoundedRectBackground(vh.mOverviewView,
4604f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout                    Color.TRANSPARENT);
461e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        }
462e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        if (scaleImage) {
463e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            vh.mImageView.setScaleType(ImageView.ScaleType.FIT_START);
464e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            vh.mImageView.setAdjustViewBounds(true);
465e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            vh.mImageView.setMaxWidth(cardHeight);
466e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
467e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
468e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        } else {
469e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            vh.mImageView.setScaleType(ImageView.ScaleType.CENTER);
470e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            vh.mImageView.setAdjustViewBounds(false);
471e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
472e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout            // Limit width to the card height
4737728d53c5c50e8ed807e8f4a189e34684de04800Craig Stout            layoutParams.width = Math.min(cardHeight, drawableWidth);
474e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        }
475e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        vh.mImageView.setLayoutParams(layoutParams);
476e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout        vh.mImageView.setImageDrawable(row.getImageDrawable());
477e23ea69ec54eb70d17239ba671fcd75563780553Craig Stout
4787d1196948811bc5f1b7ec0cdc74340fca60fc8e2Craig Stout        mDetailsPresenter.onBindViewHolder(vh.mDetailsDescriptionViewHolder, row.getItem());
479a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
480e652714f2fcc876de6f168b28dd03bfc22e1cb96Tim Kilbourn        ArrayObjectAdapter aoa = new ArrayObjectAdapter(mActionPresenterSelector);
481a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        aoa.addAll(0, (Collection)row.getActions());
482cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.bind(aoa);
4834121f22713bbed467a977ec0d867ef53989ff374Dake Gu
4844121f22713bbed467a977ec0d867ef53989ff374Dake Gu        if (row.getImageDrawable() != null && mSharedElementHelper != null) {
4854121f22713bbed467a977ec0d867ef53989ff374Dake Gu            mSharedElementHelper.onBindToDrawable(vh);
4864121f22713bbed467a977ec0d867ef53989ff374Dake Gu        }
487a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
488a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
489a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    @Override
490cb13a318e577e14461eb008071dddf762847de42Dake Gu    protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) {
491cb13a318e577e14461eb008071dddf762847de42Dake Gu        super.onUnbindRowViewHolder(holder);
492a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
493a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        ViewHolder vh = (ViewHolder) holder;
494a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        if (vh.mDetailsDescriptionViewHolder != null) {
495a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            mDetailsPresenter.onUnbindViewHolder(vh.mDetailsDescriptionViewHolder);
496a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        }
497a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
498a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn}
499