mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 02:38:20 +00:00
Merge "Scale Launcher folders on hover." into udc-qpr-dev
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.launcher3.folder;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
|
||||
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
|
||||
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
|
||||
import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
|
||||
@@ -627,7 +628,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
||||
Utilities.scaleRectAboutCenter(iconBounds, iconScale);
|
||||
|
||||
// If we are animating to the accepting state, animate the dot out.
|
||||
mDotParams.scale = Math.max(0, mDotScale - mBackground.getScaleProgress());
|
||||
mDotParams.scale = Math.max(0, mDotScale - mBackground.getAcceptScaleProgress());
|
||||
mDotParams.dotColor = mBackground.getDotColor();
|
||||
mDotRenderer.draw(canvas, mDotParams);
|
||||
}
|
||||
@@ -801,6 +802,14 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHoverChanged(boolean hovered) {
|
||||
super.onHoverChanged(hovered);
|
||||
if (ENABLE_CURSOR_HOVER_STATES.get()) {
|
||||
mBackground.setHovered(hovered);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface that provides callbacks to a parent ViewGroup that hosts this FolderIcon.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.launcher3.folder;
|
||||
|
||||
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
|
||||
import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
|
||||
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
|
||||
import static com.android.launcher3.graphics.IconShape.getShape;
|
||||
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
|
||||
@@ -39,6 +41,9 @@ import android.graphics.Region;
|
||||
import android.graphics.Shader;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
@@ -55,7 +60,10 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
|
||||
private static final boolean DRAW_SHADOW = false;
|
||||
private static final boolean DRAW_STROKE = false;
|
||||
|
||||
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
|
||||
@VisibleForTesting protected static final int CONSUMPTION_ANIMATION_DURATION = 100;
|
||||
|
||||
@VisibleForTesting protected static final float HOVER_SCALE = 1.1f;
|
||||
@VisibleForTesting protected static final int HOVER_ANIMATION_DURATION = 300;
|
||||
|
||||
private final PorterDuffXfermode mShadowPorterDuffXfermode
|
||||
= new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
|
||||
@@ -86,17 +94,21 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
|
||||
public boolean isClipping = true;
|
||||
|
||||
// Drawing / animation configurations
|
||||
private static final float ACCEPT_SCALE_FACTOR = 1.20f;
|
||||
@VisibleForTesting protected static final float ACCEPT_SCALE_FACTOR = 1.20f;
|
||||
|
||||
// Expressed on a scale from 0 to 255.
|
||||
private static final int BG_OPACITY = 255;
|
||||
private static final int MAX_BG_OPACITY = 255;
|
||||
private static final int SHADOW_OPACITY = 40;
|
||||
|
||||
private ValueAnimator mScaleAnimator;
|
||||
@VisibleForTesting protected ValueAnimator mScaleAnimator;
|
||||
private ObjectAnimator mStrokeAlphaAnimator;
|
||||
private ObjectAnimator mShadowAnimator;
|
||||
|
||||
@VisibleForTesting protected boolean mIsAccepting;
|
||||
@VisibleForTesting protected boolean mIsHovered;
|
||||
@VisibleForTesting protected boolean mIsHoveredOrAnimating;
|
||||
|
||||
private static final Property<PreviewBackground, Integer> STROKE_ALPHA =
|
||||
new Property<PreviewBackground, Integer>(Integer.class, "strokeAlpha") {
|
||||
@Override
|
||||
@@ -203,11 +215,11 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the progress of the scale animation, where 0 means the scale is at 1f
|
||||
* and 1 means the scale is at ACCEPT_SCALE_FACTOR.
|
||||
* Returns the progress of the scale animation to accept state, where 0 means the scale is at
|
||||
* 1f and 1 means the scale is at ACCEPT_SCALE_FACTOR. Returns 0 when scaled due to hover.
|
||||
*/
|
||||
float getScaleProgress() {
|
||||
return (mScale - 1f) / (ACCEPT_SCALE_FACTOR - 1f);
|
||||
float getAcceptScaleProgress() {
|
||||
return mIsHoveredOrAnimating ? 0 : (mScale - 1f) / (ACCEPT_SCALE_FACTOR - 1f);
|
||||
}
|
||||
|
||||
void invalidate() {
|
||||
@@ -385,60 +397,70 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
|
||||
return mDrawingDelegate != null;
|
||||
}
|
||||
|
||||
private void animateScale(float finalScale, final Runnable onStart, final Runnable onEnd) {
|
||||
final float scale0 = mScale;
|
||||
final float scale1 = finalScale;
|
||||
|
||||
protected void animateScale(boolean isAccepting, boolean isHovered) {
|
||||
if (mScaleAnimator != null) {
|
||||
mScaleAnimator.cancel();
|
||||
}
|
||||
|
||||
mScaleAnimator = ValueAnimator.ofFloat(0f, 1.0f);
|
||||
|
||||
mScaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
float prog = animation.getAnimatedFraction();
|
||||
mScale = prog * scale1 + (1 - prog) * scale0;
|
||||
invalidate();
|
||||
final float startScale = mScale;
|
||||
final float endScale = isAccepting ? ACCEPT_SCALE_FACTOR : (isHovered ? HOVER_SCALE : 1f);
|
||||
Interpolator interpolator =
|
||||
isAccepting != mIsAccepting ? ACCELERATE_DECELERATE : EMPHASIZED_DECELERATE;
|
||||
int duration = isAccepting != mIsAccepting ? CONSUMPTION_ANIMATION_DURATION
|
||||
: HOVER_ANIMATION_DURATION;
|
||||
mIsAccepting = isAccepting;
|
||||
mIsHovered = isHovered;
|
||||
if (startScale == endScale) {
|
||||
if (!mIsAccepting) {
|
||||
clearDrawingDelegate();
|
||||
}
|
||||
mIsHoveredOrAnimating = mIsHovered;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mScaleAnimator = ValueAnimator.ofFloat(0f, 1.0f);
|
||||
mScaleAnimator.addUpdateListener(animation -> {
|
||||
float prog = animation.getAnimatedFraction();
|
||||
mScale = prog * endScale + (1 - prog) * startScale;
|
||||
invalidate();
|
||||
});
|
||||
mScaleAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
if (onStart != null) {
|
||||
onStart.run();
|
||||
if (mIsHovered) {
|
||||
mIsHoveredOrAnimating = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (onEnd != null) {
|
||||
onEnd.run();
|
||||
if (!mIsAccepting) {
|
||||
clearDrawingDelegate();
|
||||
}
|
||||
mIsHoveredOrAnimating = mIsHovered;
|
||||
mScaleAnimator = null;
|
||||
}
|
||||
});
|
||||
|
||||
mScaleAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
|
||||
mScaleAnimator.setInterpolator(interpolator);
|
||||
mScaleAnimator.setDuration(duration);
|
||||
mScaleAnimator.start();
|
||||
}
|
||||
|
||||
public void animateToAccept(CellLayout cl, int cellX, int cellY) {
|
||||
animateScale(ACCEPT_SCALE_FACTOR, () -> delegateDrawing(cl, cellX, cellY), null);
|
||||
delegateDrawing(cl, cellX, cellY);
|
||||
animateScale(/* isAccepting= */ true, mIsHovered);
|
||||
}
|
||||
|
||||
public void animateToRest() {
|
||||
// This can be called multiple times -- we need to make sure the drawing delegate
|
||||
// is saved and restored at the beginning of the animation, since cancelling the
|
||||
// existing animation can clear the delgate.
|
||||
CellLayout cl = mDrawingDelegate;
|
||||
int cellX = mDelegateCellX;
|
||||
int cellY = mDelegateCellY;
|
||||
animateScale(1f, () -> delegateDrawing(cl, cellX, cellY), this::clearDrawingDelegate);
|
||||
animateScale(/* isAccepting= */ false, mIsHovered);
|
||||
}
|
||||
|
||||
public float getStrokeWidth() {
|
||||
return mStrokeWidth;
|
||||
}
|
||||
|
||||
protected void setHovered(boolean hovered) {
|
||||
animateScale(mIsAccepting, /* isHovered= */ hovered);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.folder;
|
||||
|
||||
import static com.android.launcher3.folder.PreviewBackground.ACCEPT_SCALE_FACTOR;
|
||||
import static com.android.launcher3.folder.PreviewBackground.CONSUMPTION_ANIMATION_DURATION;
|
||||
import static com.android.launcher3.folder.PreviewBackground.HOVER_ANIMATION_DURATION;
|
||||
import static com.android.launcher3.folder.PreviewBackground.HOVER_SCALE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.launcher3.CellLayout;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
public class PreviewBackgroundTest {
|
||||
|
||||
private static final float REST_SCALE = 1f;
|
||||
private static final float EPSILON = 0.00001f;
|
||||
|
||||
@Mock
|
||||
CellLayout mCellLayout;
|
||||
|
||||
private final PreviewBackground mPreviewBackground = new PreviewBackground();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mPreviewBackground.mScale = REST_SCALE;
|
||||
mPreviewBackground.mIsAccepting = false;
|
||||
mPreviewBackground.mIsHovered = false;
|
||||
mPreviewBackground.mIsHoveredOrAnimating = false;
|
||||
mPreviewBackground.invalidate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_restToHovered() {
|
||||
mPreviewBackground.setHovered(true);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, HOVER_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
HOVER_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator() instanceof PathInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_restToNotHovered() {
|
||||
mPreviewBackground.setHovered(false);
|
||||
|
||||
assertEquals("Scale changed.", mPreviewBackground.mScale, REST_SCALE, EPSILON);
|
||||
assertNull("Animator not null.", mPreviewBackground.mScaleAnimator);
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_hoveredToHovered() {
|
||||
mPreviewBackground.mScale = HOVER_SCALE;
|
||||
mPreviewBackground.mIsHovered = true;
|
||||
mPreviewBackground.mIsHoveredOrAnimating = true;
|
||||
mPreviewBackground.invalidate();
|
||||
|
||||
mPreviewBackground.setHovered(true);
|
||||
|
||||
assertEquals("Scale changed.", mPreviewBackground.mScale, HOVER_SCALE, EPSILON);
|
||||
assertNull("Animator not null.", mPreviewBackground.mScaleAnimator);
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_hoveredToRest() {
|
||||
mPreviewBackground.mScale = HOVER_SCALE;
|
||||
mPreviewBackground.mIsHovered = true;
|
||||
mPreviewBackground.mIsHoveredOrAnimating = true;
|
||||
mPreviewBackground.invalidate();
|
||||
|
||||
mPreviewBackground.setHovered(false);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, REST_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
HOVER_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator() instanceof PathInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_restToAccept() {
|
||||
mPreviewBackground.animateToAccept(mCellLayout, 0, 0);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale changed.", mPreviewBackground.mScale, ACCEPT_SCALE_FACTOR, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
CONSUMPTION_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator()
|
||||
instanceof AccelerateDecelerateInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 1.", mPreviewBackground.getAcceptScaleProgress(), 1,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_restToRest() {
|
||||
mPreviewBackground.animateToRest();
|
||||
|
||||
assertEquals("Scale changed.", mPreviewBackground.mScale, REST_SCALE, EPSILON);
|
||||
assertNull("Animator not null.", mPreviewBackground.mScaleAnimator);
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_acceptToRest() {
|
||||
mPreviewBackground.mScale = ACCEPT_SCALE_FACTOR;
|
||||
mPreviewBackground.mIsAccepting = true;
|
||||
mPreviewBackground.invalidate();
|
||||
|
||||
mPreviewBackground.animateToRest();
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, REST_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
CONSUMPTION_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator()
|
||||
instanceof AccelerateDecelerateInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_acceptToHover() {
|
||||
mPreviewBackground.mScale = ACCEPT_SCALE_FACTOR;
|
||||
mPreviewBackground.mIsAccepting = true;
|
||||
mPreviewBackground.invalidate();
|
||||
|
||||
mPreviewBackground.mIsAccepting = false;
|
||||
mPreviewBackground.setHovered(true);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, HOVER_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
HOVER_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator() instanceof PathInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_hoverToAccept() {
|
||||
mPreviewBackground.mScale = HOVER_SCALE;
|
||||
mPreviewBackground.mIsHovered = true;
|
||||
mPreviewBackground.mIsHoveredOrAnimating = true;
|
||||
mPreviewBackground.invalidate();
|
||||
|
||||
mPreviewBackground.animateToAccept(mCellLayout, 0, 0);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, ACCEPT_SCALE_FACTOR, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
CONSUMPTION_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator()
|
||||
instanceof AccelerateDecelerateInterpolator);
|
||||
mPreviewBackground.mIsHovered = false;
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 1.", mPreviewBackground.getAcceptScaleProgress(), 1,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_midwayToHoverToAccept() {
|
||||
mPreviewBackground.setHovered(true);
|
||||
runAnimationToFraction(0.5f);
|
||||
assertTrue("Scale not changed.",
|
||||
mPreviewBackground.mScale > REST_SCALE && mPreviewBackground.mScale < HOVER_SCALE);
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
|
||||
mPreviewBackground.animateToAccept(mCellLayout, 0, 0);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, ACCEPT_SCALE_FACTOR, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
CONSUMPTION_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator()
|
||||
instanceof AccelerateDecelerateInterpolator);
|
||||
mPreviewBackground.mIsHovered = false;
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 1.", mPreviewBackground.getAcceptScaleProgress(), 1,
|
||||
EPSILON);
|
||||
assertNull("Animator not null.", mPreviewBackground.mScaleAnimator);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_partWayToAcceptToHover() {
|
||||
mPreviewBackground.animateToAccept(mCellLayout, 0, 0);
|
||||
runAnimationToFraction(0.25f);
|
||||
assertTrue("Scale not changed part way.", mPreviewBackground.mScale > REST_SCALE
|
||||
&& mPreviewBackground.mScale < ACCEPT_SCALE_FACTOR);
|
||||
|
||||
mPreviewBackground.mIsAccepting = false;
|
||||
mPreviewBackground.setHovered(true);
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, HOVER_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
HOVER_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator() instanceof PathInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_midwayToAcceptEqualsHover() {
|
||||
mPreviewBackground.animateToAccept(mCellLayout, 0, 0);
|
||||
runAnimationToFraction(0.5f);
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, HOVER_SCALE, EPSILON);
|
||||
mPreviewBackground.mIsAccepting = false;
|
||||
|
||||
mPreviewBackground.setHovered(true);
|
||||
|
||||
assertEquals("Scale changed.", mPreviewBackground.mScale, HOVER_SCALE, EPSILON);
|
||||
assertNull("Animator not null.", mPreviewBackground.mScaleAnimator);
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_midwayToHoverToRest() {
|
||||
mPreviewBackground.setHovered(true);
|
||||
runAnimationToFraction(0.5f);
|
||||
assertTrue("Scale not changed midway.",
|
||||
mPreviewBackground.mScale > REST_SCALE && mPreviewBackground.mScale < HOVER_SCALE);
|
||||
|
||||
mPreviewBackground.mIsHovered = false;
|
||||
mPreviewBackground.animateToRest();
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, REST_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
HOVER_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator() instanceof PathInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimateScale_midwayToAcceptToRest() {
|
||||
mPreviewBackground.animateToAccept(mCellLayout, 0, 0);
|
||||
runAnimationToFraction(0.5f);
|
||||
assertTrue("Scale not changed.", mPreviewBackground.mScale > REST_SCALE
|
||||
&& mPreviewBackground.mScale < ACCEPT_SCALE_FACTOR);
|
||||
|
||||
mPreviewBackground.animateToRest();
|
||||
runAnimationToFraction(1f);
|
||||
|
||||
assertEquals("Scale not changed.", mPreviewBackground.mScale, REST_SCALE, EPSILON);
|
||||
assertEquals("Duration not correct.", mPreviewBackground.mScaleAnimator.getDuration(),
|
||||
CONSUMPTION_ANIMATION_DURATION);
|
||||
assertTrue("Wrong interpolator used.",
|
||||
mPreviewBackground.mScaleAnimator.getInterpolator()
|
||||
instanceof AccelerateDecelerateInterpolator);
|
||||
endAnimation();
|
||||
assertEquals("Scale progress not 0.", mPreviewBackground.getAcceptScaleProgress(), 0,
|
||||
EPSILON);
|
||||
}
|
||||
|
||||
private void runAnimationToFraction(float animationFraction) {
|
||||
mPreviewBackground.mScaleAnimator.setCurrentFraction(animationFraction);
|
||||
}
|
||||
|
||||
private void endAnimation() {
|
||||
mPreviewBackground.mScaleAnimator.end();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user