Merge "Fix NPE that occurs with poorly behaved widgets" into ics-mr1
diff --git a/res/drawable-hdpi/ic_home_all_apps_holo_dark.png b/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
index a0bfc0f..18a524b 100644
--- a/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
+++ b/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_clear_active_holo.png b/res/drawable-hdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..cdd0052
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_clear_normal_holo.png b/res/drawable-hdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..84549ff
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_all_apps_holo_dark.png b/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
index ffc3020..23616d4 100644
--- a/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
+++ b/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_clear_active_holo.png b/res/drawable-mdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..2683bea
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_clear_normal_holo.png b/res/drawable-mdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..219f3e5
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png b/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
index 21a51ab..dff3e16 100644
--- a/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
+++ b/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_clear_active_holo.png b/res/drawable-xhdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..1a7e53d
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_clear_normal_holo.png b/res/drawable-xhdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..d4965d9
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable/remove_target_selector.xml b/res/drawable/remove_target_selector.xml
new file mode 100644
index 0000000..5e071fb
--- /dev/null
+++ b/res/drawable/remove_target_selector.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/ic_launcher_clear_normal_holo" />
+ <item android:drawable="@drawable/ic_launcher_clear_active_holo" />
+</transition>
diff --git a/res/drawable/delete_target_selector.xml b/res/drawable/uninstall_target_selector.xml
similarity index 100%
rename from res/drawable/delete_target_selector.xml
rename to res/drawable/uninstall_target_selector.xml
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 084b163..a74eb14 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -66,6 +66,11 @@
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
</com.android.launcher2.Workspace>
+ <include layout="@layout/hotseat"
+ android:id="@+id/hotseat"
+ android:layout_width="@dimen/button_bar_height_plus_padding"
+ android:layout_height="match_parent"
+ android:layout_gravity="right" />
<include
android:id="@+id/qsb_bar"
layout="@layout/qsb_bar" />
@@ -76,12 +81,6 @@
android:layout_height="match_parent"
android:visibility="invisible" />
- <include layout="@layout/hotseat"
- android:id="@+id/hotseat"
- android:layout_width="@dimen/button_bar_height_plus_padding"
- android:layout_height="match_parent"
- android:layout_gravity="right" />
-
<include layout="@layout/workspace_cling"
android:id="@+id/workspace_cling"
android:layout_width="match_parent"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index b8df2ee..062656f 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -60,16 +60,16 @@
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
</com.android.launcher2.Workspace>
- <include
- android:id="@+id/qsb_bar"
- layout="@layout/qsb_bar" />
-
<include layout="@layout/hotseat"
android:id="@+id/hotseat"
android:layout_width="match_parent"
android:layout_height="@dimen/button_bar_height_plus_padding"
android:layout_gravity="bottom" />
+ <include
+ android:id="@+id/qsb_bar"
+ layout="@layout/qsb_bar" />
+
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index 704401a..90883c5 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -63,7 +63,7 @@
</LinearLayout>
<!-- The icon of the widget. -->
- <ImageView
+ <com.android.launcher2.PagedViewWidgetImageView
android:id="@+id/widget_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/layout/qsb_bar.xml b/res/layout/qsb_bar.xml
index c2179ce..9daf7bf 100644
--- a/res/layout/qsb_bar.xml
+++ b/res/layout/qsb_bar.xml
@@ -37,7 +37,7 @@
style="@style/DropTargetButton"
android:id="@+id/delete_target_text"
android:text="@string/delete_zone_label_workspace"
- android:drawableLeft="@drawable/delete_target_selector" />
+ android:drawableLeft="@drawable/remove_target_selector" />
</FrameLayout>
<FrameLayout
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 22f2692..cde0b4b 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -31,13 +31,13 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Bitmap.Config;
import android.graphics.TableMaskFilter;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
@@ -48,10 +48,10 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.Toast;
@@ -984,7 +984,6 @@
// Generate a preview image if we couldn't load one
if (drawable == null) {
- Resources resources = mLauncher.getResources();
// TODO: This actually uses the apps customize cell layout params, where as we make want
// the Workspace params for more accuracy.
int targetWidth = mWidgetSpacingLayout.estimateCellWidth(cellHSpan);
@@ -1026,6 +1025,7 @@
int hoffset = (int) (bitmapWidth / 2 - mAppIconSize * iconScale / 2);
int yoffset = (int) (bitmapHeight / 2 - mAppIconSize * iconScale / 2);
if (info.icon > 0) icon = mIconCache.getFullResIcon(packageName, info.icon);
+ Resources resources = mLauncher.getResources();
if (icon == null) icon = resources.getDrawable(R.drawable.ic_launcher_application);
renderDrawableToBitmap(icon, preview, hoffset, yoffset,
@@ -1272,7 +1272,7 @@
scale = 1.0f;
alpha = 1.0f;
// On the first page, we don't want the page to have any lateral motion
- translationX = getScrollX();
+ translationX = 0;
} else if (i == getChildCount() - 1 && scrollProgress > 0) {
// Overscroll to the right
v.setPivotX((1 - TRANSITION_PIVOT) * pageWidth);
@@ -1280,7 +1280,7 @@
scale = 1.0f;
alpha = 1.0f;
// On the last page, we don't want the page to have any lateral motion.
- translationX = getScrollX() - mMaxScrollX;
+ translationX = 0;
} else {
v.setPivotY(pageHeight / 2.0f);
v.setPivotX(pageWidth / 2.0f);
@@ -1292,6 +1292,14 @@
v.setScaleX(scale);
v.setScaleY(scale);
v.setAlpha(alpha);
+
+ // If the view has 0 alpha, we set it to be invisible so as to prevent
+ // it from accepting touches
+ if (alpha < ViewConfiguration.ALPHA_THRESHOLD) {
+ v.setVisibility(INVISIBLE);
+ } else if (v.getVisibility() != VISIBLE) {
+ v.setVisibility(VISIBLE);
+ }
}
}
}
@@ -1428,6 +1436,7 @@
ApplicationInfo.dumpApplicationInfoList(LOG_TAG, "mApps", mApps);
dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
}
+
private void dumpAppWidgetProviderInfoList(String tag, String label,
ArrayList<Object> list) {
Log.d(tag, label + " size=" + list.size());
@@ -1445,6 +1454,7 @@
}
}
}
+
@Override
public void surrender() {
// TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 9ffc1d0..6e60280 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -36,7 +36,6 @@
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
@@ -72,6 +71,7 @@
private int mWidthGap;
private int mHeightGap;
private int mMaxGap;
+ private boolean mScrollingTransformsDirty = false;
private final Rect mRect = new Rect();
private final CellInfo mCellInfo = new CellInfo();
@@ -102,9 +102,6 @@
private Drawable mOverScrollRight;
private Rect mBackgroundRect;
private Rect mForegroundRect;
- private Rect mGlowBackgroundRect;
- private float mGlowBackgroundScale;
- private float mGlowBackgroundAlpha;
private int mForegroundPadding;
// If we're actively dragging something over this screen, mIsDragOverlapping is true
@@ -258,9 +255,6 @@
mBackgroundRect = new Rect();
mForegroundRect = new Rect();
- mGlowBackgroundRect = new Rect();
- setHoverScale(1.0f);
- setHoverAlpha(1.0f);
mChildren = new CellLayoutChildren(context);
mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
@@ -351,68 +345,23 @@
return mIsDragOverlapping;
}
- private void updateGlowRect() {
- float marginFraction = (mGlowBackgroundScale - 1.0f) / 2.0f;
- int marginX = (int) (marginFraction * (mBackgroundRect.right - mBackgroundRect.left));
- int marginY = (int) (marginFraction * (mBackgroundRect.bottom - mBackgroundRect.top));
- mGlowBackgroundRect.set(mBackgroundRect.left - marginX, mBackgroundRect.top - marginY,
- mBackgroundRect.right + marginX, mBackgroundRect.bottom + marginY);
- invalidate();
+ protected void setOverscrollTransformsDirty(boolean dirty) {
+ mScrollingTransformsDirty = dirty;
}
- public void setHoverScale(float scaleFactor) {
- if (scaleFactor != mGlowBackgroundScale) {
- mGlowBackgroundScale = scaleFactor;
- updateGlowRect();
- if (getParent() != null) {
- ((View) getParent()).invalidate();
- }
+ protected void resetOverscrollTransforms() {
+ if (mScrollingTransformsDirty) {
+ setOverscrollTransformsDirty(false);
+ setTranslationX(0);
+ setRotationY(0);
+ // It doesn't matter if we pass true or false here, the important thing is that we
+ // pass 0, which results in the overscroll drawable not being drawn any more.
+ setOverScrollAmount(0, false);
+ setPivotX(getMeasuredWidth() / 2);
+ setPivotY(getMeasuredHeight() / 2);
}
}
- public float getHoverScale() {
- return mGlowBackgroundScale;
- }
-
- public float getHoverAlpha() {
- return mGlowBackgroundAlpha;
- }
-
- public void setHoverAlpha(float alpha) {
- mGlowBackgroundAlpha = alpha;
- invalidate();
- }
-
- void animateDrop() {
- Resources res = getResources();
- float onDropScale = res.getInteger(R.integer.config_screenOnDropScalePercent) / 100.0f;
- ObjectAnimator scaleUp = ObjectAnimator.ofFloat(this, "hoverScale", onDropScale);
- scaleUp.setDuration(res.getInteger(R.integer.config_screenOnDropScaleUpDuration));
- ObjectAnimator scaleDown = ObjectAnimator.ofFloat(this, "hoverScale", 1.0f);
- scaleDown.setDuration(res.getInteger(R.integer.config_screenOnDropScaleDownDuration));
- ObjectAnimator alphaFadeOut = ObjectAnimator.ofFloat(this, "hoverAlpha", 0.0f);
-
- alphaFadeOut.setStartDelay(res.getInteger(R.integer.config_screenOnDropAlphaFadeDelay));
- alphaFadeOut.setDuration(res.getInteger(R.integer.config_screenOnDropAlphaFadeDuration));
-
- AnimatorSet bouncer = new AnimatorSet();
- bouncer.play(scaleUp).before(scaleDown);
- bouncer.play(scaleUp).with(alphaFadeOut);
- bouncer.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- setIsDragOverlapping(true);
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- setIsDragOverlapping(false);
- setHoverScale(1.0f);
- setHoverAlpha(1.0f);
- }
- });
- bouncer.start();
- }
-
@Override
protected void onDraw(Canvas canvas) {
// When we're large, we are either drawn in a "hover" state (ie when dragging an item to
@@ -939,7 +888,6 @@
mBackgroundRect.set(0, 0, w, h);
mForegroundRect.set(mForegroundPadding, mForegroundPadding,
w - 2 * mForegroundPadding, h - 2 * mForegroundPadding);
- updateGlowRect();
}
@Override
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 1553d3c..4e93b22 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -23,6 +23,7 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.View;
@@ -35,8 +36,10 @@
private static int DELETE_ANIMATION_DURATION = 250;
private ColorStateList mOriginalTextColor;
- private TransitionDrawable mDrawable;
private int mHoverColor = 0xFFFF0000;
+ private TransitionDrawable mUninstallDrawable;
+ private TransitionDrawable mRemoveDrawable;
+ private TransitionDrawable mCurrentDrawable;
public DeleteDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -58,8 +61,16 @@
mHoverColor = r.getColor(R.color.delete_target_hover_tint);
mHoverPaint.setColorFilter(new PorterDuffColorFilter(
mHoverColor, PorterDuff.Mode.SRC_ATOP));
- mDrawable = (TransitionDrawable) getCompoundDrawables()[0];
- mDrawable.setCrossFadeEnabled(true);
+ mUninstallDrawable = (TransitionDrawable)
+ r.getDrawable(R.drawable.uninstall_target_selector);
+ mRemoveDrawable = (TransitionDrawable) r.getDrawable(R.drawable.remove_target_selector);
+
+ mRemoveDrawable.setCrossFadeEnabled(true);
+ mUninstallDrawable.setCrossFadeEnabled(true);
+
+ // The current drawable is set to either the remove drawable or the uninstall drawable
+ // and is initially set to the remove drawable, as set in the layout xml.
+ mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
// Remove the text in the Phone UI in landscape
int orientation = getResources().getConfiguration().orientation;
@@ -116,8 +127,15 @@
}
}
+ if (isUninstall) {
+ setCompoundDrawablesWithIntrinsicBounds(mUninstallDrawable, null, null, null);
+ } else {
+ setCompoundDrawablesWithIntrinsicBounds(mRemoveDrawable, null, null, null);
+ }
+ mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
+
mActive = isVisible;
- mDrawable.resetTransition();
+ mCurrentDrawable.resetTransition();
setTextColor(mOriginalTextColor);
((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
if (getText().length() > 0) {
@@ -135,7 +153,7 @@
public void onDragEnter(DragObject d) {
super.onDragEnter(d);
- mDrawable.startTransition(mTransitionDuration);
+ mCurrentDrawable.startTransition(mTransitionDuration);
setTextColor(mHoverColor);
}
@@ -143,7 +161,7 @@
super.onDragExit(d);
if (!d.dragComplete) {
- mDrawable.resetTransition();
+ mCurrentDrawable.resetTransition();
setTextColor(mOriginalTextColor);
}
}
@@ -155,8 +173,8 @@
dragLayer.getViewRectRelativeToSelf(d.dragView, from);
dragLayer.getViewRectRelativeToSelf(this, to);
- int width = mDrawable.getIntrinsicWidth();
- int height = mDrawable.getIntrinsicHeight();
+ int width = mCurrentDrawable.getIntrinsicWidth();
+ int height = mCurrentDrawable.getIntrinsicHeight();
to.set(to.left + getPaddingLeft(), to.top + getPaddingTop(),
to.left + getPaddingLeft() + width, to.bottom);
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index 433db50..3c626d4 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -70,7 +70,7 @@
private boolean mHoverPointClosesFolder = false;
private Rect mHitRect = new Rect();
private int mWorkspaceIndex = -1;
- private int mHotseatIndex = -1;
+ private int mQsbIndex = -1;
/**
* Used to create a new DragLayer from XML.
@@ -627,13 +627,13 @@
private void updateChildIndices() {
if (mLauncher != null) {
mWorkspaceIndex = indexOfChild(mLauncher.getWorkspace());
- mHotseatIndex = indexOfChild(mLauncher.getHotseat());
+ mQsbIndex = indexOfChild(mLauncher.getSearchBar());
}
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
- if (mWorkspaceIndex == -1 || mHotseatIndex == -1 ||
+ if (mWorkspaceIndex == -1 || mQsbIndex == -1 ||
mLauncher.getWorkspace().isDrawingBackgroundGradient()) {
return i;
}
@@ -641,10 +641,10 @@
// This ensures that the workspace is drawn above the hotseat and qsb,
// except when the workspace is drawing a background gradient, in which
// case we want the workspace to stay behind these elements.
- if (i == mHotseatIndex) {
+ if (i == mQsbIndex) {
return mWorkspaceIndex;
} else if (i == mWorkspaceIndex) {
- return mHotseatIndex;
+ return mQsbIndex;
} else {
return i;
}
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index a62dfa6..f91a471 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1956,6 +1956,9 @@
Hotseat getHotseat() {
return mHotseat;
}
+ SearchDropTargetBar getSearchBar() {
+ return mSearchDropTargetBar;
+ }
/**
* Returns the CellLayout of the specified container at the specified screen.
@@ -2503,8 +2506,6 @@
void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
showOutOfSpaceMessage();
- } else {
- layout.animateDrop();
}
}
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 2de7d4a..14ef53f 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -127,6 +127,12 @@
protected boolean mCenterPagesVertically;
protected boolean mAllowOverScroll = true;
protected int mUnboundedScrollX;
+ protected int[] mTempVisiblePagesRange = new int[2];
+
+ // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+ // it is equal to the scaled overscroll position. We use a separate value so as to prevent
+ // the screens from continuing to translate beyond the normal bounds.
+ protected int mOverScrollX;
// parameter that adjusts the layout to be optimized for pages with that scale factor
protected float mLayoutScale = 1.0f;
@@ -376,6 +382,7 @@
overScroll(x - mMaxScrollX);
}
} else {
+ mOverScrollX = x;
super.scrollTo(x, y);
}
@@ -701,20 +708,7 @@
return (int) (maxWidth * mLayoutScale + 0.5f);
}
- @Override
- protected void dispatchDraw(Canvas canvas) {
- int halfScreenSize = getMeasuredWidth() / 2;
- int screenCenter = mScrollX + halfScreenSize;
-
- if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
- screenScrolled(screenCenter);
- mLastScreenCenter = screenCenter;
- mForceScreenScrolled = false;
- }
-
- // Find out which screens are visible; as an optimization we only call draw on them
- // As an optimization, this code assumes that all pages have the same width as the 0th
- // page.
+ protected void getVisiblePages(int[] range) {
final int pageCount = getChildCount();
if (pageCount > 0) {
final int pageWidth = getScaledMeasuredWidth(getPageAt(0));
@@ -731,6 +725,33 @@
rightScreen++;
x += getScaledMeasuredWidth(getPageAt(rightScreen)) + mPageSpacing;
}
+ range[0] = leftScreen;
+ range[1] = rightScreen;
+ } else {
+ range[0] = -1;
+ range[1] = -1;
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ int halfScreenSize = getMeasuredWidth() / 2;
+ // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+ // it is equal to the scaled overscroll position.
+ int screenCenter = mOverScrollX + halfScreenSize;
+
+ if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
+ screenScrolled(screenCenter);
+ mLastScreenCenter = screenCenter;
+ mForceScreenScrolled = false;
+ }
+
+ // Find out which screens are visible; as an optimization we only call draw on them
+ final int pageCount = getChildCount();
+ if (pageCount > 0) {
+ getVisiblePages(mTempVisiblePagesRange);
+ final int leftScreen = mTempVisiblePagesRange[0];
+ final int rightScreen = mTempVisiblePagesRange[1];
final long drawingTime = getDrawingTime();
// Clip to the bounds
@@ -1064,9 +1085,11 @@
int overScrollAmount = (int) Math.round(f * screenSize);
if (amount < 0) {
- mScrollX = overScrollAmount;
+ mOverScrollX = overScrollAmount;
+ mScrollX = 0;
} else {
- mScrollX = mMaxScrollX + overScrollAmount;
+ mOverScrollX = mMaxScrollX + overScrollAmount;
+ mScrollX = mMaxScrollX;
}
invalidate();
}
@@ -1086,9 +1109,11 @@
int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
if (amount < 0) {
- mScrollX = overScrollAmount;
+ mOverScrollX = overScrollAmount;
+ mScrollX = 0;
} else {
- mScrollX = mMaxScrollX + overScrollAmount;
+ mOverScrollX = mMaxScrollX + overScrollAmount;
+ mScrollX = mMaxScrollX;
}
invalidate();
}
@@ -1777,7 +1802,7 @@
updateScrollingIndicatorPosition();
cancelScrollingIndicatorAnimations();
if (immediately) {
- mScrollIndicator.setVisibility(View.GONE);
+ mScrollIndicator.setVisibility(View.INVISIBLE);
mScrollIndicator.setAlpha(0f);
} else {
mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 0f);
@@ -1791,7 +1816,7 @@
@Override
public void onAnimationEnd(Animator animation) {
if (!cancelled) {
- mScrollIndicator.setVisibility(View.GONE);
+ mScrollIndicator.setVisibility(View.INVISIBLE);
}
}
});
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 12c98b2..3eb4db4 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -136,10 +136,13 @@
}
void applyPreview(FastBitmapDrawable preview, int index, boolean scale) {
- final ImageView image = (ImageView) findViewById(R.id.widget_preview);
+ final PagedViewWidgetImageView image =
+ (PagedViewWidgetImageView) findViewById(R.id.widget_preview);
if (preview != null) {
+ image.mAllowRequestLayout = false;
image.setImageDrawable(preview);
image.setScaleType(scale ? ImageView.ScaleType.FIT_START : ImageView.ScaleType.MATRIX);
+ image.mAllowRequestLayout = true;
image.setAlpha(0f);
image.animate()
.alpha(1f)
diff --git a/src/com/android/launcher2/PagedViewWidgetImageView.java b/src/com/android/launcher2/PagedViewWidgetImageView.java
new file mode 100644
index 0000000..844b337
--- /dev/null
+++ b/src/com/android/launcher2/PagedViewWidgetImageView.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011 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.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+
+
+class PagedViewWidgetImageView extends ImageView {
+ public boolean mAllowRequestLayout = true;
+
+ public PagedViewWidgetImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void requestLayout() {
+ if (mAllowRequestLayout) {
+ super.requestLayout();
+ }
+ }
+}
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index e90406e..3a7f24b 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -119,7 +119,7 @@
mDropTargetBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mDropTargetBar.setVisibility(View.GONE);
+ mDropTargetBar.setVisibility(View.INVISIBLE);
mDropTargetBar.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
@@ -136,7 +136,7 @@
mQSBSearchBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mQSBSearchBar.setVisibility(View.GONE);
+ mQSBSearchBar.setVisibility(View.INVISIBLE);
}
});
}
@@ -166,7 +166,7 @@
if (animated) {
mQSBSearchBarFadeOutAnim.start();
} else {
- mQSBSearchBar.setVisibility(View.GONE);
+ mQSBSearchBar.setVisibility(View.INVISIBLE);
mQSBSearchBar.setAlpha(0f);
}
mIsSearchBarHidden = true;
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index d3a31c4..4ad441d 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -1101,6 +1101,7 @@
}
private void screenScrolledLargeUI(int screenCenter) {
+ boolean isInOverscroll = false;
for (int i = 0; i < getChildCount(); i++) {
CellLayout cl = (CellLayout) getChildAt(i);
if (cl != null) {
@@ -1111,11 +1112,17 @@
// If the current page (i) is being over scrolled, we use a different
// set of rules for setting the background alpha multiplier.
if (!isSmall()) {
- if ((mScrollX < 0 && i == 0) || (mScrollX > mMaxScrollX &&
- i == getChildCount() -1 )) {
+ if ((mOverScrollX < 0 && i == 0) || (mOverScrollX > mMaxScrollX &&
+ i == getChildCount() -1)) {
+ isInOverscroll = true;
+ rotation *= -1;
cl.setBackgroundAlphaMultiplier(
overScrollBackgroundAlphaInterpolator(Math.abs(scrollProgress)));
mOverScrollPageIndex = i;
+ cl.setOverScrollAmount(Math.abs(scrollProgress), i == 0);
+ cl.setPivotX(cl.getMeasuredWidth() * (i == 0 ? 0.75f : 0.25f));
+ cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
+ cl.setOverscrollTransformsDirty(true);
} else if (mOverScrollPageIndex != i) {
cl.setBackgroundAlphaMultiplier(
backgroundAlphaInterpolator(Math.abs(scrollProgress)));
@@ -1130,29 +1137,25 @@
cl.fastInvalidate();
}
}
+ if (!isSwitchingState() && !isInOverscroll) {
+ ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
+ ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
+ }
invalidate();
}
- private void resetCellLayoutTransforms(CellLayout cl, boolean left) {
- cl.setTranslationX(0);
- cl.setRotationY(0);
- cl.setOverScrollAmount(0, left);
- cl.setPivotX(cl.getMeasuredWidth() / 2);
- cl.setPivotY(cl.getMeasuredHeight() / 2);
- }
-
private void screenScrolledStandardUI(int screenCenter) {
- if (mScrollX < 0 || mScrollX > mMaxScrollX) {
- int index = mScrollX < 0 ? 0 : getChildCount() - 1;
+ if (mOverScrollX < 0 || mOverScrollX > mMaxScrollX) {
+ int index = mOverScrollX < 0 ? 0 : getChildCount() - 1;
CellLayout cl = (CellLayout) getChildAt(index);
float scrollProgress = getScrollProgress(screenCenter, cl, index);
cl.setOverScrollAmount(Math.abs(scrollProgress), index == 0);
- float translationX = index == 0 ? mScrollX : - (mMaxScrollX - mScrollX);
float rotation = - WORKSPACE_OVERSCROLL_ROTATION * scrollProgress;
cl.setCameraDistance(mDensity * CAMERA_DISTANCE);
cl.setPivotX(cl.getMeasuredWidth() * (index == 0 ? 0.75f : 0.25f));
- cl.setTranslationX(translationX);
+ cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
cl.setRotationY(rotation);
+ cl.setOverscrollTransformsDirty(true);
setFadeForOverScroll(Math.abs(scrollProgress));
} else {
if (mOverscrollFade != 0) {
@@ -1160,8 +1163,8 @@
}
// We don't want to mess with the translations during transitions
if (!isSwitchingState()) {
- resetCellLayoutTransforms((CellLayout) getChildAt(0), true);
- resetCellLayoutTransforms((CellLayout) getChildAt(getChildCount() - 1), false);
+ ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
+ ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
}
}
}
@@ -1241,6 +1244,19 @@
@Override
protected void dispatchDraw(Canvas canvas) {
+ if (mChildrenLayersEnabled) {
+ getVisiblePages(mTempVisiblePagesRange);
+ final int leftScreen = mTempVisiblePagesRange[0];
+ final int rightScreen = mTempVisiblePagesRange[1];
+ if (leftScreen != -1 && rightScreen != -1) {
+ // calling setChildrenLayersEnabled on a view that's not visible/rendered
+ // causes slowdowns on some graphics cards, so we set it here to be sure
+ // it's only called when it's safe (ie when the view will be rendered)
+ for (int i = leftScreen; i <= rightScreen; i++) {
+ ((ViewGroup)getPageAt(i)).setChildrenLayersEnabled(true);
+ }
+ }
+ }
super.dispatchDraw(canvas);
if (mInScrollArea && !LauncherApplication.isScreenLarge()) {
@@ -1345,8 +1361,13 @@
if (enableChildrenLayers != mChildrenLayersEnabled) {
mChildrenLayersEnabled = enableChildrenLayers;
- for (int i = 0; i < getPageCount(); i++) {
- ((ViewGroup)getChildAt(i)).setChildrenLayersEnabled(enableChildrenLayers);
+ // calling setChildrenLayersEnabled on a view that's not visible/rendered
+ // causes slowdowns on some graphics cards, so we only disable it here and leave
+ // the enabling to dispatchDraw
+ if (!enableChildrenLayers) {
+ for (int i = 0; i < getPageCount(); i++) {
+ ((ViewGroup)getChildAt(i)).setChildrenLayersEnabled(false);
+ }
}
}
}
@@ -2960,7 +2981,6 @@
addInScreen(view, container, screen, mTargetCell[0], mTargetCell[1], info.spanX,
info.spanY, insertAtFirst);
cellLayout.onDropChild(view);
- cellLayout.animateDrop();
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
cellLayout.getChildrenLayout().measureChild(view);