10246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu/*
20246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * Copyright (C) 2014 The Android Open Source Project
30246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
40246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
50246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * in compliance with the License. You may obtain a copy of the License at
60246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
70246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * http://www.apache.org/licenses/LICENSE-2.0
80246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
90246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License
100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * or implied. See the License for the specific language governing permissions and limitations under
120246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * the License.
130246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu */
140246318f27a905a31df5a8af445cfe67d31dfb68Dake Gupackage android.support.v17.leanback.widget;
150246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
160246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.app.Activity;
170246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.content.Context;
180246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.content.res.Resources;
190246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.graphics.Bitmap;
200246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.graphics.Color;
210246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.graphics.Rect;
220246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.graphics.drawable.Drawable;
230246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.graphics.drawable.BitmapDrawable;
240246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.graphics.drawable.ColorDrawable;
250246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.os.Handler;
260246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.support.v17.leanback.R;
270246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.support.v17.leanback.widget.ListRowPresenter.ViewHolder;
280246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.support.v7.widget.RecyclerView;
290246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.util.Log;
300246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.util.TypedValue;
310246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.view.KeyEvent;
320246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.view.LayoutInflater;
330246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.view.View;
340246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.view.ViewGroup;
350246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.view.ViewGroup.MarginLayoutParams;
360246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.widget.FrameLayout;
370246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.widget.ImageView;
380246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
390246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport java.util.Collection;
400246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
410246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu/**
420246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * Renders a {@link DetailsOverviewRow} to display an overview of an item. Typically this row will
430246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * be the first row in a fragment such as the
440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * {@link android.support.v17.leanback.app.DetailsFragment}. The View created by the
450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * FullWidthDetailsOverviewRowPresenter is made in three parts: logo view on the left, action list view on
460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * the top and a customizable detailed description view on the right.
470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * <p>The detailed description is rendered using a {@link Presenter} passed in
490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * {@link #FullWidthDetailsOverviewRowPresenter(Presenter)}. Typically this will be an instance of
500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * {@link AbstractDetailsDescriptionPresenter}. The application can access the detailed description
510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * ViewHolder from {@link ViewHolder#getDetailsDescriptionViewHolder()}.
520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * </p>
530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * <p>The logo view is rendered using a customizable {@link DetailsOverviewLogoPresenter} passed in
550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * {@link #FullWidthDetailsOverviewRowPresenter(Presenter, DetailsOverviewLogoPresenter)}. The application
560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * can access the logo ViewHolder from {@link ViewHolder#getLogoViewHolder()}.
570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * </p>
580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
590246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * <p>
600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * To support activity shared element transition, call {@link #setListener(Listener)} with
610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * {@link FullWidthDetailsOverviewSharedElementHelper} during Activity's onCreate(). Application is free to
620246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * create its own "shared element helper" class using the Listener for image binding.
630246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * Call {@link #setParticipatingEntranceTransition(boolean)} with false
640246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * </p>
650246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu *
660246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * <p>
670246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * The view has three states: {@link #STATE_HALF} {@link #STATE_FULL} and {@link #STATE_SMALL}. See
680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * {@link android.support.v17.leanback.app.DetailsFragment} where it switches states based on
690246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * selected row position.
700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu * </p>
710246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu */
720246318f27a905a31df5a8af445cfe67d31dfb68Dake Gupublic class FullWidthDetailsOverviewRowPresenter extends RowPresenter {
730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private static final String TAG = "FullWidthDetailsOverviewRowPresenter";
750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private static final boolean DEBUG = false;
760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private static Rect sTmpRect = new Rect();
78813de6fe46801f8a01952699d553826a4f5fe116Dake Gu    private static final Handler sHandler = new Handler();
790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
810246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * This is the default state corresponding to layout file.  The view takes full width
820246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * of screen and covers bottom half of the screen.
830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public static final int STATE_HALF = 0;
850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * This is the state when the view covers full width and height of screen.
870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public static final int STATE_FULL = 1;
890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * This is the state where the view shrinks to a small banner.
910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public static final int STATE_SMALL = 2;
930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
95c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * This is the alignment mode that the logo and description align to the starting edge of the
96c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * overview view.
97c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     */
98c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public static final int ALIGN_MODE_START = 0;
99c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    /**
100c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * This is the alignment mode that the ending edge of logo and the starting edge of description
101c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * align to the middle of the overview view. Note that this might not be the exact horizontal
102c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * center of the overview view.
103c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     */
104c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public static final int ALIGN_MODE_MIDDLE = 1;
105c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
106c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    /**
1070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Listeners for events on ViewHolder.
1080246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
1090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public static abstract class Listener {
1100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
1120246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * {@link FullWidthDetailsOverviewRowPresenter#notifyOnBindLogo(ViewHolder)} is called.
1130246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * @param vh  The ViewHolder that has bound logo view.
1140246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
1150246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public void onBindLogo(ViewHolder vh) {
1160246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1170246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1180246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
1190246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1200246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    class ActionsItemBridgeAdapter extends ItemBridgeAdapter {
1210246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        FullWidthDetailsOverviewRowPresenter.ViewHolder mViewHolder;
1220246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1230246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ActionsItemBridgeAdapter(FullWidthDetailsOverviewRowPresenter.ViewHolder viewHolder) {
1240246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mViewHolder = viewHolder;
1250246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1260246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1270246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        @Override
1280246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public void onBind(final ItemBridgeAdapter.ViewHolder ibvh) {
1290246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            if (mViewHolder.getOnItemViewClickedListener() != null ||
1300246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    mActionClickedListener != null) {
1310246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                ibvh.getPresenter().setOnClickListener(
1320246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                        ibvh.getViewHolder(), new View.OnClickListener() {
1330246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                            @Override
1340246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                            public void onClick(View v) {
1350246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                if (mViewHolder.getOnItemViewClickedListener() != null) {
1360246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                    mViewHolder.getOnItemViewClickedListener().onItemClicked(
1370246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                            ibvh.getViewHolder(), ibvh.getItem(),
1380246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                            mViewHolder, mViewHolder.getRow());
1390246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                }
1400246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                if (mActionClickedListener != null) {
1410246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                    mActionClickedListener.onActionClicked((Action) ibvh.getItem());
1420246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                                }
1430246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                            }
1440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                        });
1450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
1460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        @Override
1480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public void onUnbind(final ItemBridgeAdapter.ViewHolder ibvh) {
1490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            if (mViewHolder.getOnItemViewClickedListener() != null ||
1500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    mActionClickedListener != null) {
1510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                ibvh.getPresenter().setOnClickListener(ibvh.getViewHolder(), null);
1520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
1530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        @Override
1550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
1560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            // Remove first to ensure we don't add ourselves more than once.
1570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder.itemView.removeOnLayoutChangeListener(mViewHolder.mLayoutChangeListener);
1580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder.itemView.addOnLayoutChangeListener(mViewHolder.mLayoutChangeListener);
1590246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        @Override
1610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
1620246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder.itemView.removeOnLayoutChangeListener(mViewHolder.mLayoutChangeListener);
1630246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mViewHolder.checkFirstAndLastPosition(false);
1640246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1650246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
1660246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1670246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
1680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * A ViewHolder for the DetailsOverviewRow.
1690246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
1700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public class ViewHolder extends RowPresenter.ViewHolder {
1710246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1720246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        protected final DetailsOverviewRow.Listener mRowListener = createRowListener();
1730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        protected DetailsOverviewRow.Listener createRowListener() {
1750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return new DetailsOverviewRowListener();
1760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
1770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1780246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public class DetailsOverviewRowListener extends DetailsOverviewRow.Listener {
1790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
1800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onImageDrawableChanged(DetailsOverviewRow row) {
181813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                sHandler.removeCallbacks(mUpdateDrawableCallback);
182813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                sHandler.post(mUpdateDrawableCallback);
1830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
1840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
1860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onItemChanged(DetailsOverviewRow row) {
1870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                if (mDetailsDescriptionViewHolder != null) {
1880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    mDetailsPresenter.onUnbindViewHolder(mDetailsDescriptionViewHolder);
1890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                }
1900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                mDetailsPresenter.onBindViewHolder(mDetailsDescriptionViewHolder, row.getItem());
1910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
1920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
1940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onActionsAdapterChanged(DetailsOverviewRow row) {
1950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                bindActions(row.getActionsAdapter());
1960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
1970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        };
1980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
1990246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final ViewGroup mOverviewRoot;
200bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu        final FrameLayout mOverviewFrame;
201c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        final ViewGroup mDetailsDescriptionFrame;
2020246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final HorizontalGridView mActionsRow;
2030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final Presenter.ViewHolder mDetailsDescriptionViewHolder;
2040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final DetailsOverviewLogoPresenter.ViewHolder mDetailsLogoViewHolder;
2050246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        int mNumItems;
2060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ItemBridgeAdapter mActionBridgeAdapter;
2070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        int mState = STATE_HALF;
2080246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final Runnable mUpdateDrawableCallback = new Runnable() {
2100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
2110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void run() {
212813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                Row row = getRow();
213813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                if (row == null) {
214813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                    return;
215813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                }
216813de6fe46801f8a01952699d553826a4f5fe116Dake Gu                mDetailsOverviewLogoPresenter.onBindViewHolder(mDetailsLogoViewHolder, row);
2170246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2180246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        };
2190246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2200246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        void bindActions(ObjectAdapter adapter) {
2210246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionBridgeAdapter.setAdapter(adapter);
2220246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setAdapter(mActionBridgeAdapter);
2230246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mNumItems = mActionBridgeAdapter.getItemCount();
2240246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2250246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
2260246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
227813de6fe46801f8a01952699d553826a4f5fe116Dake Gu        void onBind() {
228813de6fe46801f8a01952699d553826a4f5fe116Dake Gu            DetailsOverviewRow row = (DetailsOverviewRow) getRow();
229813de6fe46801f8a01952699d553826a4f5fe116Dake Gu            bindActions(row.getActionsAdapter());
230813de6fe46801f8a01952699d553826a4f5fe116Dake Gu            row.addListener(mRowListener);
231813de6fe46801f8a01952699d553826a4f5fe116Dake Gu        }
232813de6fe46801f8a01952699d553826a4f5fe116Dake Gu
233813de6fe46801f8a01952699d553826a4f5fe116Dake Gu        void onUnbind() {
234813de6fe46801f8a01952699d553826a4f5fe116Dake Gu            DetailsOverviewRow row = (DetailsOverviewRow) getRow();
235813de6fe46801f8a01952699d553826a4f5fe116Dake Gu            row.removeListener(mRowListener);
236813de6fe46801f8a01952699d553826a4f5fe116Dake Gu            sHandler.removeCallbacks(mUpdateDrawableCallback);
237813de6fe46801f8a01952699d553826a4f5fe116Dake Gu        }
238813de6fe46801f8a01952699d553826a4f5fe116Dake Gu
2390246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final View.OnLayoutChangeListener mLayoutChangeListener =
2400246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                new View.OnLayoutChangeListener() {
2410246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2420246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
2430246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onLayoutChange(View v, int left, int top, int right,
2440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
2450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                if (DEBUG) Log.v(TAG, "onLayoutChange " + v);
2460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                checkFirstAndLastPosition(false);
2470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        };
2490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final OnChildSelectedListener mChildSelectedListener = new OnChildSelectedListener() {
2510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
2520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
2530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                dispatchItemSelection(view);
2540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        };
2560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        void dispatchItemSelection(View view) {
2580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            if (!isSelected()) {
2590246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                return;
2600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            ItemBridgeAdapter.ViewHolder ibvh = (ItemBridgeAdapter.ViewHolder) (view != null ?
2620246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    mActionsRow.getChildViewHolder(view) :
2630246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    mActionsRow.findViewHolderForPosition(mActionsRow.getSelectedPosition()));
2640246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            if (ibvh == null) {
2650246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                if (getOnItemViewSelectedListener() != null) {
2660246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    getOnItemViewSelectedListener().onItemSelected(null, null,
2670246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                            ViewHolder.this, getRow());
2680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                }
2690246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            } else {
2700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                if (getOnItemViewSelectedListener() != null) {
2710246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    getOnItemViewSelectedListener().onItemSelected(ibvh.getViewHolder(), ibvh.getItem(),
2720246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                            ViewHolder.this, getRow());
2730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                }
2740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        };
2760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final RecyclerView.OnScrollListener mScrollListener =
2780246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                new RecyclerView.OnScrollListener() {
2790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
2810246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
2820246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
2840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
2850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                checkFirstAndLastPosition(true);
2860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
2870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        };
2880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        private int getViewCenter(View view) {
2900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return (view.getRight() - view.getLeft()) / 2;
2910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
2920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        private void checkFirstAndLastPosition(boolean fromScroll) {
2940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            RecyclerView.ViewHolder viewHolder;
2950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
2960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder = mActionsRow.findViewHolderForPosition(mNumItems - 1);
2970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            boolean showRight = (viewHolder == null ||
2980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    viewHolder.itemView.getRight() > mActionsRow.getWidth());
2990246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3000246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder = mActionsRow.findViewHolderForPosition(0);
3010246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            boolean showLeft = (viewHolder == null || viewHolder.itemView.getLeft() < 0);
3020246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            if (DEBUG) Log.v(TAG, "checkFirstAndLast fromScroll " + fromScroll +
3040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    " showRight " + showRight + " showLeft " + showLeft);
3050246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3080246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Constructor for the ViewHolder.
3100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         *
3110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * @param rootView The root View that this view holder will be attached
3120246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         *        to.
3130246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3140246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public ViewHolder(View rootView, Presenter detailsPresenter,
3150246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                DetailsOverviewLogoPresenter logoPresenter) {
3160246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            super(rootView);
3170246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mOverviewRoot = (ViewGroup) rootView.findViewById(R.id.details_root);
318bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu            mOverviewFrame = (FrameLayout) rootView.findViewById(R.id.details_frame);
3190246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mDetailsDescriptionFrame =
320c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    (ViewGroup) rootView.findViewById(R.id.details_overview_description);
3210246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow =
3220246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    (HorizontalGridView) mOverviewFrame.findViewById(R.id.details_overview_actions);
3230246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setHasOverlappingRendering(false);
3240246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setOnScrollListener(mScrollListener);
3250246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setAdapter(mActionBridgeAdapter);
3260246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setOnChildSelectedListener(mChildSelectedListener);
3270246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3280246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            final int fadeLength = rootView.getResources().getDimensionPixelSize(
3290246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    R.dimen.lb_details_overview_actions_fade_size);
3300246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setFadingRightEdgeLength(fadeLength);
3310246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mActionsRow.setFadingLeftEdgeLength(fadeLength);
3320246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mDetailsDescriptionViewHolder =
3330246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    detailsPresenter.onCreateViewHolder(mDetailsDescriptionFrame);
3340246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mDetailsDescriptionFrame.addView(mDetailsDescriptionViewHolder.view);
3350246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mDetailsLogoViewHolder = (DetailsOverviewLogoPresenter.ViewHolder)
3360246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    logoPresenter.onCreateViewHolder(mOverviewRoot);
3370246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mOverviewRoot.addView(mDetailsLogoViewHolder.view);
3380246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3390246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3400246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3410246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Returns the rectangle area with a color background.
3420246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3430246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public final ViewGroup getOverviewView() {
3440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return mOverviewFrame;
3450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Returns the ViewHolder for logo.
3490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public final DetailsOverviewLogoPresenter.ViewHolder getLogoViewHolder() {
3510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return mDetailsLogoViewHolder;
3520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Returns the ViewHolder for DetailsDescription.
3560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public final Presenter.ViewHolder getDetailsDescriptionViewHolder() {
3580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return mDetailsDescriptionViewHolder;
3590246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3620246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Returns the root view for inserting details description.
3630246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3640246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public final ViewGroup getDetailsDescriptionFrame() {
3650246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return mDetailsDescriptionFrame;
3660246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3670246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3690246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Returns the view of actions row.
3700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3710246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public final ViewGroup getActionsRow() {
3720246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return mActionsRow;
3730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        /**
3760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * Returns current state of the ViewHolder set by
3770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         * {@link FullWidthDetailsOverviewRowPresenter#setState(ViewHolder, int)}.
3780246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu         */
3790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        public final int getState() {
3800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return mState;
3810246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
3820246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
3830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected int mInitialState = STATE_HALF;
3850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private final Presenter mDetailsPresenter;
3870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private final DetailsOverviewLogoPresenter mDetailsOverviewLogoPresenter;
3880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private OnActionClickedListener mActionClickedListener;
3890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private int mBackgroundColor = Color.TRANSPARENT;
391c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    private int mActionsBackgroundColor = Color.TRANSPARENT;
3920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private boolean mBackgroundColorSet;
393c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    private boolean mActionsBackgroundColorSet;
3940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
3950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private Listener mListener;
3960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private boolean mParticipatingEntranceTransition;
3970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
398c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    private int mAlignmentMode;
399c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
4000246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4010246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Constructor for a FullWidthDetailsOverviewRowPresenter.
4020246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     *
4030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param detailsPresenter The {@link Presenter} used to render the detailed
4040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     *        description of the row.
4050246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public FullWidthDetailsOverviewRowPresenter(Presenter detailsPresenter) {
4070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        this(detailsPresenter, new DetailsOverviewLogoPresenter());
4080246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Constructor for a FullWidthDetailsOverviewRowPresenter.
4120246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     *
4130246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param detailsPresenter The {@link Presenter} used to render the detailed
4140246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     *        description of the row.
4150246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param logoPresenter  The {@link Presenter} used to render the logo view.
4160246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4170246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public FullWidthDetailsOverviewRowPresenter(Presenter detailsPresenter,
4180246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            DetailsOverviewLogoPresenter logoPresenter) {
4190246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        setHeaderPresenter(null);
4200246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        setSelectEffectEnabled(false);
4210246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsPresenter = detailsPresenter;
4220246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsOverviewLogoPresenter = logoPresenter;
4230246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4240246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4250246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4260246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Sets the listener for Action click events.
4270246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4280246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public void setOnActionClickedListener(OnActionClickedListener listener) {
4290246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mActionClickedListener = listener;
4300246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4310246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4320246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4330246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Returns the listener for Action click events.
4340246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4350246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public OnActionClickedListener getOnActionClickedListener() {
4360246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return mActionClickedListener;
4370246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4380246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4390246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4400246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Sets the background color.  If not set, a default from the theme will be used.
4410246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
442c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public final void setBackgroundColor(int color) {
4430246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mBackgroundColor = color;
4440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mBackgroundColorSet = true;
4450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
448c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * Returns the background color.  If {@link #setBackgroundColor(int)}, transparent
4490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * is returned.
4500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
451c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public final int getBackgroundColor() {
4520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return mBackgroundColor;
4530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
456c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * Sets the background color for Action Bar.  If not set, a default from the theme will be
457c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * used.
458c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     */
459c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public final void setActionsBackgroundColor(int color) {
460c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        mActionsBackgroundColor = color;
461c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        mActionsBackgroundColorSet = true;
462c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    }
463c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
464c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    /**
465c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * Returns the background color of actions.  If {@link #setActionsBackgroundColor(int)}
466c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * is not called,  transparent is returned.
467c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     */
468c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public final int getActionsBackgroundColor() {
469c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        return mActionsBackgroundColor;
470c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    }
471c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
472c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    /**
4730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Returns true if the overview should be part of shared element transition.
4740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final boolean isParticipatingEntranceTransition() {
4760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return mParticipatingEntranceTransition;
4770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4780246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Sets if the overview should be part of shared element transition.
4810246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4820246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final void setParticipatingEntranceTransition(boolean participating) {
4830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mParticipatingEntranceTransition = participating;
4840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Change the initial state used to create ViewHolder.
4880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final void setInitialState(int state) {
4900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mInitialState = state;
4910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
4930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
4940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Returns the initial state used to create ViewHolder.
4950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
4960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final int getInitialState() {
4970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return mInitialState;
4980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
4990246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
500c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    /**
501c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * Set alignment mode of Description.
502c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     *
503c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * @param alignmentMode  One of {@link #ALIGN_MODE_MIDDLE} or {@link #ALIGN_MODE_START}
504c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     */
505c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public final void setAlignmentMode(int alignmentMode) {
506c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        mAlignmentMode = alignmentMode;
507c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    }
508c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
509c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    /**
510c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * Returns alignment mode of Description.
511c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     *
512c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     * @return  One of {@link #ALIGN_MODE_MIDDLE} or {@link #ALIGN_MODE_START}.
513c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang     */
514c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    public final int getAlignmentMode() {
515c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        return mAlignmentMode;
516c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    }
517c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
5180246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
5190246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected boolean isClippingChildren() {
5200246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return true;
5210246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5220246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5230246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
5240246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Set listener for details overview presenter. Must be called before creating
5250246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * ViewHolder.
5260246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
5270246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final void setListener(Listener listener) {
5280246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mListener = listener;
5290246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5300246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5310246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private int getDefaultBackgroundColor(Context context) {
5320246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        TypedValue outValue = new TypedValue();
5330246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        if (context.getTheme().resolveAttribute(R.attr.defaultBrandColor, outValue, true)) {
5340246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            return context.getResources().getColor(outValue.resourceId);
5350246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
5360246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return context.getResources().getColor(R.color.lb_default_brand_color);
5370246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5380246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
539c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    private int getDefaultActionsBackgroundColor(Context context) {
540c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        int c = getDefaultBackgroundColor(context);
541c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        return Color.argb(Color.alpha(c), Color.red(c) / 2, Color.green(c) / 2, Color.blue(c) / 2);
542c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang    }
543c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
5440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
5450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Get resource id to inflate the layout.  The layout must match {@link #STATE_HALF}
5460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
5470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected int getLayoutResourceId() {
5480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return R.layout.lb_fullwidth_details_overview;
5490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
5520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
5530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        View v = LayoutInflater.from(parent.getContext())
5540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            .inflate(getLayoutResourceId(), parent, false);
5550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final ViewHolder vh = new ViewHolder(v, mDetailsPresenter, mDetailsOverviewLogoPresenter);
5560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsOverviewLogoPresenter.setContext(vh.mDetailsLogoViewHolder, vh, this);
5570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        setState(vh, mInitialState);
5580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5590246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        vh.mActionBridgeAdapter = new ActionsItemBridgeAdapter(vh);
5600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final View overview = vh.mOverviewFrame;
5610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final int bgColor = mBackgroundColorSet ? mBackgroundColor :
5620246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                getDefaultBackgroundColor(overview.getContext());
5630246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        overview.setBackgroundColor(bgColor);
564c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        final int actionBgColor = mActionsBackgroundColorSet ? mActionsBackgroundColor :
565c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                getDefaultActionsBackgroundColor(overview.getContext());
566c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        overview.findViewById(R.id.details_overview_actions_background)
567c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                .setBackgroundColor(actionBgColor);
5680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        RoundedRectHelper.getInstance().setClipToRoundedOutline(overview, true);
5690246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
570bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu        if (!getSelectEffectEnabled()) {
571bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu            vh.mOverviewFrame.setForeground(null);
572bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu        }
573bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu
5740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        vh.mActionsRow.setOnUnhandledKeyListener(new BaseGridView.OnUnhandledKeyListener() {
5750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            @Override
5760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            public boolean onUnhandledKey(KeyEvent event) {
5770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                if (vh.getOnKeyListener() != null) {
5780246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    if (vh.getOnKeyListener().onKey(vh.view, event.getKeyCode(), event)) {
5790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                        return true;
5800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    }
5810246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                }
5820246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                return false;
5830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            }
5840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        });
5850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return vh;
5860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private static int getNonNegativeWidth(Drawable drawable) {
5890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final int width = (drawable == null) ? 0 : drawable.getIntrinsicWidth();
5900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return (width > 0 ? width : 0);
5910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private static int getNonNegativeHeight(Drawable drawable) {
5940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        final int height = (drawable == null) ? 0 : drawable.getIntrinsicHeight();
5950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return (height > 0 ? height : 0);
5960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
5970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
5980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
5990246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) {
6000246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        super.onBindRowViewHolder(holder, item);
6010246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6020246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        DetailsOverviewRow row = (DetailsOverviewRow) item;
6030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ViewHolder vh = (ViewHolder) holder;
6040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6050246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsOverviewLogoPresenter.onBindViewHolder(vh.mDetailsLogoViewHolder, row);
6060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsPresenter.onBindViewHolder(vh.mDetailsDescriptionViewHolder, row.getItem());
607813de6fe46801f8a01952699d553826a4f5fe116Dake Gu        vh.onBind();
6080246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
6090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
6110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) {
6120246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ViewHolder vh = (ViewHolder) holder;
613813de6fe46801f8a01952699d553826a4f5fe116Dake Gu        vh.onUnbind();
6140246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsPresenter.onUnbindViewHolder(vh.mDetailsDescriptionViewHolder);
6150246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsOverviewLogoPresenter.onUnbindViewHolder(vh.mDetailsLogoViewHolder);
6160246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        super.onUnbindRowViewHolder(holder);
6170246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
6180246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6190246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
6200246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final boolean isUsingDefaultSelectEffect() {
6210246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        return false;
6220246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
6230246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6240246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
625bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu    protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) {
626bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu        super.onSelectLevelChanged(holder);
627bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu        if (getSelectEffectEnabled()) {
628bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu            ViewHolder vh = (ViewHolder) holder;
629bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu            int dimmedColor = vh.mColorDimmer.getPaint().getColor();
630bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu            ((ColorDrawable) vh.mOverviewFrame.getForeground().mutate()).setColor(dimmedColor);
631bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu        }
632bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu    }
633bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu
634bc00c3b6c1d1be08d2f462080fb7ccd551fe65d8Dake Gu    @Override
6350246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onRowViewAttachedToWindow(RowPresenter.ViewHolder vh) {
6360246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        super.onRowViewAttachedToWindow(vh);
6370246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ViewHolder viewHolder = (ViewHolder) vh;
6380246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsPresenter.onViewAttachedToWindow(viewHolder.mDetailsDescriptionViewHolder);
6390246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsOverviewLogoPresenter.onViewAttachedToWindow(viewHolder.mDetailsLogoViewHolder);
6400246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
6410246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6420246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
6430246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onRowViewDetachedFromWindow(RowPresenter.ViewHolder vh) {
6440246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        super.onRowViewDetachedFromWindow(vh);
6450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ViewHolder viewHolder = (ViewHolder) vh;
6460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsPresenter.onViewDetachedFromWindow(viewHolder.mDetailsDescriptionViewHolder);
6470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        mDetailsOverviewLogoPresenter.onViewDetachedFromWindow(viewHolder.mDetailsLogoViewHolder);
6480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
6490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
6510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Called by {@link DetailsOverviewLogoPresenter} to notify logo was bound to view.
6520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Application should not directly call this method.
6530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param viewHolder  The row ViewHolder that has logo bound to view.
6540246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
6550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final void notifyOnBindLogo(ViewHolder viewHolder) {
6560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        onLayoutOverviewFrame(viewHolder, viewHolder.getState(), true);
6570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        onLayoutLogo(viewHolder, viewHolder.getState(), true);
6580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        if (mListener != null) {
6590246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            mListener.onBindLogo(viewHolder);
6600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
6610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
6620246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
6630246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
6640246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Layout logo position based on current state.  Subclass may override.
6650246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * The method is called when a logo is bound to view or state changes.
6660246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param viewHolder  The row ViewHolder that contains the logo.
6670246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param oldState    The old state,  can be same as current viewHolder.getState()
6680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param logoChanged Whether logo was changed.
6690246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
6700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onLayoutLogo(ViewHolder viewHolder, int oldState, boolean logoChanged) {
6710246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        View v = viewHolder.getLogoViewHolder().view;
6720246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
6730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                v.getLayoutParams();
674c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        switch (mAlignmentMode) {
675c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            case ALIGN_MODE_START:
676c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            default:
677c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                lp.setMarginStart(v.getResources().getDimensionPixelSize(
678c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        R.dimen.lb_details_v2_logo_margin_start));
679c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                break;
680c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            case ALIGN_MODE_MIDDLE:
681c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                lp.setMarginStart(v.getResources().getDimensionPixelSize(R.dimen.lb_details_v2_left)
682c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        - lp.width);
683c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                break;
684c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang        }
685c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
6860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        switch (viewHolder.getState()) {
6870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        case STATE_FULL:
6880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        default:
6890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            lp.topMargin =
6900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    v.getResources().getDimensionPixelSize(R.dimen.lb_details_v2_blank_height)
6910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    - lp.height / 2;
6920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            break;
6930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        case STATE_HALF:
6940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            lp.topMargin = v.getResources().getDimensionPixelSize(
6950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    R.dimen.lb_details_v2_blank_height) + v.getResources()
6960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    .getDimensionPixelSize(R.dimen.lb_details_v2_actions_height) + v
6970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    .getResources().getDimensionPixelSize(
6980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    R.dimen.lb_details_v2_description_margin_top);
6990246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            break;
7000246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        case STATE_SMALL:
7010246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            lp.topMargin = 0;
7020246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            break;
7030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
7040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        v.setLayoutParams(lp);
7050246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
7060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
7070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
7080246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Layout overview frame based on current state.  Subclass may override.
7090246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * The method is called when a logo is bound to view or state changes.
7100246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param viewHolder  The row ViewHolder that contains the logo.
7110246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param oldState    The old state,  can be same as current viewHolder.getState()
7120246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param logoChanged Whether logo was changed.
7130246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
7140246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onLayoutOverviewFrame(ViewHolder viewHolder, int oldState, boolean logoChanged) {
7150246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        boolean wasBanner = oldState == STATE_SMALL;
7160246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        boolean isBanner = viewHolder.getState() == STATE_SMALL;
7170246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        if (wasBanner != isBanner || logoChanged) {
7180246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            Resources res = viewHolder.view.getResources();
719c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
720c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            int frameMarginStart;
721c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            int descriptionMarginStart = 0;
722c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            int logoWidth = 0;
723c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            if (mDetailsOverviewLogoPresenter.isBoundToImage(viewHolder.getLogoViewHolder(),
724c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    (DetailsOverviewRow) viewHolder.getRow())) {
725c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                logoWidth = viewHolder.getLogoViewHolder().view.getLayoutParams().width;
726c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            }
727c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            switch (mAlignmentMode) {
728c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                case ALIGN_MODE_START:
729c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                default:
730c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    if (isBanner) {
731c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        frameMarginStart = res.getDimensionPixelSize(
732c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                                R.dimen.lb_details_v2_logo_margin_start);
733c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        descriptionMarginStart = logoWidth;
734c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    } else {
735c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        frameMarginStart = 0;
736c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        descriptionMarginStart = logoWidth + res.getDimensionPixelSize(
737c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                                R.dimen.lb_details_v2_logo_margin_start);
738c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    }
739c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    break;
740c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                case ALIGN_MODE_MIDDLE:
741c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    if (isBanner) {
742c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        frameMarginStart = res.getDimensionPixelSize(R.dimen.lb_details_v2_left)
743c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                                - logoWidth;
744c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        descriptionMarginStart = logoWidth;
745c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    } else {
746c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        frameMarginStart = 0;
747c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                        descriptionMarginStart = res.getDimensionPixelSize(
748c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                                R.dimen.lb_details_v2_left);
749c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    }
750c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    break;
751c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            }
7520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            MarginLayoutParams lpFrame =
7530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    (MarginLayoutParams) viewHolder.getOverviewView().getLayoutParams();
754c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            lpFrame.topMargin = isBanner ? 0
755c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang                    : res.getDimensionPixelSize(R.dimen.lb_details_v2_blank_height);
756c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            lpFrame.leftMargin = lpFrame.rightMargin = frameMarginStart;
7570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder.getOverviewView().setLayoutParams(lpFrame);
758c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
759c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            View description = viewHolder.getDetailsDescriptionFrame();
760c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            MarginLayoutParams lpDesc = (MarginLayoutParams) description.getLayoutParams();
761c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            lpDesc.setMarginStart(descriptionMarginStart);
762c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            description.setLayoutParams(lpDesc);
763c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang
764c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            View action = viewHolder.getActionsRow();
765c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            MarginLayoutParams lpActions = (MarginLayoutParams) action.getLayoutParams();
766c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            lpActions.setMarginStart(descriptionMarginStart);
7670246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            lpActions.height =
7680246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    isBanner ? 0 : res.getDimensionPixelSize(R.dimen.lb_details_v2_actions_height);
769c6714279e5a39ac1f5eabd0431bb46fcfe6240feXiaolei Wang            action.setLayoutParams(lpActions);
7700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
7710246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
7720246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
7730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
7740246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Switch state of a ViewHolder.
7750246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param viewHolder   The ViewHolder to change state.
7760246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param state        New state, can be {@link #STATE_FULL}, {@link #STATE_HALF}
7770246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     *                     or {@link #STATE_SMALL}.
7780246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
7790246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public final void setState(ViewHolder viewHolder, int state) {
7800246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        if (viewHolder.getState() != state) {
7810246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            int oldState = viewHolder.getState();
7820246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            viewHolder.mState = state;
7830246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            onStateChanged(viewHolder, oldState);
7840246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
7850246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
7860246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
7870246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    /**
7880246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * Called when {@link ViewHolder#getState()} changes.  Subclass may override.
7890246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * The default implementation calls {@link #onLayoutLogo(ViewHolder, int, boolean)} and
7900246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * {@link #onLayoutOverviewFrame(ViewHolder, int, boolean)}.
7910246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param viewHolder   The ViewHolder which state changed.
7920246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     * @param oldState     The old state.
7930246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu     */
7940246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    protected void onStateChanged(ViewHolder viewHolder, int oldState) {
7950246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        onLayoutOverviewFrame(viewHolder, oldState, false);
7960246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        onLayoutLogo(viewHolder, oldState, false);
7970246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
7980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu
7990246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    @Override
8000246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    public void setEntranceTransitionState(RowPresenter.ViewHolder holder,
8010246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            boolean afterEntrance) {
8020246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        super.setEntranceTransitionState(holder, afterEntrance);
8030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        if (mParticipatingEntranceTransition) {
8040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            holder.view.setVisibility(afterEntrance? View.VISIBLE : View.INVISIBLE);
8050246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu        }
8060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    }
8070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu}
808