Improve wallpaper cropping
- Add support for tablets - Add support for parallax with user-cropped images - Improve behavior in landscape Change-Id: I50c4bba59b03d26d595a086a9ea425894f341705
|
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 5.5 MiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 702 KiB After Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 470 KiB After Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 768 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 389 KiB After Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 736 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 885 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 658 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 726 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 451 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 436 KiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 262 KiB After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 421 KiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 18 KiB |
@@ -55,10 +55,6 @@
|
||||
<item name="android:windowActionModeOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.WallpaperPicker">
|
||||
<item name="android:screenOrientation">unspecified</item>
|
||||
</style>
|
||||
|
||||
<style name="WorkspaceIcon.Portrait.AppsCustomize">
|
||||
<item name="android:shadowRadius">0.0</item> <!-- Don't use text shadow -->
|
||||
<item name="android:background">@null</item>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* Copyright (C) 2009 Google Inc.
|
||||
*
|
||||
* 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string-array name="wallpapers" translatable="false">
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
@@ -79,17 +80,30 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
|
||||
return new RectF(cropLeft, cropTop, cropRight, cropBottom);
|
||||
}
|
||||
|
||||
public Point getSourceDimensions() {
|
||||
return new Point(mRenderer.source.getImageWidth(), mRenderer.source.getImageHeight());
|
||||
}
|
||||
|
||||
public void setTileSource(TileSource source, Runnable isReadyCallback) {
|
||||
super.setTileSource(source, isReadyCallback);
|
||||
updateMinScale(getWidth(), getHeight(), source);
|
||||
updateMinScale(getWidth(), getHeight(), source, true);
|
||||
}
|
||||
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
updateMinScale(w, h, mRenderer.source);
|
||||
updateMinScale(w, h, mRenderer.source, false);
|
||||
}
|
||||
|
||||
private void updateMinScale(int w, int h, TileSource source) {
|
||||
public void setScale(float scale) {
|
||||
synchronized (mLock) {
|
||||
mRenderer.scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMinScale(int w, int h, TileSource source, boolean resetScale) {
|
||||
synchronized (mLock) {
|
||||
if (resetScale) {
|
||||
mRenderer.scale = 1;
|
||||
}
|
||||
if (source != null) {
|
||||
mMinScale = Math.max(w / (float) source.getImageWidth(),
|
||||
h / (float) source.getImageHeight());
|
||||
|
||||
@@ -62,6 +62,7 @@ public class WallpaperCropActivity extends Activity {
|
||||
|
||||
protected class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
|
||||
Uri mInUri = null;
|
||||
int mInResId = 0;
|
||||
InputStream mInStream;
|
||||
RectF mCropBounds = null;
|
||||
int mOutWidth, mOutHeight;
|
||||
@@ -71,9 +72,10 @@ public class WallpaperCropActivity extends Activity {
|
||||
boolean mSetWallpaper;
|
||||
boolean mSaveCroppedBitmap;
|
||||
Bitmap mCroppedBitmap;
|
||||
Runnable mOnEndRunnable;
|
||||
|
||||
public BitmapCropTask(Uri inUri, RectF cropBounds, int outWidth, int outHeight,
|
||||
boolean setWallpaper, boolean saveCroppedBitmap) {
|
||||
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
|
||||
mInUri = inUri;
|
||||
mCropBounds = cropBounds;
|
||||
mOutWidth = outWidth;
|
||||
@@ -81,17 +83,35 @@ public class WallpaperCropActivity extends Activity {
|
||||
mWPManager = WallpaperManager.getInstance(getApplicationContext());
|
||||
mSetWallpaper = setWallpaper;
|
||||
mSaveCroppedBitmap = saveCroppedBitmap;
|
||||
mOnEndRunnable = onEndRunnable;
|
||||
}
|
||||
|
||||
public BitmapCropTask(int inResId, RectF cropBounds, int outWidth, int outHeight,
|
||||
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
|
||||
mInResId = inResId;
|
||||
mCropBounds = cropBounds;
|
||||
mOutWidth = outWidth;
|
||||
mOutHeight = outHeight;
|
||||
mWPManager = WallpaperManager.getInstance(getApplicationContext());
|
||||
mSetWallpaper = setWallpaper;
|
||||
mSaveCroppedBitmap = saveCroppedBitmap;
|
||||
mOnEndRunnable = onEndRunnable;
|
||||
}
|
||||
|
||||
// Helper to setup input stream
|
||||
private void regenerateInputStream() {
|
||||
if (mInUri == null) {
|
||||
Log.w(LOGTAG, "cannot read original file, no input URI given");
|
||||
if (mInUri == null && mInResId == 0) {
|
||||
Log.w(LOGTAG, "cannot read original file, no input URI or resource ID given");
|
||||
} else {
|
||||
Utils.closeSilently(mInStream);
|
||||
try {
|
||||
mInStream = new BufferedInputStream(
|
||||
getContentResolver().openInputStream(mInUri));
|
||||
if (mInUri != null) {
|
||||
mInStream = new BufferedInputStream(
|
||||
getContentResolver().openInputStream(mInUri));
|
||||
} else {
|
||||
mInStream = new BufferedInputStream(
|
||||
getResources().openRawResource(mInResId));
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
|
||||
}
|
||||
@@ -227,13 +247,15 @@ public class WallpaperCropActivity extends Activity {
|
||||
try {
|
||||
mWPManager.setStream(new ByteArrayInputStream(tmpOut
|
||||
.toByteArray()));
|
||||
updateWallpaperDimensions(mOutWidth, mOutHeight);
|
||||
} catch (IOException e) {
|
||||
Log.w(LOGTAG, "cannot write stream to wallpaper", e);
|
||||
failure = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mOnEndRunnable != null) {
|
||||
mOnEndRunnable.run();
|
||||
}
|
||||
} else {
|
||||
Log.w(LOGTAG, "cannot compress bitmap");
|
||||
failure = true;
|
||||
@@ -266,6 +288,7 @@ public class WallpaperCropActivity extends Activity {
|
||||
editor.remove(WALLPAPER_HEIGHT_KEY);
|
||||
}
|
||||
editor.commit();
|
||||
|
||||
WallpaperPickerActivity.suggestWallpaperDimension(getResources(),
|
||||
sp, getWindowManager(), WallpaperManager.getInstance(this));
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -35,6 +34,7 @@ import android.graphics.drawable.LevelListDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -53,7 +53,6 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.photos.BitmapRegionTileSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -99,14 +98,35 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
|
||||
meta.mGalleryImageUri, 1024, 0), null);
|
||||
mCropView.setTouchEnabled(true);
|
||||
} else {
|
||||
mCropView.setTileSource(new BitmapRegionTileSource(WallpaperPickerActivity.this,
|
||||
meta.mWallpaperResId, 1024, 0), null);
|
||||
BitmapRegionTileSource source = new BitmapRegionTileSource(
|
||||
WallpaperPickerActivity.this, meta.mWallpaperResId, 1024, 0);
|
||||
mCropView.setTileSource(source, null);
|
||||
Point wallpaperSize = getDefaultWallpaperSize(getResources(), getWindowManager());
|
||||
RectF crop = getMaxCropRect(source.getImageWidth(), source.getImageHeight(),
|
||||
wallpaperSize.x, wallpaperSize.y);
|
||||
mCropView.setScale(wallpaperSize.x / crop.width());
|
||||
mCropView.setTouchEnabled(false);
|
||||
mCropView.moveToUpperLeft();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private RectF getMaxCropRect(int inWidth, int inHeight, int outWidth, int outHeight) {
|
||||
RectF cropRect = new RectF();
|
||||
// Get a crop rect that will fit this
|
||||
if (inWidth / (float) inHeight > outWidth / (float) outHeight) {
|
||||
cropRect.top = 0;
|
||||
cropRect.bottom = inHeight;
|
||||
cropRect.left = (inWidth - (outWidth / (float) outHeight) * inHeight) / 2;
|
||||
cropRect.right = inWidth - cropRect.left;
|
||||
} else {
|
||||
cropRect.left = 0;
|
||||
cropRect.right = inWidth;
|
||||
cropRect.top = (inHeight - (outHeight / (float) outWidth) * inWidth) / 2;
|
||||
cropRect.bottom = inHeight - cropRect.top;
|
||||
}
|
||||
return cropRect;
|
||||
}
|
||||
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == IMAGE_PICK && resultCode == RESULT_OK) {
|
||||
Uri uri = data.getData();
|
||||
@@ -124,22 +144,11 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
|
||||
int width = res.getDimensionPixelSize(R.dimen.wallpaperThumbnailWidth);
|
||||
int height = res.getDimensionPixelSize(R.dimen.wallpaperThumbnailHeight);
|
||||
|
||||
BitmapCropTask cropTask = new BitmapCropTask(uri, null, width, height, false, true);
|
||||
BitmapCropTask cropTask =
|
||||
new BitmapCropTask(uri, null, width, height, false, true, null);
|
||||
Point bounds = cropTask.getImageBounds();
|
||||
|
||||
RectF cropRect = new RectF();
|
||||
// Get a crop rect that will fit this
|
||||
if (bounds.x / (float) bounds.y > width / (float) height) {
|
||||
cropRect.top = 0;
|
||||
cropRect.bottom = bounds.y;
|
||||
cropRect.left = (bounds.x - (width / (float) height) * bounds.y) / 2;
|
||||
cropRect.right = bounds.x - cropRect.left;
|
||||
} else {
|
||||
cropRect.left = 0;
|
||||
cropRect.right = bounds.x;
|
||||
cropRect.top = (bounds.y - (height / (float) width) * bounds.x) / 2;
|
||||
cropRect.bottom = bounds.y - cropRect.top;
|
||||
}
|
||||
RectF cropRect = getMaxCropRect(bounds.x, bounds.y, width, height);
|
||||
cropTask.setCropBounds(cropRect);
|
||||
|
||||
if (cropTask.cropBitmap()) {
|
||||
@@ -154,6 +163,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
|
||||
ThumbnailMetaData meta = new ThumbnailMetaData();
|
||||
meta.mGalleryImageUri = uri;
|
||||
pickedImageThumbnail.setTag(meta);
|
||||
pickedImageThumbnail.setOnClickListener(mThumbnailOnClickListener);
|
||||
mThumbnailOnClickListener.onClick(pickedImageThumbnail);
|
||||
} else if (requestCode == PICK_WALLPAPER_THIRD_PARTY_ACTIVITY) {
|
||||
// No result code is returned; just return
|
||||
@@ -209,38 +219,84 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
ThumbnailMetaData meta = (ThumbnailMetaData) mSelectedThumb.getTag();
|
||||
if (meta.mLaunchesGallery) {
|
||||
// shouldn't be selected, but do nothing
|
||||
} else if (meta.mGalleryImageUri != null) {
|
||||
// Get the crop
|
||||
// TODO: get outwidth/outheight more robustly?
|
||||
BitmapCropTask cropTask = new BitmapCropTask(meta.mGalleryImageUri,
|
||||
mCropView.getCrop(), mCropView.getWidth(), mCropView.getHeight(),
|
||||
true, false);
|
||||
|
||||
Point inSize = mCropView.getSourceDimensions();
|
||||
|
||||
Point minDims = new Point();
|
||||
Point maxDims = new Point();
|
||||
Display d = getWindowManager().getDefaultDisplay();
|
||||
d.getCurrentSizeRange(minDims, maxDims);
|
||||
Point displaySize = new Point();
|
||||
d.getSize(displaySize);
|
||||
|
||||
// Get the crop
|
||||
RectF cropRect = mCropView.getCrop();
|
||||
|
||||
float cropScale = displaySize.x / (float) cropRect.width();
|
||||
if (displaySize.x < displaySize.y) { // PORTRAIT
|
||||
// Save the leftmost position for portrait mode
|
||||
// Extend the crop all the way to the right, for parallax
|
||||
float extraSpaceToRight = inSize.x - cropRect.right;
|
||||
cropRect.right = inSize.x;
|
||||
// Add some space to the left for the landscape case
|
||||
//float extraLandscapeWidth = maxDims.x - cropRect.width();
|
||||
//float shiftLeft = Math.min(
|
||||
// Math.min(extraSpaceToRight, cropRect.left),
|
||||
// extraLandscapeWidth / 2);
|
||||
//cropRect.left -= shiftLeft;
|
||||
// Adjust the "leftMost variable now"
|
||||
//float leftForPortrait = shiftLeft;
|
||||
} else { // LANDSCAPE
|
||||
float leftForPortrait = (cropRect.width() - minDims.x) / 2;
|
||||
cropRect.right = inSize.x;
|
||||
// TODO: how to actually get the proper portrait height?
|
||||
// This is not quite right:
|
||||
float portraitHeight = Math.max(maxDims.x, maxDims.y);
|
||||
float extraPortraitHeight = portraitHeight - cropRect.height();
|
||||
float expandHeight =
|
||||
Math.min(Math.min(inSize.y - cropRect.bottom, cropRect.top),
|
||||
extraPortraitHeight / 2);
|
||||
cropRect.top -= expandHeight;
|
||||
cropRect.bottom += expandHeight;
|
||||
}
|
||||
final int outWidth = (int) Math.ceil(cropRect.width() * cropScale);
|
||||
final int outHeight = (int) Math.ceil(cropRect.height() * cropScale);
|
||||
|
||||
Runnable onEndCrop = new Runnable() {
|
||||
public void run() {
|
||||
updateWallpaperDimensions(outWidth, outHeight);
|
||||
}
|
||||
};
|
||||
BitmapCropTask cropTask = new BitmapCropTask(meta.mGalleryImageUri,
|
||||
cropRect, outWidth, outHeight, true, false, onEndCrop);
|
||||
cropTask.execute();
|
||||
} else if (meta.mWallpaperResId != 0) {
|
||||
try {
|
||||
WallpaperManager wm =
|
||||
WallpaperManager.getInstance(getApplicationContext());
|
||||
wm.setResource(meta.mWallpaperResId);
|
||||
// passing 0 will just revert back to using the default wallpaper
|
||||
// size (setWallpaperDimension)
|
||||
updateWallpaperDimensions(0, 0);
|
||||
String spKey = LauncherAppState.getSharedPreferencesKey();
|
||||
SharedPreferences sp =
|
||||
getSharedPreferences(spKey, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.remove(WALLPAPER_WIDTH_KEY);
|
||||
editor.remove(WALLPAPER_HEIGHT_KEY);
|
||||
editor.commit();
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to set wallpaper: " + e);
|
||||
}
|
||||
// crop this image and scale it down to the default wallpaper size for
|
||||
// this device
|
||||
Point inSize = mCropView.getSourceDimensions();
|
||||
Point outSize = getDefaultWallpaperSize(getResources(),
|
||||
getWindowManager());
|
||||
RectF crop = getMaxCropRect(
|
||||
inSize.x, inSize.y, outSize.x, outSize.y);
|
||||
Runnable onEndCrop = new Runnable() {
|
||||
public void run() {
|
||||
// Passing 0, 0 will cause launcher to revert to using the
|
||||
// default wallpaper size
|
||||
updateWallpaperDimensions(0, 0);
|
||||
}
|
||||
};
|
||||
BitmapCropTask cropTask = new BitmapCropTask(meta.mWallpaperResId,
|
||||
crop, outSize.x, outSize.y,
|
||||
true, false, onEndCrop);
|
||||
cropTask.execute();
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -371,10 +427,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
|
||||
return x * aspectRatio + y;
|
||||
}
|
||||
|
||||
static public void suggestWallpaperDimension(Resources res,
|
||||
final SharedPreferences sharedPrefs,
|
||||
WindowManager windowManager,
|
||||
final WallpaperManager wallpaperManager) {
|
||||
static private Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
|
||||
Point minDims = new Point();
|
||||
Point maxDims = new Point();
|
||||
windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
|
||||
@@ -393,11 +446,20 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
|
||||
defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
|
||||
defaultHeight = maxDim;
|
||||
}
|
||||
return new Point(defaultWidth, defaultHeight);
|
||||
}
|
||||
|
||||
static public void suggestWallpaperDimension(Resources res,
|
||||
final SharedPreferences sharedPrefs,
|
||||
WindowManager windowManager,
|
||||
final WallpaperManager wallpaperManager) {
|
||||
final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
|
||||
|
||||
new Thread("suggestWallpaperDimension") {
|
||||
public void run() {
|
||||
// If we have saved a wallpaper width/height, use that instead
|
||||
int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWidth);
|
||||
int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultHeight);
|
||||
int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
|
||||
int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
|
||||
wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
|
||||
}
|
||||
}.start();
|
||||
|
||||
@@ -971,16 +971,7 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
|
||||
|
||||
private float wallpaperOffsetForCurrentScroll() {
|
||||
// Set wallpaper offset steps (1 / (number of screens - 1))
|
||||
mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f);
|
||||
if (mMaxScrollX == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// do different behavior if it's alive wallpaper?
|
||||
return getScrollX() / (float) mMaxScrollX;
|
||||
}
|
||||
|
||||
protected void snapToPage(int whichPage, Runnable r) {
|
||||
if (mDelayedSnapToPageRunnable != null) {
|
||||
@@ -998,7 +989,7 @@ public class Workspace extends SmoothPagedView
|
||||
float mFinalOffset = 0.0f;
|
||||
float mCurrentOffset = 0.0f;
|
||||
//long mLastWallpaperOffsetUpdateTime;
|
||||
boolean mWaitingForCallback;
|
||||
boolean mWaitingForUpdate;
|
||||
Choreographer mChoreographer;
|
||||
Interpolator mInterpolator;
|
||||
boolean mAnimating;
|
||||
@@ -1014,10 +1005,18 @@ public class Workspace extends SmoothPagedView
|
||||
|
||||
@Override
|
||||
public void doFrame(long frameTimeNanos) {
|
||||
mWaitingForCallback = false;
|
||||
if (computeScrollOffset()) {
|
||||
mWallpaperManager.setWallpaperOffsets(mWindowToken,
|
||||
mWallpaperOffset.getCurrX(), 0f);
|
||||
updateOffset(false);
|
||||
}
|
||||
|
||||
|
||||
private void updateOffset(boolean force) {
|
||||
if (mWaitingForUpdate || force) {
|
||||
mWaitingForUpdate = false;
|
||||
if (computeScrollOffset()) {
|
||||
mWallpaperManager.setWallpaperOffsets(mWindowToken,
|
||||
mWallpaperOffset.getCurrX(), 0.5f);
|
||||
setWallpaperOffsetSteps();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,13 +1033,38 @@ public class Workspace extends SmoothPagedView
|
||||
mCurrentOffset = mFinalOffset;
|
||||
}
|
||||
|
||||
if (Math.abs(mCurrentOffset - mFinalOffset) > 0.0000001f) {
|
||||
scheduleUpdate();
|
||||
}
|
||||
if (Math.abs(oldOffset - mCurrentOffset) > 0.0000001f) {
|
||||
scheduleCallback();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private float wallpaperOffsetForCurrentScroll() {
|
||||
if (getChildCount() <= 1) {
|
||||
return 0;
|
||||
}
|
||||
final int lastIndex = isLayoutRtl() ? 0 : getChildCount() - 1;
|
||||
final int firstIndex = isLayoutRtl() ? getChildCount() - 2 : 1;
|
||||
int firstPageScrollX = getScrollForPage(firstIndex);
|
||||
int scrollRange = getScrollForPage(lastIndex) - firstPageScrollX;
|
||||
if (scrollRange == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
// do different behavior if it's a live wallpaper?
|
||||
float offset = (getScrollX() - firstPageScrollX) / (float) scrollRange;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
public void syncWithScroll() {
|
||||
float offset = wallpaperOffsetForCurrentScroll();
|
||||
mWallpaperOffset.setFinalX(offset);
|
||||
updateOffset(true);
|
||||
}
|
||||
|
||||
public float getCurrX() {
|
||||
return mCurrentOffset;
|
||||
}
|
||||
@@ -1055,8 +1079,13 @@ public class Workspace extends SmoothPagedView
|
||||
mAnimationStartTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void setWallpaperOffsetSteps() {
|
||||
// Set wallpaper offset steps (1 / (number of screens - 1))
|
||||
mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f);
|
||||
}
|
||||
|
||||
public void setFinalX(float x) {
|
||||
scheduleCallback();
|
||||
scheduleUpdate();
|
||||
mFinalOffset = Math.max(0f, Math.min(x, 1.0f));
|
||||
if (getChildCount() != mNumScreens) {
|
||||
if (mNumScreens > 0) {
|
||||
@@ -1067,10 +1096,10 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleCallback() {
|
||||
if (!mWaitingForCallback) {
|
||||
private void scheduleUpdate() {
|
||||
if (!mWaitingForUpdate) {
|
||||
mChoreographer.postFrameCallback(this);
|
||||
mWaitingForCallback = true;
|
||||
mWaitingForUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,11 +1111,7 @@ public class Workspace extends SmoothPagedView
|
||||
@Override
|
||||
public void computeScroll() {
|
||||
super.computeScroll();
|
||||
syncWallpaperOffsetWithScroll();
|
||||
}
|
||||
|
||||
private void syncWallpaperOffsetWithScroll() {
|
||||
mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
|
||||
mWallpaperOffset.syncWithScroll();
|
||||
}
|
||||
|
||||
void showOutlines() {
|
||||
@@ -1325,7 +1350,7 @@ 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()) {
|
||||
syncWallpaperOffsetWithScroll();
|
||||
mWallpaperOffset.syncWithScroll();
|
||||
mWallpaperOffset.jumpToFinal();
|
||||
}
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||