DetailsOverviewSharedElementHelper.java revision 95400e6d31a1ac09e48cb8944a79b7250484aa4c
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16import android.os.Handler; 17import android.support.v4.app.ActivityCompat; 18import android.support.v4.app.SharedElementListener; 19import android.support.v4.view.ViewCompat; 20import android.support.v17.leanback.transition.TransitionListener; 21import android.support.v17.leanback.transition.TransitionHelper; 22import android.support.v17.leanback.widget.DetailsOverviewRowPresenter.ViewHolder; 23import android.app.Activity; 24import android.text.TextUtils; 25import android.view.View; 26import android.view.ViewGroup; 27import android.view.View.MeasureSpec; 28 29import java.util.List; 30 31final class DetailsOverviewSharedElementHelper extends SharedElementListener { 32 33 private ViewHolder mViewHolder; 34 private Activity mActivityToRunTransition; 35 private String mSharedElementName; 36 private int mRightPanelWidth; 37 private int mRightPanelHeight; 38 39 @Override 40 public void setSharedElementStart(List<String> sharedElementNames, 41 List<View> sharedElements, List<View> sharedElementSnapshots) { 42 if (sharedElements.size() < 1) { 43 return; 44 } 45 View overviewView = sharedElements.get(0); 46 if (mViewHolder == null || mViewHolder.mOverviewView != overviewView) { 47 return; 48 } 49 View imageView = mViewHolder.mImageView; 50 final int width = overviewView.getWidth(); 51 final int height = overviewView.getHeight(); 52 imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 53 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 54 imageView.layout(0, 0, width, height); 55 final View rightPanel = mViewHolder.mRightPanel; 56 if (mRightPanelWidth != 0 && mRightPanelHeight != 0) { 57 rightPanel.measure(MeasureSpec.makeMeasureSpec(mRightPanelWidth, MeasureSpec.EXACTLY), 58 MeasureSpec.makeMeasureSpec(mRightPanelHeight, MeasureSpec.EXACTLY)); 59 rightPanel.layout(width, rightPanel.getTop(), width + mRightPanelWidth, 60 rightPanel.getTop() + mRightPanelHeight); 61 } else { 62 rightPanel.offsetLeftAndRight(width - rightPanel.getLeft()); 63 } 64 mViewHolder.mActionsRow.setVisibility(View.INVISIBLE); 65 mViewHolder.mDetailsDescriptionFrame.setVisibility(View.INVISIBLE); 66 } 67 68 @Override 69 public void setSharedElementEnd(List<String> sharedElementNames, 70 List<View> sharedElements, List<View> sharedElementSnapshots) { 71 if (sharedElements.size() < 1) { 72 return; 73 } 74 View overviewView = sharedElements.get(0); 75 if (mViewHolder == null || mViewHolder.mOverviewView != overviewView) { 76 return; 77 } 78 // temporary let action row take focus so we defer button background animation 79 mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 80 mViewHolder.mActionsRow.setVisibility(View.VISIBLE); 81 mViewHolder.mActionsRow.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 82 mViewHolder.mDetailsDescriptionFrame.setVisibility(View.VISIBLE); 83 } 84 85 void setSharedElementEnterTransition(Activity activity, String sharedElementName) { 86 if (activity == null && !TextUtils.isEmpty(sharedElementName) || 87 activity != null && TextUtils.isEmpty(sharedElementName)) { 88 throw new IllegalArgumentException(); 89 } 90 if (activity == mActivityToRunTransition && 91 TextUtils.equals(sharedElementName, mSharedElementName)) { 92 return; 93 } 94 if (mActivityToRunTransition != null) { 95 ActivityCompat.setEnterSharedElementListener(mActivityToRunTransition, null); 96 } 97 mActivityToRunTransition = activity; 98 mSharedElementName = sharedElementName; 99 if (mActivityToRunTransition != null) { 100 ActivityCompat.setEnterSharedElementListener(mActivityToRunTransition, this); 101 ActivityCompat.postponeEnterTransition(mActivityToRunTransition); 102 TransitionHelper transitionHelper = TransitionHelper.getInstance(); 103 Object transition = transitionHelper.getSharedElementEnterTransition( 104 mActivityToRunTransition.getWindow()); 105 if (transition != null) { 106 transitionHelper.setTransitionListener(transition, new TransitionListener() { 107 public void onTransitionEnd(Object transition) { 108 // after transition if the action row still focused, transfer 109 // focus to its children 110 if (mViewHolder.mActionsRow.isFocused()) { 111 mViewHolder.mActionsRow.requestFocus(); 112 } 113 } 114 }); 115 } 116 } 117 } 118 119 void onBindToDrawable(ViewHolder vh) { 120 // After we got a image drawable, we can determine size of right panel. 121 // We want right panel to have fixed size so that the right panel don't change size 122 // when the overview is layout as a small bounds in transition. 123 mViewHolder = vh; 124 mViewHolder.mRightPanel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 125 @Override 126 public void onLayoutChange(View v, int left, int top, int right, int bottom, 127 int oldLeft, int oldTop, int oldRight, int oldBottom) { 128 mViewHolder.mRightPanel.removeOnLayoutChangeListener(this); 129 mRightPanelWidth = mViewHolder.mRightPanel.getWidth(); 130 mRightPanelHeight = mViewHolder.mRightPanel.getHeight(); 131 } 132 }); 133 if (mActivityToRunTransition != null) { 134 mViewHolder.mRightPanel.postOnAnimation(new Runnable() { 135 @Override 136 public void run() { 137 if (mActivityToRunTransition == null) { 138 return; 139 } 140 ViewCompat.setTransitionName(mViewHolder.mOverviewView, mSharedElementName); 141 ActivityCompat.startPostponedEnterTransition(mActivityToRunTransition); 142 mActivityToRunTransition = null; 143 mSharedElementName = null; 144 } 145 }); 146 } 147 } 148} 149