DetailsOverviewSharedElementHelper.java revision ceb7ab2ddd6e157cd4ade0f14a382c39428163c4
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.support.v4.app.ActivityCompat; 17import android.support.v4.app.SharedElementCallback; 18import android.support.v4.view.ViewCompat; 19import android.support.v17.leanback.R; 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 SharedElementCallback { 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 onSharedElementStart(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 onSharedElementEnd(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.setEnterSharedElementCallback(mActivityToRunTransition, null); 96 } 97 mActivityToRunTransition = activity; 98 mSharedElementName = sharedElementName; 99 if (mActivityToRunTransition != null) { 100 ActivityCompat.setEnterSharedElementCallback(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 @Override 108 public void onTransitionEnd(Object transition) { 109 // after transition if the action row still focused, transfer 110 // focus to its children 111 if (mViewHolder.mActionsRow.isFocused()) { 112 mViewHolder.mActionsRow.requestFocus(); 113 } 114 } 115 }); 116 } 117 } 118 } 119 120 void onBindToDrawable(ViewHolder vh) { 121 // After we got a image drawable, we can determine size of right panel. 122 // We want right panel to have fixed size so that the right panel don't change size 123 // when the overview is layout as a small bounds in transition. 124 mViewHolder = vh; 125 mViewHolder.mRightPanel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 126 @Override 127 public void onLayoutChange(View v, int left, int top, int right, int bottom, 128 int oldLeft, int oldTop, int oldRight, int oldBottom) { 129 mViewHolder.mRightPanel.removeOnLayoutChangeListener(this); 130 mRightPanelWidth = mViewHolder.mRightPanel.getWidth(); 131 mRightPanelHeight = mViewHolder.mRightPanel.getHeight(); 132 } 133 }); 134 if (mActivityToRunTransition != null) { 135 mViewHolder.mRightPanel.postOnAnimation(new Runnable() { 136 @Override 137 public void run() { 138 if (mActivityToRunTransition == null) { 139 return; 140 } 141 ViewCompat.setTransitionName(mViewHolder.mOverviewView, mSharedElementName); 142 ActivityCompat.startPostponedEnterTransition(mActivityToRunTransition); 143 mActivityToRunTransition = null; 144 mSharedElementName = null; 145 } 146 }); 147 } 148 } 149} 150