DetailsOverviewSharedElementHelper.java revision b0181a77ce38f75a7d218745a330c5d80daacfb6
1010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten/*
2010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Copyright (C) 2014 The Android Open Source Project
3010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
4010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * in compliance with the License. You may obtain a copy of the License at
6010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
7010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0
8010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
9010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Unless required by applicable law or agreed to in writing, software distributed under the License
10010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * or implied. See the License for the specific language governing permissions and limitations under
12010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * the License.
13010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten */
14010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenpackage android.support.v17.leanback.widget;
15010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
16010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.support.v4.app.ActivityCompat;
17010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.support.v4.app.SharedElementListener;
18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.support.v4.view.ViewCompat;
19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.support.v17.leanback.widget.DetailsOverviewRowPresenter.ViewHolder;
20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
212dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kastenimport android.app.Activity;
22010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.text.TextUtils;
23010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.view.View;
24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport android.view.View.MeasureSpec;
2572e54af9fcdc4754914fe2bf8de699523538b315Glenn Kasten
26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenimport java.util.List;
27b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten
28010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenfinal class DetailsOverviewSharedElementHelper extends SharedElementListener {
29010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
3072e54af9fcdc4754914fe2bf8de699523538b315Glenn Kasten    private ViewHolder mViewHolder;
31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    private Activity mActivityToRunTransition;
32b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    private String mSharedElementName;
33b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    private int mRightPanelWidth;
34010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    private int mRightPanelHeight;
35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
3651d53cd993043d9286e12cba884e6ee4d10b5facGlenn Kasten    @Override
3751d53cd993043d9286e12cba884e6ee4d10b5facGlenn Kasten    public void setSharedElementStart(List<String> sharedElementNames,
38b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            List<View> sharedElements, List<View> sharedElementSnapshots) {
39b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (sharedElements.size() < 1) {
40b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            return;
41b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
42b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        View overviewView = sharedElements.get(0);
43b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (mViewHolder == null || mViewHolder.mOverviewView != overviewView) {
44b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            return;
45b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
46b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        View imageView = mViewHolder.mImageView;
47b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        final int width = overviewView.getWidth();
48b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        final int height = overviewView.getHeight();
49b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
50b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
51b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        imageView.layout(0, 0, width, height);
52b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        final View rightPanel = mViewHolder.mRightPanel;
53b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (mRightPanelWidth != 0 && mRightPanelHeight != 0) {
54b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            rightPanel.measure(MeasureSpec.makeMeasureSpec(mRightPanelWidth, MeasureSpec.EXACTLY),
55b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    MeasureSpec.makeMeasureSpec(mRightPanelHeight, MeasureSpec.EXACTLY));
5672e54af9fcdc4754914fe2bf8de699523538b315Glenn Kasten            rightPanel.layout(width, rightPanel.getTop(), width + mRightPanelWidth,
57010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten                    rightPanel.getTop() + mRightPanelHeight);
58b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        } else {
59b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            rightPanel.offsetLeftAndRight(width - rightPanel.getLeft());
60b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
61b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        rightPanel.setVisibility(View.INVISIBLE);
62b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    }
63b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten
64b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    @Override
65b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    public void setSharedElementEnd(List<String> sharedElementNames,
66b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            List<View> sharedElements, List<View> sharedElementSnapshots) {
67b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (sharedElements.size() < 1) {
68b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            return;
69b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
70b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        View overviewView = sharedElements.get(0);
71b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (mViewHolder == null || mViewHolder.mOverviewView != overviewView) {
72b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            return;
73b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
74b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        final View rightPanel = mViewHolder.mRightPanel;
75010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        rightPanel.setVisibility(View.VISIBLE);
76b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    }
77010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
78010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    void setSharedElementEnterTransition(Activity activity, String sharedElementName) {
79010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        if (activity == null && !TextUtils.isEmpty(sharedElementName) ||
80010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten                activity != null && TextUtils.isEmpty(sharedElementName)) {
81010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            throw new IllegalArgumentException();
82010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        }
8372e54af9fcdc4754914fe2bf8de699523538b315Glenn Kasten        if (activity == mActivityToRunTransition &&
84010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten                TextUtils.equals(sharedElementName, mSharedElementName)) {
85b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            return;
86b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
87b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (mActivityToRunTransition != null) {
88b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            ActivityCompat.setEnterSharedElementListener(mActivityToRunTransition, null);
89b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
90010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mActivityToRunTransition = activity;
91b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        mSharedElementName = sharedElementName;
92010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        if (mActivityToRunTransition != null) {
93010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            ActivityCompat.setEnterSharedElementListener(mActivityToRunTransition, this);
94010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            ActivityCompat.postponeEnterTransition(mActivityToRunTransition);
95010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        }
96010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
97010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
98010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    void onBindToDrawable(ViewHolder vh) {
99010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        // After we got a image drawable,  we can determine size of right panel.
100b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        // We want right panel to have fixed size so that the right panel don't change size
101b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        // when the overview is layout as a small bounds in transition.
102b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        mViewHolder = vh;
103b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        mViewHolder.mRightPanel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
104b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            @Override
105b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            public void onLayoutChange(View v, int left, int top, int right, int bottom,
106b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
107b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                mViewHolder.mRightPanel.removeOnLayoutChangeListener(this);
108b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                mRightPanelWidth = mViewHolder.mRightPanel.getWidth();
109b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                mRightPanelHeight = mViewHolder.mRightPanel.getHeight();
110b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            }
111b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        });
112b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        if (mActivityToRunTransition != null) {
113b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            mViewHolder.mRightPanel.postOnAnimation(new Runnable() {
114b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                @Override
115b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                public void run() {
116b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    if (mActivityToRunTransition == null) {
117b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                        return;
118b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    }
119b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    ViewCompat.setTransitionName(mViewHolder.mOverviewView, mSharedElementName);
120b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    ActivityCompat.startPostponedEnterTransition(mActivityToRunTransition);
121b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    mActivityToRunTransition = null;
122b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                    mSharedElementName = null;
123b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten                }
124b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten            });
125b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten        }
126b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten    }
127b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten}
128b64497eb8724c4c372fffdbf3ee30543432953c5Glenn Kasten