Merge "Adding animation post-installing a shortcut."
This commit is contained in:
@@ -82,7 +82,7 @@ s -->
|
||||
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper-->
|
||||
<string name="group_wallpapers">Wallpapers</string>
|
||||
<!-- Error message when user has filled a home screen, possibly not used -->
|
||||
<string name="out_of_space">No more room on this Home screen.</string>
|
||||
<string name="out_of_space">No more room on your Home screens.</string>
|
||||
<!-- Error message when user tries to drop an invalid item on the hotseat -->
|
||||
<string name="invalid_hotseat_item">This widget is too large for the hotseat.</string>
|
||||
<!-- Message displayed when a shortcut is created by an external application -->
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.widget.Toast;
|
||||
@@ -27,10 +27,21 @@ import android.widget.Toast;
|
||||
import com.android.launcher.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
public static final String ACTION_INSTALL_SHORTCUT =
|
||||
"com.android.launcher.action.INSTALL_SHORTCUT";
|
||||
public static final String NEW_APPS_PAGE_KEY = "apps.new.page";
|
||||
public static final String NEW_APPS_LIST_KEY = "apps.new.list";
|
||||
|
||||
public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450;
|
||||
public static final int NEW_SHORTCUT_STAGGER_DELAY = 75;
|
||||
|
||||
private static final int INSTALL_SHORTCUT_SUCCESSFUL = 0;
|
||||
private static final int INSTALL_SHORTCUT_IS_DUPLICATE = -1;
|
||||
private static final int INSTALL_SHORTCUT_NO_SPACE = -2;
|
||||
|
||||
// A mime-type representing shortcut data
|
||||
public static final String SHORTCUT_MIMETYPE =
|
||||
@@ -42,6 +53,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
|
||||
return;
|
||||
}
|
||||
String spKey = LauncherApplication.getSharedPreferencesKey();
|
||||
SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
|
||||
|
||||
final int screen = Launcher.getScreen();
|
||||
final Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
|
||||
@@ -62,26 +75,35 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
|
||||
final boolean shortcutExists = LauncherModel.shortcutExists(context, name, intent);
|
||||
final String[] errorMsgs = {""};
|
||||
final boolean exists = LauncherModel.shortcutExists(context, name, intent);
|
||||
final int[] result = {INSTALL_SHORTCUT_SUCCESSFUL};
|
||||
|
||||
if (!installShortcut(context, data, items, name, intent, screen, shortcutExists,
|
||||
errorMsgs)) {
|
||||
// The target screen is full, let's try the other screens
|
||||
for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {
|
||||
if (i != screen && installShortcut(context, data, items, name, intent, i,
|
||||
shortcutExists, errorMsgs)) break;
|
||||
// Try adding the target to the workspace screens incrementally, starting at the current
|
||||
// screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
|
||||
boolean found = false;
|
||||
for (int i = 0; i < (2 * Launcher.SCREEN_COUNT) + 1 && !found; ++i) {
|
||||
int si = screen + (int) ((i / 2f) + 0.5f) * ((i % 2 == 1) ? 1 : -1);
|
||||
if (0 <= si && si < Launcher.SCREEN_COUNT) {
|
||||
found = installShortcut(context, data, items, name, intent, si, exists, sp, result);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorMsgs[0].isEmpty()) {
|
||||
Toast.makeText(context, errorMsgs[0],
|
||||
Toast.LENGTH_SHORT).show();
|
||||
// We only report error messages (duplicate shortcut or out of space) as the add-animation
|
||||
// will provide feedback otherwise
|
||||
if (!found) {
|
||||
if (result[0] == INSTALL_SHORTCUT_NO_SPACE) {
|
||||
Toast.makeText(context, context.getString(R.string.out_of_space),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else if (result[0] == INSTALL_SHORTCUT_IS_DUPLICATE) {
|
||||
Toast.makeText(context, context.getString(R.string.shortcut_duplicate, name),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean installShortcut(Context context, Intent data, ArrayList<ItemInfo> items,
|
||||
String name, Intent intent, int screen, boolean shortcutExists, String[] errorMsgs) {
|
||||
String name, Intent intent, int screen, boolean shortcutExists,
|
||||
SharedPreferences sharedPrefs, int[] result) {
|
||||
if (findEmptyCell(context, items, mCoordinates, screen)) {
|
||||
if (intent != null) {
|
||||
if (intent.getAction() == null) {
|
||||
@@ -92,23 +114,35 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
// different places)
|
||||
boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
|
||||
if (duplicate || !shortcutExists) {
|
||||
// If the new app is going to fall into the same page as before, then just
|
||||
// continue adding to the current page
|
||||
int newAppsScreen = sharedPrefs.getInt(NEW_APPS_PAGE_KEY, screen);
|
||||
Set<String> newApps = new HashSet<String>();
|
||||
if (newAppsScreen == screen) {
|
||||
newApps = sharedPrefs.getStringSet(NEW_APPS_LIST_KEY, newApps);
|
||||
}
|
||||
newApps.add(intent.toUri(0).toString());
|
||||
sharedPrefs.edit()
|
||||
.putInt(NEW_APPS_PAGE_KEY, screen)
|
||||
.putStringSet(NEW_APPS_LIST_KEY, newApps)
|
||||
.commit();
|
||||
|
||||
// Update the Launcher db
|
||||
LauncherApplication app = (LauncherApplication) context.getApplicationContext();
|
||||
ShortcutInfo info = app.getModel().addShortcut(context, data,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, mCoordinates[0],
|
||||
mCoordinates[1], true);
|
||||
if (info != null) {
|
||||
errorMsgs[0] = context.getString(R.string.shortcut_installed, name);
|
||||
} else {
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
|
||||
mCoordinates[0], mCoordinates[1], true);
|
||||
if (info == null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
errorMsgs[0] = context.getString(R.string.shortcut_duplicate, name);
|
||||
result[0] = INSTALL_SHORTCUT_IS_DUPLICATE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
errorMsgs[0] = context.getString(R.string.out_of_space);
|
||||
result[0] = INSTALL_SHORTCUT_NO_SPACE;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -55,6 +55,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -84,6 +85,7 @@ import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.BounceInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Advanceable;
|
||||
@@ -103,7 +105,12 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
@@ -253,6 +260,10 @@ public final class Launcher extends Activity
|
||||
// it from the context.
|
||||
private SharedPreferences mSharedPrefs;
|
||||
|
||||
// Holds the page that we need to animate to, and the icon views that we need to animate up
|
||||
// when we scroll to that page on resume.
|
||||
private int mNewShortcutAnimatePage = -1;
|
||||
private ArrayList<View> mNewShortcutAnimateViews = new ArrayList<View>();
|
||||
|
||||
private BubbleTextView mWaitingForResume;
|
||||
|
||||
@@ -280,7 +291,8 @@ public final class Launcher extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
LauncherApplication app = ((LauncherApplication)getApplication());
|
||||
mSharedPrefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
|
||||
mSharedPrefs = getSharedPreferences(LauncherApplication.getSharedPreferencesKey(),
|
||||
Context.MODE_PRIVATE);
|
||||
mModel = app.setLauncher(this);
|
||||
mIconCache = app.getIconCache();
|
||||
mDragController = new DragController(this);
|
||||
@@ -317,7 +329,7 @@ public final class Launcher extends Activity
|
||||
}
|
||||
|
||||
if (!mRestoring) {
|
||||
mModel.startLoader(this, true);
|
||||
mModel.startLoader(true);
|
||||
}
|
||||
|
||||
if (!mModel.isAllAppsLoaded()) {
|
||||
@@ -593,10 +605,11 @@ public final class Launcher extends Activity
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mPaused = false;
|
||||
if (mRestoring || mOnResumeNeedsLoad) {
|
||||
mWorkspaceLoading = true;
|
||||
mModel.startLoader(this, true);
|
||||
mModel.startLoader(true);
|
||||
mRestoring = false;
|
||||
mOnResumeNeedsLoad = false;
|
||||
}
|
||||
@@ -725,7 +738,7 @@ public final class Launcher extends Activity
|
||||
showAllApps(false);
|
||||
}
|
||||
|
||||
final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
|
||||
int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
|
||||
if (currentScreen > -1) {
|
||||
mWorkspace.setCurrentPage(currentScreen);
|
||||
}
|
||||
@@ -2184,7 +2197,7 @@ public final class Launcher extends Activity
|
||||
|
||||
if (mWorkspaceLoading) {
|
||||
lockAllApps();
|
||||
mModel.startLoader(Launcher.this, false);
|
||||
mModel.startLoader(false);
|
||||
} else {
|
||||
final FolderIcon folderIcon = (FolderIcon)
|
||||
mWorkspace.getViewForTag(mFolderInfo);
|
||||
@@ -2196,7 +2209,7 @@ public final class Launcher extends Activity
|
||||
} else {
|
||||
lockAllApps();
|
||||
mWorkspaceLoading = true;
|
||||
mModel.startLoader(Launcher.this, false);
|
||||
mModel.startLoader(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3076,7 +3089,6 @@ public final class Launcher extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refreshes the shortcuts shown on the workspace.
|
||||
*
|
||||
@@ -3085,6 +3097,8 @@ public final class Launcher extends Activity
|
||||
public void startBinding() {
|
||||
final Workspace workspace = mWorkspace;
|
||||
|
||||
mNewShortcutAnimatePage = -1;
|
||||
mNewShortcutAnimateViews.clear();
|
||||
mWorkspace.clearDropTargets();
|
||||
int count = workspace.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
@@ -3106,8 +3120,12 @@ public final class Launcher extends Activity
|
||||
public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) {
|
||||
setLoadOnResume();
|
||||
|
||||
final Workspace workspace = mWorkspace;
|
||||
for (int i=start; i<end; i++) {
|
||||
// Get the list of added shortcuts and intersect them with the set of shortcuts here
|
||||
Set<String> newApps = new HashSet<String>();
|
||||
newApps = mSharedPrefs.getStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY, newApps);
|
||||
|
||||
Workspace workspace = mWorkspace;
|
||||
for (int i = start; i < end; i++) {
|
||||
final ItemInfo item = shortcuts.get(i);
|
||||
|
||||
// Short circuit if we are loading dock items for a configuration which has no dock
|
||||
@@ -3119,9 +3137,23 @@ public final class Launcher extends Activity
|
||||
switch (item.itemType) {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
||||
View shortcut = createShortcut((ShortcutInfo)item);
|
||||
ShortcutInfo info = (ShortcutInfo) item;
|
||||
String uri = info.intent.toUri(0).toString();
|
||||
View shortcut = createShortcut(info);
|
||||
workspace.addInScreen(shortcut, item.container, item.screen, item.cellX,
|
||||
item.cellY, 1, 1, false);
|
||||
if (newApps.contains(uri)) {
|
||||
newApps.remove(uri);
|
||||
|
||||
// Prepare the view to be animated up
|
||||
shortcut.setAlpha(0f);
|
||||
shortcut.setScaleX(0f);
|
||||
shortcut.setScaleY(0f);
|
||||
mNewShortcutAnimatePage = item.screen;
|
||||
if (!mNewShortcutAnimateViews.contains(shortcut)) {
|
||||
mNewShortcutAnimateViews.add(shortcut);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||
FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
|
||||
@@ -3132,6 +3164,7 @@ public final class Launcher extends Activity
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
workspace.requestLayout();
|
||||
}
|
||||
|
||||
@@ -3169,11 +3202,6 @@ public final class Launcher extends Activity
|
||||
item.hostView.setAppWidget(appWidgetId, appWidgetInfo);
|
||||
item.hostView.setTag(item);
|
||||
|
||||
// We need to load the minimum span and embed it into the item info
|
||||
int[] minSpan = getMinSpanForWidget(appWidgetInfo, null);
|
||||
item.minSpanX = minSpan[0];
|
||||
item.minSpanY = minSpan[1];
|
||||
|
||||
workspace.addInScreen(item.hostView, item.container, item.screen, item.cellX,
|
||||
item.cellY, item.spanX, item.spanY, false);
|
||||
|
||||
@@ -3207,8 +3235,6 @@ public final class Launcher extends Activity
|
||||
mSavedInstanceState = null;
|
||||
}
|
||||
|
||||
mWorkspaceLoading = false;
|
||||
|
||||
// If we received the result of any pending adds while the loader was running (e.g. the
|
||||
// widget configuration forced an orientation change), process them now.
|
||||
for (int i = 0; i < sPendingAddList.size(); i++) {
|
||||
@@ -3220,7 +3246,72 @@ public final class Launcher extends Activity
|
||||
// package changes in bindSearchablesChanged()
|
||||
updateAppMarketIcon();
|
||||
|
||||
mWorkspace.postDelayed(mBuildLayersRunnable, 500);
|
||||
// Animate up any icons as necessary
|
||||
if (mVisible || mWorkspaceLoading) {
|
||||
Runnable newAppsRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runNewAppsAnimation();
|
||||
}
|
||||
};
|
||||
if (mNewShortcutAnimatePage > -1 &&
|
||||
mNewShortcutAnimatePage != mWorkspace.getCurrentPage()) {
|
||||
mWorkspace.snapToPage(mNewShortcutAnimatePage, newAppsRunnable);
|
||||
} else {
|
||||
newAppsRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
mWorkspaceLoading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a new animation that scales up icons that were added while Launcher was in the
|
||||
* background.
|
||||
*/
|
||||
private void runNewAppsAnimation() {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
Collection<Animator> bounceAnims = new ArrayList<Animator>();
|
||||
Collections.sort(mNewShortcutAnimateViews, new Comparator<View>() {
|
||||
@Override
|
||||
public int compare(View a, View b) {
|
||||
CellLayout.LayoutParams alp = (CellLayout.LayoutParams) a.getLayoutParams();
|
||||
CellLayout.LayoutParams blp = (CellLayout.LayoutParams) b.getLayoutParams();
|
||||
int cellCountX = LauncherModel.getCellCountX();
|
||||
return (alp.cellY * cellCountX + alp.cellX) - (blp.cellY * cellCountX + blp.cellX);
|
||||
}
|
||||
});
|
||||
for (int i = 0; i < mNewShortcutAnimateViews.size(); ++i) {
|
||||
View v = mNewShortcutAnimateViews.get(i);
|
||||
ValueAnimator bounceAnim = ObjectAnimator.ofPropertyValuesHolder(v,
|
||||
PropertyValuesHolder.ofFloat("alpha", 1f),
|
||||
PropertyValuesHolder.ofFloat("scaleX", 1f),
|
||||
PropertyValuesHolder.ofFloat("scaleY", 1f));
|
||||
bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);
|
||||
bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);
|
||||
bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());
|
||||
bounceAnims.add(bounceAnim);
|
||||
}
|
||||
anim.playTogether(bounceAnims);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mWorkspace.postDelayed(mBuildLayersRunnable, 500);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
|
||||
// Clean up
|
||||
mNewShortcutAnimatePage = -1;
|
||||
mNewShortcutAnimateViews.clear();
|
||||
new Thread("clearNewAppsThread") {
|
||||
public void run() {
|
||||
mSharedPrefs.edit()
|
||||
.putInt(InstallShortcutReceiver.NEW_APPS_PAGE_KEY, -1)
|
||||
.putStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY, null)
|
||||
.commit();
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3363,7 +3454,6 @@ public final class Launcher extends Activity
|
||||
}
|
||||
|
||||
/* Cling related */
|
||||
private static final String PREFS_KEY = "com.android.launcher2.prefs";
|
||||
private boolean isClingsEnabled() {
|
||||
// disable clings when running in a test harness
|
||||
if(ActivityManager.isRunningInTestHarness()) return false;
|
||||
|
||||
@@ -37,6 +37,7 @@ public class LauncherApplication extends Application {
|
||||
private static boolean sIsScreenLarge;
|
||||
private static float sScreenDensity;
|
||||
private static int sLongPressTimeout = 300;
|
||||
private static final String sSharedPreferencesKey = "com.android.launcher2.prefs";
|
||||
WeakReference<LauncherProvider> mLauncherProvider;
|
||||
|
||||
@Override
|
||||
@@ -94,7 +95,10 @@ public class LauncherApplication extends Application {
|
||||
private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
mModel.startLoader(LauncherApplication.this, false);
|
||||
// If the database has ever changed, then we really need to force a reload of the
|
||||
// workspace on the next load
|
||||
mModel.resetLoadedState(false, true);
|
||||
mModel.startLoaderFromBackground();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,6 +123,10 @@ public class LauncherApplication extends Application {
|
||||
return mLauncherProvider.get();
|
||||
}
|
||||
|
||||
public static String getSharedPreferencesKey() {
|
||||
return sSharedPreferencesKey;
|
||||
}
|
||||
|
||||
public static boolean isScreenLarge() {
|
||||
return sIsScreenLarge;
|
||||
}
|
||||
|
||||
@@ -649,19 +649,24 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
private void forceReload() {
|
||||
synchronized (mLock) {
|
||||
// Stop any existing loaders first, so they don't set mAllAppsLoaded or
|
||||
// mWorkspaceLoaded to true later
|
||||
stopLoaderLocked();
|
||||
mAllAppsLoaded = false;
|
||||
mWorkspaceLoaded = false;
|
||||
}
|
||||
resetLoadedState(true, true);
|
||||
|
||||
// Do this here because if the launcher activity is running it will be restarted.
|
||||
// If it's not running startLoaderFromBackground will merely tell it that it needs
|
||||
// to reload.
|
||||
startLoaderFromBackground();
|
||||
}
|
||||
|
||||
public void resetLoadedState(boolean resetAllAppsLoaded, boolean resetWorkspaceLoaded) {
|
||||
synchronized (mLock) {
|
||||
// Stop any existing loaders first, so they don't set mAllAppsLoaded or
|
||||
// mWorkspaceLoaded to true later
|
||||
stopLoaderLocked();
|
||||
if (resetAllAppsLoaded) mAllAppsLoaded = false;
|
||||
if (resetWorkspaceLoaded) mWorkspaceLoaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the launcher is in the background, it's possible for it to miss paired
|
||||
* configuration changes. So whenever we trigger the loader from the background
|
||||
@@ -680,7 +685,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
if (runLoader) {
|
||||
startLoader(mApp, false);
|
||||
startLoader(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,7 +703,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
return isLaunching;
|
||||
}
|
||||
|
||||
public void startLoader(Context context, boolean isLaunching) {
|
||||
public void startLoader(boolean isLaunching) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "startLoader isLaunching=" + isLaunching);
|
||||
@@ -709,7 +714,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
// If there is already one running, tell it to stop.
|
||||
// also, don't downgrade isLaunching if we're already running
|
||||
isLaunching = isLaunching || stopLoaderLocked();
|
||||
mLoaderTask = new LoaderTask(context, isLaunching);
|
||||
mLoaderTask = new LoaderTask(mApp, isLaunching);
|
||||
sWorkerThread.setPriority(Thread.NORM_PRIORITY);
|
||||
sWorker.post(mLoaderTask);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ public abstract class PagedView extends ViewGroup {
|
||||
// the min drag distance for a fling to register, to prevent random page shifts
|
||||
private static final int MIN_LENGTH_FOR_FLING = 25;
|
||||
|
||||
private static final int PAGE_SNAP_ANIMATION_DURATION = 550;
|
||||
protected static final int PAGE_SNAP_ANIMATION_DURATION = 550;
|
||||
protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
|
||||
protected static final float NANOTIME_DIV = 1000000000.0f;
|
||||
|
||||
private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
|
||||
|
||||
@@ -35,11 +35,11 @@ public abstract class SmoothPagedView extends PagedView {
|
||||
|
||||
private Interpolator mScrollInterpolator;
|
||||
|
||||
private static class WorkspaceOvershootInterpolator implements Interpolator {
|
||||
public static class OvershootInterpolator implements Interpolator {
|
||||
private static final float DEFAULT_TENSION = 1.3f;
|
||||
private float mTension;
|
||||
|
||||
public WorkspaceOvershootInterpolator() {
|
||||
public OvershootInterpolator() {
|
||||
mTension = DEFAULT_TENSION;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public abstract class SmoothPagedView extends PagedView {
|
||||
if (mScrollMode == DEFAULT_MODE) {
|
||||
mBaseLineFlingVelocity = 2500.0f;
|
||||
mFlingVelocityInfluence = 0.4f;
|
||||
mScrollInterpolator = new WorkspaceOvershootInterpolator();
|
||||
mScrollInterpolator = new OvershootInterpolator();
|
||||
mScroller = new Scroller(getContext(), mScrollInterpolator);
|
||||
}
|
||||
}
|
||||
@@ -139,9 +139,9 @@ public abstract class SmoothPagedView extends PagedView {
|
||||
}
|
||||
|
||||
if (settle) {
|
||||
((WorkspaceOvershootInterpolator) mScrollInterpolator).setDistance(screenDelta);
|
||||
((OvershootInterpolator) mScrollInterpolator).setDistance(screenDelta);
|
||||
} else {
|
||||
((WorkspaceOvershootInterpolator) mScrollInterpolator).disableSettle();
|
||||
((OvershootInterpolator) mScrollInterpolator).disableSettle();
|
||||
}
|
||||
|
||||
velocity = Math.abs(velocity);
|
||||
|
||||
@@ -184,6 +184,7 @@ public class Workspace extends SmoothPagedView
|
||||
WallpaperOffsetInterpolator mWallpaperOffset;
|
||||
boolean mUpdateWallpaperOffsetImmediately = false;
|
||||
private Runnable mDelayedResizeRunnable;
|
||||
private Runnable mDelayedSnapToPageRunnable;
|
||||
private int mDisplayWidth;
|
||||
private int mDisplayHeight;
|
||||
private boolean mIsStaticWallpaper;
|
||||
@@ -766,6 +767,11 @@ public class Workspace extends SmoothPagedView
|
||||
mDelayedResizeRunnable.run();
|
||||
mDelayedResizeRunnable = null;
|
||||
}
|
||||
|
||||
if (mDelayedSnapToPageRunnable != null) {
|
||||
mDelayedSnapToPageRunnable.run();
|
||||
mDelayedSnapToPageRunnable = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -907,6 +913,20 @@ public class Workspace extends SmoothPagedView
|
||||
computeWallpaperScrollRatio(whichPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void snapToPage(int whichPage, int duration) {
|
||||
super.snapToPage(whichPage, duration);
|
||||
computeWallpaperScrollRatio(whichPage);
|
||||
}
|
||||
|
||||
protected void snapToPage(int whichPage, Runnable r) {
|
||||
if (mDelayedSnapToPageRunnable != null) {
|
||||
mDelayedSnapToPageRunnable.run();
|
||||
}
|
||||
mDelayedSnapToPageRunnable = r;
|
||||
snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION);
|
||||
}
|
||||
|
||||
private void computeWallpaperScrollRatio(int page) {
|
||||
// Here, we determine what the desired scroll would be with and without a layout scale,
|
||||
// and compute a ratio between the two. This allows us to adjust the wallpaper offset
|
||||
|
||||
Reference in New Issue
Block a user