use of com.android.launcher3.BubbleTextView in project Launcher3 by chislon.
the class LauncherTransitionable method onClick.
/**
* Launches the intent referred by the clicked shortcut.
*
* @param v The view representing the clicked shortcut.
*/
public void onClick(View v) {
// view has detached (it's possible for this to happen if the view is removed mid touch).
if (v.getWindowToken() == null) {
return;
}
if (!mWorkspace.isFinishedSwitchingState()) {
return;
}
if (v instanceof Workspace) {
if (mWorkspace.isInOverviewMode()) {
mWorkspace.exitOverviewMode(true);
}
return;
}
if (v instanceof CellLayout) {
if (mWorkspace.isInOverviewMode()) {
mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);
}
}
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
// Open shortcut
final ShortcutInfo shortcut = (ShortcutInfo) tag;
final Intent intent = shortcut.intent;
// Check for special shortcuts
if (intent.getComponent() != null) {
final String shortcutClass = intent.getComponent().getClassName();
if (shortcutClass.equals(WidgetAdder.class.getName())) {
showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
return;
} else if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {
MemoryDumpActivity.startDump(this);
return;
} else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {
toggleShowWeightWatcher();
return;
}
}
// Start activities
int[] pos = new int[2];
v.getLocationOnScreen(pos);
intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight()));
boolean success = startActivitySafely(v, intent, tag);
mStats.recordLaunch(intent, shortcut);
if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
mWaitingForResume.setStayPressed(true);
}
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
FolderIcon fi = (FolderIcon) v;
handleFolderClick(fi);
}
} else if (v == mAllAppsButton) {
if (isAllAppsVisible()) {
showWorkspace(true);
} else {
onClickAllAppsButton(v);
}
}
}
use of com.android.launcher3.BubbleTextView in project android_packages_apps_Launcher3 by crdroidandroid.
the class QuickstepTransitionManager method getOpeningWindowAnimators.
/**
* @return Animator that controls the window of the opening targets from app icons.
*/
private Animator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets, RemoteAnimationTargetCompat[] nonAppTargets, Rect windowTargetBounds, boolean appTargetsAreTranslucent, int rotationChange) {
RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, !appTargetsAreTranslucent, launcherIconBounds, true);
Rect crop = new Rect();
Matrix matrix = new Matrix();
RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING);
SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(floatingView);
openingTargets.addReleaseCheck(surfaceApplier);
RemoteAnimationTargetCompat navBarTarget = openingTargets.getNavBarRemoteAnimationTarget();
int[] dragLayerBounds = new int[2];
mDragLayer.getLocationOnScreen(dragLayerBounds);
final boolean hasSplashScreen;
if (supportsSSplashScreen()) {
int taskId = openingTargets.getFirstAppTargetTaskId();
Pair<Integer, Integer> defaultParams = Pair.create(STARTING_WINDOW_TYPE_NONE, 0);
Pair<Integer, Integer> taskParams = mTaskStartParams.getOrDefault(taskId, defaultParams);
mTaskStartParams.remove(taskId);
hasSplashScreen = taskParams.first == STARTING_WINDOW_TYPE_SPLASH_SCREEN;
} else {
hasSplashScreen = false;
}
AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile, windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1], hasSplashScreen, floatingView.isDifferentFromAppIcon());
int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
int right = (int) (left + prop.cropWidthStart);
int bottom = (int) (top + prop.cropHeightStart);
// Set the crop here so we can calculate the corner radius below.
crop.set(left, top, right, bottom);
RectF floatingIconBounds = new RectF();
RectF tmpRectF = new RectF();
Point tmpPos = new Point();
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setDuration(APP_LAUNCH_DURATION);
appAnimator.setInterpolator(LINEAR);
appAnimator.addListener(floatingView);
appAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (v instanceof BubbleTextView) {
((BubbleTextView) v).setStayPressed(false);
}
openingTargets.release();
}
});
final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources()) ? Math.max(crop.width(), crop.height()) / 2f : 0f;
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher.getResources());
final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
FloatProp mDx = new FloatProp(0, prop.dX, 0, APP_LAUNCH_DURATION, mOpeningXInterpolator);
FloatProp mDy = new FloatProp(0, prop.dY, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale, prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f, APP_LAUNCH_ALPHA_START_DELAY, APP_LAUNCH_ALPHA_DURATION, LINEAR);
FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mShadowRadius = new FloatProp(0, finalShadowRadius, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION, NAV_FADE_OUT_INTERPOLATOR);
FloatProp mNavFadeIn = new FloatProp(0f, 1f, ANIMATION_DELAY_NAV_FADE_IN, ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);
@Override
public void onUpdate(float percent, boolean initOnly) {
// Calculate the size of the scaled icon.
float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;
int left = (int) (mCropRectCenterX.value - mCropRectWidth.value / 2);
int top = (int) (mCropRectCenterY.value - mCropRectHeight.value / 2);
int right = (int) (left + mCropRectWidth.value);
int bottom = (int) (top + mCropRectHeight.value);
crop.set(left, top, right, bottom);
final int windowCropWidth = crop.width();
final int windowCropHeight = crop.height();
if (rotationChange != 0) {
Utilities.rotateBounds(crop, mDeviceProfile.widthPx, mDeviceProfile.heightPx, rotationChange);
}
// Scale the size of the icon to match the size of the window crop.
float scaleX = iconWidth / windowCropWidth;
float scaleY = iconHeight / windowCropHeight;
float scale = Math.min(1f, Math.max(scaleX, scaleY));
float scaledCropWidth = windowCropWidth * scale;
float scaledCropHeight = windowCropHeight * scale;
float offsetX = (scaledCropWidth - iconWidth) / 2;
float offsetY = (scaledCropHeight - iconHeight) / 2;
// Calculate the window position to match the icon position.
tmpRectF.set(launcherIconBounds);
tmpRectF.offset(dragLayerBounds[0], dragLayerBounds[1]);
tmpRectF.offset(mDx.value, mDy.value);
Utilities.scaleRectFAboutCenter(tmpRectF, mIconScaleToFitScreen.value);
float windowTransX0 = tmpRectF.left - offsetX - crop.left * scale;
float windowTransY0 = tmpRectF.top - offsetY - crop.top * scale;
// Calculate the icon position.
floatingIconBounds.set(launcherIconBounds);
floatingIconBounds.offset(mDx.value, mDy.value);
Utilities.scaleRectFAboutCenter(floatingIconBounds, mIconScaleToFitScreen.value);
floatingIconBounds.left -= offsetX;
floatingIconBounds.top -= offsetY;
floatingIconBounds.right += offsetX;
floatingIconBounds.bottom += offsetY;
if (initOnly) {
// For the init pass, we want full alpha since the window is not yet ready.
floatingView.update(1f, 255, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true);
return;
}
ArrayList<SurfaceParams> params = new ArrayList<>();
for (int i = appTargets.length - 1; i >= 0; i--) {
RemoteAnimationTargetCompat target = appTargets[i];
SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash);
if (target.mode == MODE_OPENING) {
matrix.setScale(scale, scale);
if (rotationChange == 1) {
matrix.postTranslate(windowTransY0, mDeviceProfile.widthPx - (windowTransX0 + scaledCropWidth));
} else if (rotationChange == 2) {
matrix.postTranslate(mDeviceProfile.widthPx - (windowTransX0 + scaledCropWidth), mDeviceProfile.heightPx - (windowTransY0 + scaledCropHeight));
} else if (rotationChange == 3) {
matrix.postTranslate(mDeviceProfile.heightPx - (windowTransY0 + scaledCropHeight), windowTransX0);
} else {
matrix.postTranslate(windowTransX0, windowTransY0);
}
floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true);
builder.withMatrix(matrix).withWindowCrop(crop).withAlpha(1f - mIconAlpha.value).withCornerRadius(mWindowRadius.value).withShadowRadius(mShadowRadius.value);
} else if (target.mode == MODE_CLOSING) {
if (target.localBounds != null) {
final Rect localBounds = target.localBounds;
tmpPos.set(target.localBounds.left, target.localBounds.top);
} else {
tmpPos.set(target.position.x, target.position.y);
}
final Rect crop = new Rect(target.screenSpaceBounds);
crop.offsetTo(0, 0);
if ((rotationChange % 2) == 1) {
int tmp = crop.right;
crop.right = crop.bottom;
crop.bottom = tmp;
tmp = tmpPos.x;
tmpPos.x = tmpPos.y;
tmpPos.y = tmp;
}
matrix.setTranslate(tmpPos.x, tmpPos.y);
builder.withMatrix(matrix).withWindowCrop(crop).withAlpha(1f);
}
params.add(builder.build());
}
if (navBarTarget != null) {
final SurfaceParams.Builder navBuilder = new SurfaceParams.Builder(navBarTarget.leash);
if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
matrix.setScale(scale, scale);
matrix.postTranslate(windowTransX0, windowTransY0);
navBuilder.withMatrix(matrix).withWindowCrop(crop).withAlpha(mNavFadeIn.value);
} else {
navBuilder.withAlpha(mNavFadeOut.value);
}
params.add(navBuilder.build());
}
surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
}
};
appAnimator.addUpdateListener(listener);
// Since we added a start delay, call update here to init the FloatingIconView properly.
listener.onUpdate(0, true);
animatorSet.playTogether(appAnimator, getBackgroundAnimator(appTargets));
return animatorSet;
}
use of com.android.launcher3.BubbleTextView in project android_packages_apps_Launcher3 by crdroidandroid.
the class PredictionRowView method applyPredictionApps.
private void applyPredictionApps() {
if (getChildCount() != mNumPredictedAppsPerRow) {
while (getChildCount() > mNumPredictedAppsPerRow) {
removeViewAt(0);
}
LayoutInflater inflater = mLauncher.getAppsView().getLayoutInflater();
while (getChildCount() < mNumPredictedAppsPerRow) {
BubbleTextView icon = (BubbleTextView) inflater.inflate(R.layout.all_apps_icon, this, false);
icon.setOnClickListener(ItemClickHandler.INSTANCE);
icon.setOnLongClickListener(ItemLongClickListener.INSTANCE_ALL_APPS);
icon.setLongPressTimeoutFactor(1f);
icon.setOnFocusChangeListener(mFocusHelper);
LayoutParams lp = (LayoutParams) icon.getLayoutParams();
// Ensure the all apps icon height matches the workspace icons in portrait mode.
lp.height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
lp.width = 0;
lp.weight = 1;
addView(icon);
}
}
int predictionCount = mPredictedApps.size();
for (int i = 0; i < getChildCount(); i++) {
BubbleTextView icon = (BubbleTextView) getChildAt(i);
icon.reset();
if (predictionCount > i) {
icon.setVisibility(View.VISIBLE);
icon.applyFromWorkspaceItem(mPredictedApps.get(i));
} else {
icon.setVisibility(predictionCount == 0 ? GONE : INVISIBLE);
}
}
boolean predictionsEnabled = predictionCount > 0;
if (predictionsEnabled != mPredictionsEnabled) {
mPredictionsEnabled = predictionsEnabled;
mLauncher.reapplyUi(false);
updateVisibility();
}
mParent.onHeightUpdated();
}
use of com.android.launcher3.BubbleTextView in project android_packages_apps_Launcher3 by crdroidandroid.
the class FolderAnimationManager method addPreviewItemAnimators.
/**
* Animate the items on the current page.
*/
private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale, int previewItemOffsetX, int previewItemOffsetY) {
ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule();
boolean isOnFirstPage = mFolder.mContent.getCurrentPage() == 0;
final List<BubbleTextView> itemsInPreview = getPreviewIconsOnPage(isOnFirstPage ? 0 : mFolder.mContent.getCurrentPage());
final int numItemsInPreview = itemsInPreview.size();
final int numItemsInFirstPagePreview = isOnFirstPage ? numItemsInPreview : MAX_NUM_ITEMS_IN_PREVIEW;
TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator();
ShortcutAndWidgetContainer cwc = mContent.getPageAt(0).getShortcutsAndWidgets();
for (int i = 0; i < numItemsInPreview; ++i) {
final BubbleTextView btv = itemsInPreview.get(i);
CellLayout.LayoutParams btvLp = (CellLayout.LayoutParams) btv.getLayoutParams();
// Calculate the final values in the LayoutParams.
btvLp.isLockedToGrid = true;
cwc.setupLp(btv);
// Match scale of icons in the preview of the items on the first page.
float previewScale = rule.scaleForItem(numItemsInFirstPagePreview);
float previewSize = rule.getIconSize() * previewScale;
float iconScale = previewSize / itemsInPreview.get(i).getIconSize();
final float initialScale = iconScale / folderScale;
final float finalScale = 1f;
float scale = mIsOpening ? initialScale : finalScale;
btv.setScaleX(scale);
btv.setScaleY(scale);
// Match positions of the icons in the folder with their positions in the preview
rule.computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, mTmpParams);
// The PreviewLayoutRule assumes that the icon size takes up the entire width so we
// offset by the actual size.
int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
final int previewPosX = (int) ((mTmpParams.transX - iconOffsetX + previewItemOffsetX) / folderScale);
final float paddingTop = btv.getPaddingTop() * iconScale;
final int previewPosY = (int) ((mTmpParams.transY + previewItemOffsetY - paddingTop) / folderScale);
final float xDistance = previewPosX - btvLp.x;
final float yDistance = previewPosY - btvLp.y;
Animator translationX = getAnimator(btv, View.TRANSLATION_X, xDistance, 0f);
translationX.setInterpolator(previewItemInterpolator);
play(animatorSet, translationX);
Animator translationY = getAnimator(btv, View.TRANSLATION_Y, yDistance, 0f);
translationY.setInterpolator(previewItemInterpolator);
play(animatorSet, translationY);
Animator scaleAnimator = getAnimator(btv, SCALE_PROPERTY, initialScale, finalScale);
scaleAnimator.setInterpolator(previewItemInterpolator);
play(animatorSet, scaleAnimator);
if (mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW) {
// These delays allows the preview items to move as part of the Folder's motion,
// and its only necessary for large folders because of differing interpolators.
int delay = mIsOpening ? mDelay : mDelay * 2;
if (mIsOpening) {
translationX.setStartDelay(delay);
translationY.setStartDelay(delay);
scaleAnimator.setStartDelay(delay);
}
translationX.setDuration(translationX.getDuration() - delay);
translationY.setDuration(translationY.getDuration() - delay);
scaleAnimator.setDuration(scaleAnimator.getDuration() - delay);
}
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
// Necessary to initialize values here because of the start delay.
if (mIsOpening) {
btv.setTranslationX(xDistance);
btv.setTranslationY(yDistance);
btv.setScaleX(initialScale);
btv.setScaleY(initialScale);
}
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
btv.setTranslationX(0.0f);
btv.setTranslationY(0.0f);
btv.setScaleX(1f);
btv.setScaleY(1f);
}
});
}
}
use of com.android.launcher3.BubbleTextView in project android_packages_apps_Launcher3 by crdroidandroid.
the class FolderAnimationManager method getAnimator.
/**
* Prepares the Folder for animating between open / closed states.
*/
public AnimatorSet getAnimator() {
final BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) mFolder.getLayoutParams();
mFolderIcon.getPreviewItemManager().recomputePreviewDrawingParams();
ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule();
final List<BubbleTextView> itemsInPreview = getPreviewIconsOnPage(0);
// Match position of the FolderIcon
final Rect folderIconPos = new Rect();
float scaleRelativeToDragLayer = mFolder.mActivityContext.getDragLayer().getDescendantRectRelativeToSelf(mFolderIcon, folderIconPos);
int scaledRadius = mPreviewBackground.getScaledRadius();
float initialSize = (scaledRadius * 2) * scaleRelativeToDragLayer;
// Match size/scale of icons in the preview
float previewScale = rule.scaleForItem(itemsInPreview.size());
float previewSize = rule.getIconSize() * previewScale;
float initialScale = previewSize / itemsInPreview.get(0).getIconSize() * scaleRelativeToDragLayer;
final float finalScale = 1f;
float scale = mIsOpening ? initialScale : finalScale;
mFolder.setPivotX(0);
mFolder.setPivotY(0);
// Scale the contents of the folder.
mFolder.mContent.setScaleX(scale);
mFolder.mContent.setScaleY(scale);
mFolder.mContent.setPivotX(0);
mFolder.mContent.setPivotY(0);
mFolder.mFooter.setScaleX(scale);
mFolder.mFooter.setScaleY(scale);
mFolder.mFooter.setPivotX(0);
mFolder.mFooter.setPivotY(0);
// We want to create a small X offset for the preview items, so that they follow their
// expected path to their final locations. ie. an icon should not move right, if it's final
// location is to its left. This value is arbitrarily defined.
int previewItemOffsetX = (int) (previewSize / 2);
if (Utilities.isRtl(mContext.getResources())) {
previewItemOffsetX = (int) (lp.width * initialScale - initialSize - previewItemOffsetX);
}
final int paddingOffsetX = (int) (mContent.getPaddingLeft() * initialScale);
final int paddingOffsetY = (int) (mContent.getPaddingTop() * initialScale);
int initialX = folderIconPos.left + mFolder.getPaddingLeft() + mPreviewBackground.getOffsetX() - paddingOffsetX - previewItemOffsetX;
int initialY = folderIconPos.top + mFolder.getPaddingTop() + mPreviewBackground.getOffsetY() - paddingOffsetY;
final float xDistance = initialX - lp.x;
final float yDistance = initialY - lp.y;
// Set up the Folder background.
final int finalColor;
int folderFillColor = Themes.getAttrColor(mContext, R.attr.folderFillColor);
if (mIsOpening) {
finalColor = folderFillColor;
} else {
finalColor = mFolderBackground.getColor().getDefaultColor();
}
final int initialColor = setColorAlphaBound(folderFillColor, mPreviewBackground.getBackgroundAlpha());
mFolderBackground.mutate();
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
// Set up the reveal animation that clips the Folder.
int totalOffsetX = paddingOffsetX + previewItemOffsetX;
Rect startRect = new Rect(totalOffsetX, paddingOffsetY, Math.round((totalOffsetX + initialSize)), Math.round((paddingOffsetY + initialSize)));
Rect endRect = new Rect(0, 0, lp.width, lp.height);
float finalRadius = mFolderBackground.getCornerRadius();
// Create the animators.
AnimatorSet a = new AnimatorSet();
// Initialize the Folder items' text.
PropertyResetListener colorResetListener = new PropertyResetListener<>(TEXT_ALPHA_PROPERTY, 1f);
for (BubbleTextView icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
if (mIsOpening) {
icon.setTextVisibility(false);
}
ObjectAnimator anim = icon.createTextAlphaAnimator(mIsOpening);
anim.addListener(colorResetListener);
play(a, anim);
}
mBgColorAnimator = getAnimator(mFolderBackground, "color", initialColor, finalColor);
play(a, mBgColorAnimator);
play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
play(a, getAnimator(mFolder.mContent, SCALE_PROPERTY, initialScale, finalScale));
play(a, getAnimator(mFolder.mFooter, SCALE_PROPERTY, initialScale, finalScale));
final int footerAlphaDuration;
final int footerStartDelay;
if (isLargeFolder()) {
if (mIsOpening) {
footerAlphaDuration = LARGE_FOLDER_FOOTER_DURATION;
footerStartDelay = mDuration - footerAlphaDuration;
} else {
footerAlphaDuration = 0;
footerStartDelay = 0;
}
} else {
footerStartDelay = 0;
footerAlphaDuration = mDuration;
}
play(a, getAnimator(mFolder.mFooter, ALPHA, 0, 1f), footerStartDelay, footerAlphaDuration);
// Create reveal animator for the folder background
play(a, getShape().createRevealAnimator(mFolder, startRect, endRect, finalRadius, !mIsOpening));
// Create reveal animator for the folder content (capture the top 4 icons 2x2)
int width = mDeviceProfile.folderCellLayoutBorderSpacingPx + mDeviceProfile.folderCellWidthPx * 2;
int height = mDeviceProfile.folderCellLayoutBorderSpacingPx + mDeviceProfile.folderCellHeightPx * 2;
int page = mIsOpening ? mContent.getCurrentPage() : mContent.getDestinationPage();
int left = mContent.getPaddingLeft() + page * lp.width;
Rect contentStart = new Rect(left, 0, left + width, height);
Rect contentEnd = new Rect(left, 0, left + lp.width, lp.height);
play(a, getShape().createRevealAnimator(mFolder.getContent(), contentStart, contentEnd, finalRadius, !mIsOpening));
// Fade in the folder name, as the text can overlap the icons when grid size is small.
mFolder.mFolderName.setAlpha(mIsOpening ? 0f : 1f);
play(a, getAnimator(mFolder.mFolderName, View.ALPHA, 0, 1), mIsOpening ? FOLDER_NAME_ALPHA_DURATION : 0, mIsOpening ? mDuration - FOLDER_NAME_ALPHA_DURATION : FOLDER_NAME_ALPHA_DURATION);
// Translate the footer so that it tracks the bottom of the content.
float normalHeight = mFolder.getContentAreaHeight();
float scaledHeight = normalHeight * initialScale;
float diff = normalHeight - scaledHeight;
play(a, getAnimator(mFolder.mFooter, View.TRANSLATION_Y, -diff, 0f));
// Animate the elevation midway so that the shadow is not noticeable in the background.
int midDuration = mDuration / 2;
Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
play(a, z, mIsOpening ? midDuration : 0, midDuration);
// Store clip variables
CellLayout cellLayout = mContent.getCurrentCellLayout();
boolean folderClipChildren = mFolder.getClipChildren();
boolean folderClipToPadding = mFolder.getClipToPadding();
boolean contentClipChildren = mContent.getClipChildren();
boolean contentClipToPadding = mContent.getClipToPadding();
boolean cellLayoutClipChildren = cellLayout.getClipChildren();
boolean cellLayoutClipPadding = cellLayout.getClipToPadding();
mFolder.setClipChildren(false);
mFolder.setClipToPadding(false);
mContent.setClipChildren(false);
mContent.setClipToPadding(false);
cellLayout.setClipChildren(false);
cellLayout.setClipToPadding(false);
a.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mFolder.setTranslationX(0.0f);
mFolder.setTranslationY(0.0f);
mFolder.setTranslationZ(0.0f);
mFolder.mContent.setScaleX(1f);
mFolder.mContent.setScaleY(1f);
mFolder.mFooter.setScaleX(1f);
mFolder.mFooter.setScaleY(1f);
mFolder.mFooter.setTranslationX(0f);
mFolder.mFolderName.setAlpha(1f);
mFolder.setClipChildren(folderClipChildren);
mFolder.setClipToPadding(folderClipToPadding);
mContent.setClipChildren(contentClipChildren);
mContent.setClipToPadding(contentClipToPadding);
cellLayout.setClipChildren(cellLayoutClipChildren);
cellLayout.setClipToPadding(cellLayoutClipPadding);
}
});
// animators may use a different interpolator.
for (Animator animator : a.getChildAnimations()) {
animator.setInterpolator(mFolderInterpolator);
}
int radiusDiff = scaledRadius - mPreviewBackground.getRadius();
addPreviewItemAnimators(a, initialScale / scaleRelativeToDragLayer, // difference to keep the preview items centered.
previewItemOffsetX + radiusDiff, radiusDiff);
return a;
}
Aggregations