tweaking parallax effect
- adding vertical parallax when switching to all apps/customize mode - added effect to have parallax lag the rest of scrolling - adjusted the amount of horizontal/vertical parallax in both portrait and landscape modes Change-Id: I5ee778f78c1080337f642217bcf828b2392ddf70
This commit is contained in:
@@ -27,13 +27,13 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.SearchManager;
|
||||
import android.app.StatusBarManager;
|
||||
import android.app.WallpaperManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ActivityNotFoundException;
|
||||
@@ -77,7 +77,6 @@ import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.TextKeyListener;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -309,7 +308,6 @@ public final class Launcher extends Activity
|
||||
|
||||
loadHotseats();
|
||||
checkForLocaleChange();
|
||||
setWallpaperDimension();
|
||||
setContentView(R.layout.launcher);
|
||||
mHomeCustomizationDrawer = (TabHost) findViewById(R.id.customization_drawer);
|
||||
if (mHomeCustomizationDrawer != null) {
|
||||
@@ -547,18 +545,6 @@ public final class Launcher extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
private void setWallpaperDimension() {
|
||||
WallpaperManager wpm = (WallpaperManager)getSystemService(WALLPAPER_SERVICE);
|
||||
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
boolean isPortrait = display.getWidth() < display.getHeight();
|
||||
// find width and height when in portrait mode
|
||||
final int width = isPortrait ? display.getWidth() : display.getHeight();
|
||||
final int height = isPortrait ? display.getHeight() : display.getWidth();
|
||||
wpm.suggestDesiredDimensions((int) (Math.max(width, height) * 1.5f),
|
||||
Math.max(width, height));
|
||||
}
|
||||
|
||||
// Note: This doesn't do all the client-id magic that BrowserProvider does
|
||||
// in Browser. (http://b/2425179)
|
||||
private Uri getDefaultBrowserUri() {
|
||||
@@ -1002,6 +988,7 @@ public final class Launcher extends Activity
|
||||
workspace.setOnLongClickListener(this);
|
||||
workspace.setDragController(dragController);
|
||||
workspace.setLauncher(this);
|
||||
workspace.setWallpaperDimension();
|
||||
|
||||
deleteZone.setLauncher(this);
|
||||
deleteZone.setDragController(dragController);
|
||||
@@ -1426,8 +1413,10 @@ public final class Launcher extends Activity
|
||||
}
|
||||
if (!mWorkspace.isDefaultPageShowing()) {
|
||||
// on the phone, we don't animate the change to the workspace if all apps is visible
|
||||
mWorkspace.moveToDefaultScreen(alreadyOnHome &&
|
||||
(LauncherApplication.isScreenXLarge() || mState != State.ALL_APPS));
|
||||
boolean animate = alreadyOnHome &&
|
||||
(LauncherApplication.isScreenXLarge() || mState != State.ALL_APPS);
|
||||
mWorkspace.moveToDefaultScreen(animate);
|
||||
if (!animate) mWorkspace.updateWallpaperOffsetImmediately();
|
||||
}
|
||||
showWorkspace(alreadyOnHome);
|
||||
|
||||
@@ -2747,6 +2736,8 @@ public final class Launcher extends Activity
|
||||
toView.setVisibility(View.VISIBLE);
|
||||
hideAndShowToolbarButtons(toState, null, null);
|
||||
}
|
||||
mWorkspace.setVerticalWallpaperOffset(toAllApps ?
|
||||
Workspace.WallpaperVerticalOffset.TOP : Workspace.WallpaperVerticalOffset.BOTTOM);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2821,6 +2812,7 @@ public final class Launcher extends Activity
|
||||
hideAndShowToolbarButtons(State.WORKSPACE, null, null);
|
||||
}
|
||||
}
|
||||
mWorkspace.setVerticalWallpaperOffset(Workspace.WallpaperVerticalOffset.MIDDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2898,6 +2890,8 @@ public final class Launcher extends Activity
|
||||
toView.setVisibility(View.VISIBLE);
|
||||
hideAndShowToolbarButtons(toState, null, null);
|
||||
}
|
||||
mWorkspace.setVerticalWallpaperOffset((toState == State.ALL_APPS) ?
|
||||
Workspace.WallpaperVerticalOffset.TOP : Workspace.WallpaperVerticalOffset.BOTTOM);
|
||||
}
|
||||
|
||||
void showAllApps(boolean animated) {
|
||||
|
||||
@@ -888,6 +888,14 @@ public abstract class PagedView extends ViewGroup {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected float maxOverScroll() {
|
||||
// Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
|
||||
// exceed). Used to find out how much extra wallpaper we need for the overscroll effect
|
||||
float f = 1.0f;
|
||||
f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
|
||||
return OVERSCROLL_DAMP_FACTOR * f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
// Skip touch handling if there are no pages to swipe
|
||||
|
||||
@@ -203,6 +203,17 @@ public class Workspace extends SmoothPagedView
|
||||
private final Camera mCamera = new Camera();
|
||||
private final float mTempFloat2[] = new float[2];
|
||||
|
||||
enum WallpaperVerticalOffset { TOP, MIDDLE, BOTTOM };
|
||||
int mWallpaperWidth;
|
||||
int mWallpaperHeight;
|
||||
float mTargetHorizontalWallpaperOffset = 0.0f;
|
||||
float mTargetVerticalWallpaperOffset = 0.5f;
|
||||
float mHorizontalWallpaperOffset = 0.0f;
|
||||
float mVerticalWallpaperOffset = 0.5f;
|
||||
long mLastWallpaperOffsetUpdateTime;
|
||||
boolean mWallpaperOffsetDirty;
|
||||
boolean mUpdateWallpaperOffsetImmediately = false;
|
||||
|
||||
/**
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
@@ -386,17 +397,6 @@ public class Workspace extends SmoothPagedView
|
||||
return mCurrentPage == mDefaultPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current screen.
|
||||
*
|
||||
* @param currentPage
|
||||
*/
|
||||
@Override
|
||||
void setCurrentPage(int currentPage) {
|
||||
super.setCurrentPage(currentPage);
|
||||
updateWallpaperOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified child in the specified screen. The position and dimension of
|
||||
* the child are defined by x, y, spanX and spanY.
|
||||
@@ -558,23 +558,157 @@ public class Workspace extends SmoothPagedView
|
||||
Launcher.setScreen(mCurrentPage);
|
||||
};
|
||||
|
||||
private void updateWallpaperOffset() {
|
||||
if (LauncherApplication.isScreenXLarge()) {
|
||||
IBinder token = getWindowToken();
|
||||
int scrollRange = getChildOffset(getChildCount() - 1) - getChildOffset(0);
|
||||
if (token != null) {
|
||||
mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0);
|
||||
float offset = mScrollX / (float) scrollRange;
|
||||
mWallpaperManager.setWallpaperOffsets(getWindowToken(),
|
||||
Math.max(0.f, Math.min(offset, 1.0f)), 0);
|
||||
}
|
||||
// As a ratio of screen height, the total distance we want the parallax effect to span
|
||||
// vertically
|
||||
private float wallpaperTravelToScreenHeightRatio(int width, int height) {
|
||||
return 1.1f;
|
||||
}
|
||||
|
||||
// As a ratio of screen height, the total distance we want the parallax effect to span
|
||||
// horizontally
|
||||
private float wallpaperTravelToScreenWidthRatio(int width, int height) {
|
||||
float aspectRatio = width / (float) height;
|
||||
|
||||
// At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width
|
||||
// At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width
|
||||
// We will use these two data points to extrapolate how much the wallpaper parallax effect
|
||||
// to span (ie travel) at any aspect ratio:
|
||||
|
||||
final float ASPECT_RATIO_LANDSCAPE = 16/10f;
|
||||
final float ASPECT_RATIO_PORTRAIT = 10/16f;
|
||||
final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
|
||||
final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
|
||||
|
||||
// To find out the desired width at different aspect ratios, we use the following two
|
||||
// formulas, where the coefficient on x is the aspect ratio (width/height):
|
||||
// (16/10)x + y = 1.5
|
||||
// (10/16)x + y = 1.2
|
||||
// We solve for x and y and end up with a final formula:
|
||||
final float x =
|
||||
(WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
|
||||
(ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
|
||||
final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
|
||||
return x * aspectRatio + y;
|
||||
}
|
||||
|
||||
// The range of scroll values for Workspace
|
||||
private int getScrollRange() {
|
||||
return getChildOffset(getChildCount() - 1) - getChildOffset(0);
|
||||
}
|
||||
|
||||
protected void setWallpaperDimension() {
|
||||
WallpaperManager wpm =
|
||||
(WallpaperManager) mLauncher.getSystemService(Context.WALLPAPER_SERVICE);
|
||||
|
||||
Display display = mLauncher.getWindowManager().getDefaultDisplay();
|
||||
final int maxDim = Math.max(display.getWidth(), display.getHeight());
|
||||
final int minDim = Math.min(display.getWidth(), display.getHeight());
|
||||
|
||||
// We need to ensure that there is enough extra space in the wallpaper for the intended
|
||||
// parallax effects
|
||||
mWallpaperWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
|
||||
mWallpaperHeight = (int)(maxDim * wallpaperTravelToScreenHeightRatio(maxDim, minDim));
|
||||
wpm.suggestDesiredDimensions(mWallpaperWidth, mWallpaperHeight);
|
||||
}
|
||||
|
||||
public void setVerticalWallpaperOffset(WallpaperVerticalOffset offsetPosition) {
|
||||
float offset = 0.5f;
|
||||
Display display = mLauncher.getWindowManager().getDefaultDisplay();
|
||||
int wallpaperTravelHeight = (int) (display.getHeight() *
|
||||
wallpaperTravelToScreenHeightRatio(display.getWidth(), display.getHeight()));
|
||||
float offsetFromCenter = (wallpaperTravelHeight / mWallpaperHeight) / 2f;
|
||||
switch (offsetPosition) {
|
||||
case TOP:
|
||||
offset = 0.5f - offsetFromCenter;
|
||||
break;
|
||||
case MIDDLE:
|
||||
offset = 0.5f;
|
||||
break;
|
||||
case BOTTOM:
|
||||
offset = 0.5f + offsetFromCenter;
|
||||
break;
|
||||
}
|
||||
mTargetVerticalWallpaperOffset = offset;
|
||||
mWallpaperOffsetDirty = true;
|
||||
}
|
||||
|
||||
private void updateHorizontalWallpaperOffset() {
|
||||
if (LauncherApplication.isScreenXLarge()) {
|
||||
Display display = mLauncher.getWindowManager().getDefaultDisplay();
|
||||
// The wallpaper travel width is how far, from left to right, the wallpaper will move
|
||||
// at this orientation (for example, in portrait mode we don't move all the way to the
|
||||
// edges of the wallpaper, or otherwise the parallax effect would be too strong)
|
||||
int wallpaperTravelWidth = (int) (display.getWidth() *
|
||||
wallpaperTravelToScreenWidthRatio(display.getWidth(), display.getHeight()));
|
||||
|
||||
// Account for overscroll: you only see the absolute edge of the wallpaper if
|
||||
// you overscroll as far as you can in landscape mode
|
||||
int overscrollOffset = (int) (maxOverScroll() * display.getWidth());
|
||||
float overscrollRatio = overscrollOffset / (float) getScrollRange();
|
||||
int scrollRangeWithOverscroll = getScrollRange() + 2 * overscrollOffset;
|
||||
|
||||
// Set wallpaper offset steps (1 / (number of screens - 1))
|
||||
// We have 3 vertical offset states (centered, and then top/bottom aligned
|
||||
// for all apps/customize)
|
||||
mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f / (3 - 1));
|
||||
|
||||
float scrollProgress =
|
||||
mScrollX / (float) scrollRangeWithOverscroll + overscrollRatio;
|
||||
float offsetInDips = wallpaperTravelWidth * scrollProgress +
|
||||
(mWallpaperWidth - wallpaperTravelWidth) / 2;
|
||||
float offset = offsetInDips / (float) mWallpaperWidth;
|
||||
|
||||
mTargetHorizontalWallpaperOffset = Math.max(0f, Math.min(offset, 1.0f));
|
||||
mWallpaperOffsetDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateWallpaperOffsetImmediately() {
|
||||
mUpdateWallpaperOffsetImmediately = true;
|
||||
}
|
||||
|
||||
private void updateWallpaperOffsets(boolean immediate) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long millisecondsSinceLastUpdate = currentTime - mLastWallpaperOffsetUpdateTime;
|
||||
millisecondsSinceLastUpdate = Math.min((long) (1000/30f), millisecondsSinceLastUpdate);
|
||||
millisecondsSinceLastUpdate = Math.min(1L, millisecondsSinceLastUpdate);
|
||||
final float PERCENT_TO_CATCH_UP_IN_100_MS_HORIZONTAL = 25f;
|
||||
final float PERCENT_TO_CATCH_UP_IN_100_MS_VERTICAL = 25f;
|
||||
final float UPDATE_THRESHOLD = 0.0001f;
|
||||
float hOffsetDelta = mTargetHorizontalWallpaperOffset - mHorizontalWallpaperOffset;
|
||||
float vOffsetDelta = mTargetVerticalWallpaperOffset - mVerticalWallpaperOffset;
|
||||
boolean stopUpdating =
|
||||
Math.abs(hOffsetDelta / mTargetHorizontalWallpaperOffset) < UPDATE_THRESHOLD &&
|
||||
Math.abs(vOffsetDelta / mTargetVerticalWallpaperOffset) < UPDATE_THRESHOLD;
|
||||
|
||||
if (stopUpdating || immediate) {
|
||||
mHorizontalWallpaperOffset = mTargetHorizontalWallpaperOffset;
|
||||
mVerticalWallpaperOffset = mTargetVerticalWallpaperOffset;
|
||||
} else {
|
||||
float percentToCatchUpVertical =
|
||||
millisecondsSinceLastUpdate / 100f * PERCENT_TO_CATCH_UP_IN_100_MS_VERTICAL;
|
||||
float percentToCatchUpHorizontal =
|
||||
millisecondsSinceLastUpdate / 100f * PERCENT_TO_CATCH_UP_IN_100_MS_HORIZONTAL;
|
||||
mHorizontalWallpaperOffset += percentToCatchUpHorizontal * hOffsetDelta;
|
||||
mVerticalWallpaperOffset +=
|
||||
percentToCatchUpVertical * (mTargetVerticalWallpaperOffset - mVerticalWallpaperOffset);
|
||||
}
|
||||
IBinder token = getWindowToken();
|
||||
if (token != null) {
|
||||
mWallpaperManager.setWallpaperOffsets(getWindowToken(),
|
||||
mHorizontalWallpaperOffset, mVerticalWallpaperOffset);
|
||||
}
|
||||
if (!stopUpdating && !immediate) {
|
||||
invalidate();
|
||||
mWallpaperOffsetDirty = true;
|
||||
}
|
||||
mLastWallpaperOffsetUpdateTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computeScroll() {
|
||||
super.computeScroll();
|
||||
updateWallpaperOffset();
|
||||
updateHorizontalWallpaperOffset();
|
||||
}
|
||||
|
||||
public void showOutlines() {
|
||||
@@ -743,6 +877,9 @@ public class Workspace extends SmoothPagedView
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
|
||||
mUpdateWallpaperOffsetImmediately = true;
|
||||
}
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||
// if shrinkToBottom() is called on initialization, it has to be deferred
|
||||
@@ -783,6 +920,12 @@ public class Workspace extends SmoothPagedView
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mWallpaperOffsetDirty) {
|
||||
updateWallpaperOffsets(mUpdateWallpaperOffsetImmediately);
|
||||
mWallpaperOffsetDirty = false;
|
||||
mUpdateWallpaperOffsetImmediately = false;
|
||||
}
|
||||
|
||||
// Draw the background gradient if necessary
|
||||
if (mBackground != null && mBackgroundAlpha > 0.0f) {
|
||||
int alpha = (int) (mBackgroundAlpha * 255);
|
||||
|
||||
Reference in New Issue
Block a user