165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.dialog.old; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.animation.Animator; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.animation.AnimatorListenerAdapter; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.animation.ObjectAnimator; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.graphics.drawable.ColorDrawable; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.Uri; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup.LayoutParams; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewTreeObserver; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.animation.DecelerateInterpolator; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.animation.Interpolator; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.ImageView; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.RelativeLayout; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.TextView; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.util.UriUtils; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.util.TransitionImage; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.util.TransitionImageAnimation; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.widget.FrameLayoutWithShadows; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.List; 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * This class exists to make extending both v4 DialogFragments and regular DialogFragments easy 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class BaseDialogFragment { 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int ANIMATE_IN_DURATION = 250; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int ANIMATE_DELAY = 550; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int SLIDE_IN_STAGGER = 100; 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int SLIDE_IN_DISTANCE = 120; 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String TAG_CONTENT = "content"; 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String TAG_ACTION = "action"; 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public int mContentAreaId = R.id.content_fragment; 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public int mActionAreaId = R.id.action_fragment; 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public FrameLayoutWithShadows mShadowLayer; 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean mFirstOnStart = true; 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean mIntroAnimationInProgress = false; 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private LiteFragment mFragment; 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Related to activity entry transition 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public ColorDrawable mBgDrawable = new ColorDrawable(); 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public BaseDialogFragment(LiteFragment fragment) { 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFragment = fragment; 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Activity activity, Action action) { 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (activity instanceof ActionAdapter.Listener) { 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ((ActionAdapter.Listener) activity).onActionClicked(action); 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = action.getIntent(); 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (intent != null) { 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane activity.startActivity(intent); 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane activity.finish(); 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void disableEntryAnimation() { 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFirstOnStart = false; 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * This method sets the layout property of this class. <br/> 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Activities extending {@link DialogFragment} should call this method 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * before calling {@link #onCreate(Bundle)} if they want to have a 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * custom view. 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param contentAreaId id of the content area 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param actionAreaId id of the action area 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setLayoutProperties(int contentAreaId, int actionAreaId) { 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContentAreaId = contentAreaId; 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mActionAreaId = actionAreaId; 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void performEntryTransition(final Activity activity, final ViewGroup contentView, 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int iconResourceId, Uri iconResourceUri, final ImageView icon, final TextView title, 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final TextView description, final TextView breadcrumb) { 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Pull out the root layout of the dialog and set the background drawable, to be 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // faded in during the transition. 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final RelativeLayout twoPane = (RelativeLayout) contentView.getChildAt(0); 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane twoPane.setVisibility(View.INVISIBLE); 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If the appropriate data is embedded in the intent and there is an icon specified 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // in the content fragment, we animate the icon from its initial position to the final 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // position. Otherwise, we perform a simpler transition in which the ActionFragment 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // slides in and the ContentFragment text fields slide in. 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIntroAnimationInProgress = true; 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean lShouldAnimateIcon = true; 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean uriMatch = false; 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane List<TransitionImage> images = TransitionImage.readMultipleFromIntent( 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane activity, activity.getIntent()); 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TransitionImageAnimation ltransitionAnimation = null; 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final Uri iconUri; 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int color; 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (images != null && images.size() > 0) { 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (iconResourceId != 0) { 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane iconUri = Uri.parse(UriUtils.getAndroidResourceUri( 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane activity, iconResourceId)); 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (iconResourceUri != null) { 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane iconUri = iconResourceUri; 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane iconUri = null; 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TransitionImage src = images.get(0); 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane color = src.getBackground(); 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (iconUri != null) { 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ltransitionAnimation = new TransitionImageAnimation(contentView); 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ltransitionAnimation.addTransitionSource(src); 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ltransitionAnimation.transitionDurationMs(ANIMATE_IN_DURATION) 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .transitionStartDelayMs(0) 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .interpolator(new DecelerateInterpolator(1f)); 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane iconUri = null; 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane color = 0; 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final TransitionImageAnimation transitionAnimation = ltransitionAnimation; 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Fade out the old activity, and hard cut the new activity. 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane activity.overridePendingTransition(R.anim.hard_cut_in, R.anim.fade_out); 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int bgColor = mFragment.getResources().getColor(R.color.dialog_activity_background); 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mBgDrawable.setColor(bgColor); 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mBgDrawable.setAlpha(0); 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane twoPane.setBackground(mBgDrawable); 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If we're animating the icon, we create a new ImageView in which to place the embedded 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // bitmap. We place it in the root layout to match its location in the previous activity. 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mShadowLayer = (FrameLayoutWithShadows) twoPane.findViewById(R.id.shadow_layout); 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (transitionAnimation != null) { 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane transitionAnimation.listener(new TransitionImageAnimation.Listener() { 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onRemovedView(TransitionImage src, TransitionImage dst) { 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (icon != null) { 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane //want to make sure that users still see at least the source image 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // if the dst image is too large to finish downloading before the 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // animation is done. Check if the icon is not visible. This mean 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // BaseContentFragement have not finish downloading the image yet. 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (icon.getVisibility() != View.VISIBLE) { 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane icon.setImageDrawable(src.getBitmap()); 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int intrinsicWidth = icon.getDrawable().getIntrinsicWidth(); 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane LayoutParams lp = icon.getLayoutParams(); 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane lp.height = lp.width * icon.getDrawable().getIntrinsicHeight() 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane / intrinsicWidth; 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane icon.setVisibility(View.VISIBLE); 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane icon.setAlpha(1f); 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mShadowLayer != null) { 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mShadowLayer.setShadowsAlpha(1f); 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onIntroAnimationFinished(); 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane icon.setAlpha(0f); 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mShadowLayer != null) { 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mShadowLayer.setShadowsAlpha(0f); 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // We need to defer the remainder of the animation preparation until the first 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // layout has occurred, as we don't yet know the final location of the icon. 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane twoPane.getViewTreeObserver().addOnGlobalLayoutListener( 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new ViewTreeObserver.OnGlobalLayoutListener() { 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onGlobalLayout() { 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane twoPane.getViewTreeObserver().removeOnGlobalLayoutListener(this); 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // if we buildLayer() at this time, the texture is actually not created 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // delay a little so we can make sure all hardware layer is created before 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // animation, in that way we can avoid the jittering of start animation 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane twoPane.postOnAnimationDelayed(mEntryAnimationRunnable, ANIMATE_DELAY); 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Runnable mEntryAnimationRunnable = new Runnable() { 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void run() { 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!mFragment.isAdded()) { 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // We have been detached before this could run, so just bail 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return; 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane twoPane.setVisibility(View.VISIBLE); 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int secondaryDelay = SLIDE_IN_DISTANCE; 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Fade in the activity background protection 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ObjectAnimator oa = ObjectAnimator.ofInt(mBgDrawable, "alpha", 255); 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane oa.setDuration(ANIMATE_IN_DURATION); 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane oa.setStartDelay(secondaryDelay); 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane oa.setInterpolator(new DecelerateInterpolator(1.0f)); 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane oa.start(); 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Fade in and slide in the ContentFragment TextViews from the left. 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane prepareAndAnimateView(title, 0, - SLIDE_IN_DISTANCE, 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane secondaryDelay, ANIMATE_IN_DURATION, 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new DecelerateInterpolator(1.0f), 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane false); 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane prepareAndAnimateView(breadcrumb, 0, - SLIDE_IN_DISTANCE, 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane secondaryDelay, ANIMATE_IN_DURATION, 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new DecelerateInterpolator(1.0f), 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane false); 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane prepareAndAnimateView(description, 0, 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane - SLIDE_IN_DISTANCE, 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane secondaryDelay, ANIMATE_IN_DURATION, 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new DecelerateInterpolator(1.0f), 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane false); 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Fade in and slide in the ActionFragment from the right. 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane View actionFragmentView = activity.findViewById(mActionAreaId); 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane prepareAndAnimateView(actionFragmentView, 0, 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actionFragmentView.getMeasuredWidth(), secondaryDelay, 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ANIMATE_IN_DURATION, new DecelerateInterpolator(1.0f), 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane false); 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (icon != null && transitionAnimation != null) { 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // now we get the icon view in place, update the transition target 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TransitionImage target = new TransitionImage(); 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane target.setUri(iconUri); 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane target.createFromImageView(icon); 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (icon.getBackground() instanceof ColorDrawable) { 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ColorDrawable d = (ColorDrawable) icon.getBackground(); 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane target.setBackground(d.getColor()); 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane transitionAnimation.addTransitionTarget(target); 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane transitionAnimation.startTransition(); 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (icon != null) { 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane prepareAndAnimateView(icon, 0, - SLIDE_IN_DISTANCE, 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane secondaryDelay, ANIMATE_IN_DURATION, 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new DecelerateInterpolator(1.0f), true /* is the icon */); 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mShadowLayer != null) { 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mShadowLayer.setShadowsAlpha(0f); 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Animates a view. 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param v view to animate 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param initAlpha initial alpha 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param initTransX initial translation in the X 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param delay delay in ms 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param duration duration in ms 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param interpolator interpolator to be used, can be null 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param isIcon if {@code true}, this is the main icon being moved 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void prepareAndAnimateView(final View v, float initAlpha, float initTransX, int delay, 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int duration, Interpolator interpolator, final boolean isIcon) { 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (v != null && v.getWindowToken() != null) { 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.buildLayer(); 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.setAlpha(initAlpha); 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.setTranslationX(initTransX); 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.animate().alpha(1f).translationX(0).setDuration(duration).setStartDelay(delay); 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (interpolator != null) { 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.animate().setInterpolator(interpolator); 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.animate().setListener(new AnimatorListenerAdapter() { 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onAnimationEnd(Animator animation) { 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.setLayerType(View.LAYER_TYPE_NONE, null); 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isIcon) { 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mShadowLayer != null) { 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mShadowLayer.setShadowsAlpha(1f); 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onIntroAnimationFinished(); 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane v.animate().start(); 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Called when intro animation is finished. 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * If a subclass is going to alter the view, should wait until this is called. 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onIntroAnimationFinished() { 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIntroAnimationInProgress = false; 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean isIntroAnimationInProgress() { 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mIntroAnimationInProgress; 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public ColorDrawable getBackgroundDrawable() { 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mBgDrawable; 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setBackgroundDrawable(ColorDrawable drawable) { 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mBgDrawable = drawable; 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 325