mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 18:58:19 +00:00
3029324 wip: Drop target crossfades as it moves from position to position
This commit is contained in:
committed by
Patrick Dubroy
parent
f34bab59fc
commit
150fbab7de
@@ -38,4 +38,11 @@
|
||||
the drag view should be offset from the position of the original view. -->
|
||||
<integer name="config_dragViewOffsetX">0</integer>
|
||||
<integer name="config_dragViewOffsetY">12</integer>
|
||||
|
||||
<!-- The duration (in ms) of the fade animation on the object outlines, used when
|
||||
we are dragging objects around on the home screen. -->
|
||||
<integer name="config_dragOutlineFadeTime">900</integer>
|
||||
|
||||
<!-- The alpha value at which to show the most recent drop visualization outline. -->
|
||||
<integer name="config_dragOutlineMaxAlpha">180</integer>
|
||||
</resources>
|
||||
|
||||
@@ -31,13 +31,14 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewDebug;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.LayoutAnimationController;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -79,15 +80,23 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
private Drawable mBackground;
|
||||
private Drawable mBackgroundMini;
|
||||
private Drawable mBackgroundMiniHover;
|
||||
// If we're actively dragging something over this screen and it's small,
|
||||
// mHover is true
|
||||
// If we're actively dragging something over this screen and it's small, mHover is true
|
||||
private boolean mHover = false;
|
||||
|
||||
private final RectF mDragRect = new RectF();
|
||||
private final Point mDragCenter = new Point();
|
||||
|
||||
private Drawable mDragRectDrawable;
|
||||
|
||||
// These arrays are used to implement the drag visualization on x-large screens.
|
||||
// They are used as circular arrays, indexed by mDragRectCurrent.
|
||||
private Rect[] mDragRects = new Rect[8];
|
||||
private int[] mDragRectAlphas = new int[mDragRects.length];
|
||||
private InterruptibleInOutAnimator[] mDragRectAnims =
|
||||
new InterruptibleInOutAnimator[mDragRects.length];
|
||||
|
||||
// Used as an index into the above 3 arrays; indicates which is the most current value.
|
||||
private int mDragRectCurrent = 0;
|
||||
|
||||
private Drawable mCrosshairsDrawable = null;
|
||||
private ValueAnimator mCrosshairsAnimator = null;
|
||||
private float mCrosshairsVisibility = 0.0f;
|
||||
@@ -139,15 +148,18 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
if (LauncherApplication.isScreenXLarge()) {
|
||||
final Resources res = getResources();
|
||||
|
||||
mBackgroundMini = getResources().getDrawable(R.drawable.mini_home_screen_bg);
|
||||
mBackgroundMini = res.getDrawable(R.drawable.mini_home_screen_bg);
|
||||
mBackgroundMini.setFilterBitmap(true);
|
||||
mBackground = getResources().getDrawable(R.drawable.home_screen_bg);
|
||||
mBackground = res.getDrawable(R.drawable.home_screen_bg);
|
||||
mBackground.setFilterBitmap(true);
|
||||
mBackgroundMiniHover = getResources().getDrawable(R.drawable.mini_home_screen_bg_hover);
|
||||
mBackgroundMiniHover = res.getDrawable(R.drawable.mini_home_screen_bg_hover);
|
||||
mBackgroundMiniHover.setFilterBitmap(true);
|
||||
|
||||
// Initialize the data structures used for the drag visualization.
|
||||
|
||||
mDragRectDrawable = res.getDrawable(R.drawable.rounded_rect_green);
|
||||
mCrosshairsDrawable = res.getDrawable(R.drawable.gardening_crosshairs);
|
||||
Interpolator interp = new DecelerateInterpolator(2.5f); // Quint ease out
|
||||
|
||||
// Set up the animation for fading the crosshairs in and out
|
||||
int animDuration = res.getInteger(R.integer.config_crosshairsFadeInTime);
|
||||
@@ -158,6 +170,32 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
CellLayout.this.invalidate();
|
||||
}
|
||||
});
|
||||
mCrosshairsAnimator.setInterpolator(interp);
|
||||
|
||||
for (int i = 0; i < mDragRects.length; i++) {
|
||||
mDragRects[i] = new Rect();
|
||||
}
|
||||
|
||||
// When dragging things around the home screens, we show a green outline of
|
||||
// where the item will land. The outlines gradually fade out, leaving a trail
|
||||
// behind the drag path.
|
||||
// Set up all the animations that are used to implement this fading.
|
||||
final int duration = res.getInteger(R.integer.config_dragOutlineFadeTime);
|
||||
final int fromAlphaValue = 0;
|
||||
final int toAlphaValue = res.getInteger(R.integer.config_dragOutlineMaxAlpha);
|
||||
for (int i = 0; i < mDragRectAnims.length; i++) {
|
||||
final InterruptibleInOutAnimator anim =
|
||||
new InterruptibleInOutAnimator(duration, fromAlphaValue, toAlphaValue);
|
||||
anim.setInterpolator(interp);
|
||||
final int thisIndex = i;
|
||||
anim.addUpdateListener(new AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
mDragRectAlphas[thisIndex] = (Integer) animation.getAnimatedValue();
|
||||
CellLayout.this.invalidate(mDragRects[thisIndex]);
|
||||
}
|
||||
});
|
||||
mDragRectAnims[i] = anim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,16 +238,6 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
final int countX = mCountX;
|
||||
final int countY = mCountY;
|
||||
|
||||
if (!mDragRect.isEmpty()) {
|
||||
mDragRectDrawable.setBounds(
|
||||
(int)mDragRect.left,
|
||||
(int)mDragRect.top,
|
||||
(int)mDragRect.right,
|
||||
(int)mDragRect.bottom);
|
||||
mDragRectDrawable.setAlpha((int) (mCrosshairsVisibility * 255));
|
||||
mDragRectDrawable.draw(canvas);
|
||||
}
|
||||
|
||||
final float MAX_ALPHA = 0.4f;
|
||||
final int MAX_VISIBLE_DISTANCE = 600;
|
||||
final float DISTANCE_MULTIPLIER = 0.002f;
|
||||
@@ -236,6 +264,15 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
}
|
||||
x += mCellWidth + mWidthGap;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mDragRects.length; i++) {
|
||||
int alpha = mDragRectAlphas[i];
|
||||
if (alpha > 0) {
|
||||
mDragRectDrawable.setAlpha(alpha);
|
||||
mDragRectDrawable.setBounds(mDragRects[i]);
|
||||
mDragRectDrawable.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,13 +788,23 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
final int left = topLeft[0];
|
||||
final int top = topLeft[1];
|
||||
|
||||
// Now find the bottom right
|
||||
final int[] bottomRight = mTmpPoint;
|
||||
cellToPoint(nearest[0] + spanX - 1, nearest[1] + spanY - 1, bottomRight);
|
||||
bottomRight[0] += mCellWidth;
|
||||
bottomRight[1] += mCellHeight;
|
||||
mDragRect.set(left, top, bottomRight[0], bottomRight[1]);
|
||||
invalidate();
|
||||
final Rect dragRect = mDragRects[mDragRectCurrent];
|
||||
|
||||
if (dragRect.isEmpty() || left != dragRect.left || top != dragRect.top) {
|
||||
// Now find the bottom right
|
||||
final int[] bottomRight = mTmpPoint;
|
||||
cellToPoint(nearest[0] + spanX - 1, nearest[1] + spanY - 1, bottomRight);
|
||||
bottomRight[0] += mCellWidth;
|
||||
bottomRight[1] += mCellHeight;
|
||||
|
||||
final int oldIndex = mDragRectCurrent;
|
||||
mDragRectCurrent = (oldIndex + 1) % mDragRects.length;
|
||||
|
||||
mDragRects[mDragRectCurrent].set(left, top, bottomRight[0], bottomRight[1]);
|
||||
|
||||
mDragRectAnims[oldIndex].animateOut();
|
||||
mDragRectAnims[mDragRectCurrent].animateIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,6 +1020,10 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
if (mCrosshairsAnimator != null) {
|
||||
animateCrosshairsTo(0.0f);
|
||||
}
|
||||
|
||||
mDragRectAnims[mDragRectCurrent].animateOut();
|
||||
mDragRectCurrent = (mDragRectCurrent + 1) % mDragRects.length;
|
||||
mDragRects[mDragRectCurrent].setEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1015,7 +1066,6 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
* or it may have begun on another layout.
|
||||
*/
|
||||
void onDragEnter(View dragView) {
|
||||
mDragRect.setEmpty();
|
||||
// Fade in the drag indicators
|
||||
if (mCrosshairsAnimator != null) {
|
||||
animateCrosshairsTo(1.0f);
|
||||
|
||||
69
src/com/android/launcher2/InterruptibleInOutAnimator.java
Normal file
69
src/com/android/launcher2/InterruptibleInOutAnimator.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.launcher2;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A convenience class for two-way animations, e.g. a fadeIn/fadeOut animation.
|
||||
* With a regular ValueAnimator, if you call reverse to show the 'out' animation, you'll get
|
||||
* a frame-by-frame mirror of the 'in' animation -- i.e., the interpolated values will
|
||||
* be exactly reversed. Using this class, both the 'in' and the 'out' animation use the
|
||||
* interpolator in the same direction.
|
||||
*/
|
||||
public class InterruptibleInOutAnimator extends ValueAnimator {
|
||||
private long mOriginalDuration;
|
||||
private Object mOriginalFromValue;
|
||||
private Object mOriginalToValue;
|
||||
|
||||
public InterruptibleInOutAnimator(long duration, Object fromValue, Object toValue) {
|
||||
super(duration, fromValue, toValue);
|
||||
mOriginalDuration = duration;
|
||||
mOriginalFromValue = fromValue;
|
||||
mOriginalToValue = toValue;
|
||||
}
|
||||
|
||||
private void animate(Object fromValue, Object toValue) {
|
||||
// This only makes sense when it's running in the opposite direction, or stopped.
|
||||
setDuration(mOriginalDuration - getCurrentPlayTime());
|
||||
|
||||
final Object startValue = isRunning() ? getAnimatedValue() : fromValue;
|
||||
cancel();
|
||||
setValues(startValue, toValue);
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the equivalent of calling Animator.start(), except that it can be called when
|
||||
* the animation is running in the opposite direction, in which case we reverse
|
||||
* direction and animate for a correspondingly shorter duration.
|
||||
*/
|
||||
public void animateIn() {
|
||||
animate(mOriginalFromValue, mOriginalToValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the roughly the equivalent of calling Animator.reverse(), except that it uses the
|
||||
* same interpolation curve as animateIn(), rather than mirroring it. Also, like animateIn(),
|
||||
* if the animation is currently running in the opposite direction, we reverse
|
||||
* direction and animate for a correspondingly shorter duration.
|
||||
*/
|
||||
public void animateOut() {
|
||||
animate(mOriginalToValue, mOriginalFromValue);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user