summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2012-11-01 14:48:51 -0700
committerWinson Chung <winsonc@google.com>2012-11-02 10:41:41 -0700
commitf3b9ec8230298e8f707c2fc44a74fb9346ec3d12 (patch)
treead686ed338db14c39bbd88d12e6e625bf7cc62bf
parentfebea58c9215c38fde2c89732b88c832ab69c143 (diff)
downloadframeworks_base-f3b9ec8230298e8f707c2fc44a74fb9346ec3d12.tar.gz
frameworks_base-f3b9ec8230298e8f707c2fc44a74fb9346ec3d12.tar.bz2
frameworks_base-f3b9ec8230298e8f707c2fc44a74fb9346ec3d12.zip
Initial changes to allow dropping on delete target to remove widget.
- Fixing deletion animation Change-Id: Ie93991c0e9af0c6b64c6b3808e38f349f6845965
-rw-r--r--core/res/res/drawable-hdpi/kg_widget_delete_drop_target.pngbin0 -> 1003 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_widget_delete_drop_target.pngbin0 -> 802 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.pngbin0 -> 1392 bytes
-rw-r--r--core/res/res/layout-land/keyguard_host_view.xml6
-rw-r--r--core/res/res/layout-land/keyguard_widget_pager.xml1
-rw-r--r--core/res/res/layout-port/keyguard_host_view.xml10
-rw-r--r--core/res/res/layout-port/keyguard_widget_pager.xml1
-rw-r--r--core/res/res/layout-sw600dp-port/keyguard_host_view.xml6
-rw-r--r--core/res/res/layout/keyguard_widget_remove_drop_target.xml32
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java28
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/PagedView.java324
14 files changed, 337 insertions, 80 deletions
diff --git a/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png
new file mode 100644
index 00000000000..84549ff946a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png
new file mode 100644
index 00000000000..219f3e5cfd6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png
new file mode 100644
index 00000000000..d4965d9f804
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
index 67ac1d5298c..be1d5b6c5ce 100644
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ b/core/res/res/layout-land/keyguard_host_view.xml
@@ -33,6 +33,12 @@
android:layout_height="match_parent"
android:clipChildren="false">
+ <include layout="@layout/keyguard_widget_remove_drop_target"
+ android:id="@+id/keyguard_widget_pager_delete_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal" />
+
<include layout="@layout/keyguard_widget_pager"
android:id="@+id/app_widget_container"
android:layout_width="match_parent"
diff --git a/core/res/res/layout-land/keyguard_widget_pager.xml b/core/res/res/layout-land/keyguard_widget_pager.xml
index 975288fa4cc..02c6d0e8d27 100644
--- a/core/res/res/layout-land/keyguard_widget_pager.xml
+++ b/core/res/res/layout-land/keyguard_widget_pager.xml
@@ -25,7 +25,6 @@
android:paddingRight="25dp"
android:paddingTop="25dp"
android:paddingBottom="25dp"
- android:clipChildren="false"
android:clipToPadding="false"
androidprv:pageSpacing="10dp">
</com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel> \ No newline at end of file
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index b3270e0d9d3..9921313bb72 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -35,6 +35,16 @@
<FrameLayout
android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <include layout="@layout/keyguard_widget_remove_drop_target"
+ android:id="@+id/keyguard_widget_pager_delete_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="match_parent"
android:layout_height="match_parent"
androidprv:layout_childType="widgets">
<include layout="@layout/keyguard_widget_pager"
diff --git a/core/res/res/layout-port/keyguard_widget_pager.xml b/core/res/res/layout-port/keyguard_widget_pager.xml
index 7fd370b6bdb..7f22709a0d7 100644
--- a/core/res/res/layout-port/keyguard_widget_pager.xml
+++ b/core/res/res/layout-port/keyguard_widget_pager.xml
@@ -26,7 +26,6 @@
android:paddingRight="25dp"
android:paddingTop="25dp"
android:paddingBottom="@dimen/kg_widget_pager_bottom_padding"
- android:clipChildren="false"
android:clipToPadding="false"
androidprv:pageSpacing="10dp">
</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
index 5d858ae2ef1..809104d6e0f 100644
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -34,6 +34,12 @@
android:clipChildren="false"
android:orientation="vertical">
+ <include layout="@layout/keyguard_widget_remove_drop_target"
+ android:id="@+id/keyguard_widget_pager_delete_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal" />
+
<include layout="@layout/keyguard_widget_pager"
android:id="@+id/app_widget_container"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_widget_remove_drop_target.xml b/core/res/res/layout/keyguard_widget_remove_drop_target.xml
new file mode 100644
index 00000000000..c4fe9e0fe50
--- /dev/null
+++ b/core/res/res/layout/keyguard_widget_remove_drop_target.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, 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.
+*/
+-->
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center"
+ android:padding="20dp"
+ android:paddingLeft="40dp"
+ android:paddingRight="40dp"
+ android:drawableLeft="@drawable/kg_widget_delete_drop_target"
+ android:drawablePadding="4dp"
+ android:textColor="#FFF"
+ android:textSize="13sp"
+ android:shadowColor="#000"
+ android:shadowDy="1.0"
+ android:shadowRadius="1.0"
+ android:visibility="gone" /> \ No newline at end of file
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index adf53a94b86..a12c14cf6fc 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1319,6 +1319,7 @@
<java-symbol type="id" name="keyguard_sim_puk_view" />
<java-symbol type="id" name="keyguard_account_view" />
<java-symbol type="id" name="keyguard_selector_fade_container" />
+ <java-symbol type="id" name="keyguard_widget_pager_delete_target" />
<java-symbol type="id" name="app_widget_container" />
<java-symbol type="id" name="view_flipper" />
<java-symbol type="id" name="emergency_call_button" />
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 08d388b8363..d28656410d9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -150,9 +150,11 @@ public class KeyguardHostView extends KeyguardViewBase {
protected void onFinishInflate() {
// Grab instances of and make any necessary changes to the main layouts. Create
// view state manager and wire up necessary listeners / callbacks.
+ View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
mAppWidgetContainer.setVisibility(VISIBLE);
mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
+ mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
mAppWidgetContainer.setMinScale(0.5f);
SlidingChallengeLayout slider =
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
index b6ea9baa409..9ffabf8f58c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
@@ -43,6 +43,10 @@ public class KeyguardWidgetFrame extends FrameLayout {
new PorterDuffXfermode(PorterDuff.Mode.ADD);
static final float OUTLINE_ALPHA_MULTIPLIER = 0.6f;
+ static final int HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR = 0x99FF0000;
+
+ // Temporarily disable this for the time being until we know why the gfx is messing up
+ static final boolean ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY = true;
private int mGradientColor;
private LinearGradient mForegroundGradient;
@@ -76,6 +80,8 @@ public class KeyguardWidgetFrame extends FrameLayout {
// This will hold the width value before we've actually been measured
private int mFrameHeight;
+ private boolean mIsHoveringOverDeleteDropTarget;
+
// Multiple callers may try and adjust the alpha of the frame. When a caller shows
// the outlines, we give that caller control, and nobody else can fade them out.
// This prevents animation conflicts.
@@ -110,6 +116,15 @@ public class KeyguardWidgetFrame extends FrameLayout {
cancelLongPress();
}
+ void setIsHoveringOverDeleteDropTarget(boolean isHovering) {
+ if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+ if (mIsHoveringOverDeleteDropTarget != isHovering) {
+ mIsHoveringOverDeleteDropTarget = isHovering;
+ invalidate();
+ }
+ }
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Watch for longpress events at this level to make sure
@@ -171,6 +186,12 @@ public class KeyguardWidgetFrame extends FrameLayout {
c.drawRect(mForegroundRect, mGradientPaint);
}
+ private void drawHoveringOverDeleteOverlay(Canvas c) {
+ if (mIsHoveringOverDeleteDropTarget) {
+ c.drawColor(HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR);
+ }
+ }
+
protected void drawBg(Canvas canvas) {
if (mBackgroundAlpha > 0.0f) {
Drawable bg = mBackgroundDrawable;
@@ -183,9 +204,16 @@ public class KeyguardWidgetFrame extends FrameLayout {
@Override
protected void dispatchDraw(Canvas canvas) {
+ if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+ canvas.save();
+ }
drawBg(canvas);
super.dispatchDraw(canvas);
drawGradientOverlay(canvas);
+ if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+ drawHoveringOverDeleteOverlay(canvas);
+ canvas.restore();
+ }
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index a6d1a029cc0..acb2913a678 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -717,4 +717,10 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
return indexOfChild((KeyguardWidgetFrame)view.getParent());
}
}
+
+ @Override
+ protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {
+ KeyguardWidgetFrame child = getWidgetPageAt(viewIndex);
+ child.setIsHoveringOverDeleteDropTarget(isHovering);
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
index bad50e8616f..00a0aede580 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -48,6 +48,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
import android.widget.Scroller;
import com.android.internal.R;
@@ -205,6 +206,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected int REORDERING_ZOOM_IN_OUT_DURATION = 250;
private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 300;
private float REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE = 0.1f;
+ private long REORDERING_DELETE_DROP_TARGET_FADE_DURATION = 150;
private float mMinScale = 1f;
protected View mDragView;
private AnimatorSet mZoomInOutAnim;
@@ -228,15 +230,21 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Convenience/caching
private Matrix mTmpInvMatrix = new Matrix();
private float[] mTmpPoint = new float[2];
+ private Rect mTmpRect = new Rect();
// Fling to delete
private int FLING_TO_DELETE_FADE_OUT_DURATION = 350;
private float FLING_TO_DELETE_FRICTION = 0.035f;
// The degrees specifies how much deviation from the up vector to still consider a fling "up"
- private float FLING_TO_DELETE_MAX_FLING_DEGREES = 35f;
- private int FLING_TO_DELETE_SLIDE_IN_SIDE_PAGE_DURATION = 250;
+ private float FLING_TO_DELETE_MAX_FLING_DEGREES = 65f;
protected int mFlingToDeleteThresholdVelocity = -1400;
- private boolean mIsFlingingToDelete = false;
+ // Drag to delete
+ private boolean mDeferringForDelete = false;
+ private int DELETE_SLIDE_IN_SIDE_PAGE_DURATION = 250;
+ private int DRAG_TO_DELETE_FADE_OUT_DURATION = 350;
+
+ // Drop to delete
+ private View mDeleteDropTarget;
public interface PageSwitchListener {
void onPageSwitching(View newPage, int newPageIndex);
@@ -294,19 +302,23 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
setOnHierarchyChangeListener(this);
}
+ void setDeleteDropTarget(View v) {
+ mDeleteDropTarget = v;
+ }
+
// Convenience methods to map points from self to parent and vice versa
- float[] mapPointFromSelfToParent(float x, float y) {
+ float[] mapPointFromViewToParent(View v, float x, float y) {
mTmpPoint[0] = x;
mTmpPoint[1] = y;
- getMatrix().mapPoints(mTmpPoint);
- mTmpPoint[0] += getLeft();
- mTmpPoint[1] += getTop();
+ v.getMatrix().mapPoints(mTmpPoint);
+ mTmpPoint[0] += v.getLeft();
+ mTmpPoint[1] += v.getTop();
return mTmpPoint;
}
- float[] mapPointFromParentToSelf(float x, float y) {
- mTmpPoint[0] = x - getLeft();
- mTmpPoint[1] = y - getTop();
- getMatrix().invert(mTmpInvMatrix);
+ float[] mapPointFromParentToView(View v, float x, float y) {
+ mTmpPoint[0] = x - v.getLeft();
+ mTmpPoint[1] = y - v.getTop();
+ v.getMatrix().invert(mTmpInvMatrix);
mTmpInvMatrix.mapPoints(mTmpPoint);
return mTmpPoint;
}
@@ -329,7 +341,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
public void setScaleX(float scaleX) {
super.setScaleX(scaleX);
if (isReordering(true)) {
- float[] p = mapPointFromParentToSelf(mParentDownMotionX, mParentDownMotionY);
+ float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
mLastMotionX = p[0];
mLastMotionY = p[1];
updateDragViewTranslationDuringDrag();
@@ -519,7 +531,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Update the last motion events when scrolling
if (isReordering(true)) {
- float[] p = mapPointFromParentToSelf(mParentDownMotionX, mParentDownMotionY);
+ float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
mLastMotionX = p[0];
mLastMotionY = p[1];
updateDragViewTranslationDuringDrag();
@@ -547,6 +559,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (mTouchState == TOUCH_STATE_REST) {
pageEndMoving();
}
+
onPostReorderingAnimationCompleted();
return true;
}
@@ -640,7 +653,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// ensure that the cache is filled with good values.
invalidateCachedOffsets();
- if (mChildCountOnLastMeasure != getChildCount() && !mIsFlingingToDelete) {
+ if (mChildCountOnLastMeasure != getChildCount() && !mDeferringForDelete) {
setCurrentPage(mCurrentPage);
}
mChildCountOnLastMeasure = getChildCount();
@@ -864,7 +877,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int pageCount = getChildCount();
if (pageCount > 0) {
getVisiblePages(mTempVisiblePagesRange);
- boundByReorderablePages(isReordering(false), mTempVisiblePagesRange);
final int leftScreen = mTempVisiblePagesRange[0];
final int rightScreen = mTempVisiblePagesRange[1];
if (leftScreen != -1 && rightScreen != -1) {
@@ -1046,7 +1058,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mDownScrollX = getScrollX();
mLastMotionX = x;
mLastMotionY = y;
- float[] p = mapPointFromSelfToParent(x, y);
+ float[] p = mapPointFromViewToParent(this, x, y);
mParentDownMotionX = p[0];
mParentDownMotionY = p[1];
mLastMotionXRemainder = 0;
@@ -1278,7 +1290,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mDownMotionX = mLastMotionX = ev.getX();
mDownMotionY = mLastMotionY = ev.getY();
mDownScrollX = getScrollX();
- float[] p = mapPointFromSelfToParent(mLastMotionX, mLastMotionY);
+ float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
mParentDownMotionX = p[0];
mParentDownMotionY = p[1];
mLastMotionXRemainder = 0;
@@ -1330,7 +1342,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Update the parent down so that our zoom animations take this new movement into
// account
- float[] pt = mapPointFromSelfToParent(mLastMotionX, mLastMotionY);
+ float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
mParentDownMotionX = pt[0];
mParentDownMotionY = pt[1];
updateDragViewTranslationDuringDrag();
@@ -1339,11 +1351,16 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int dragViewIndex = indexOfChild(mDragView);
int bufferSize = (int) (REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE *
getViewportWidth());
- int leftBufferEdge = (int) (mapPointFromSelfToParent(mViewport.left, 0)[0]
+ int leftBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.left, 0)[0]
+ bufferSize);
- int rightBufferEdge = (int) (mapPointFromSelfToParent(mViewport.right, 0)[0]
+ int rightBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.right, 0)[0]
- bufferSize);
+ // Change the drag view if we are hovering over the drop target
+ boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget(
+ (int) mParentDownMotionX, (int) mParentDownMotionY);
+ setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);
+
if (DEBUG) Log.d(TAG, "leftBufferEdge: " + leftBufferEdge);
if (DEBUG) Log.d(TAG, "rightBufferEdge: " + rightBufferEdge);
if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX);
@@ -1360,7 +1377,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
final int pageUnderPointIndex = pageIndexToSnapTo;
- if (pageUnderPointIndex > -1) {
+ if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
mTempVisiblePagesRange[0] = 0;
mTempVisiblePagesRange[1] = getPageCount() - 1;
boundByReorderablePages(true, mTempVisiblePagesRange);
@@ -1493,13 +1510,29 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_REORDERING) {
+ // Update the last motion position
+ mLastMotionX = ev.getX();
+ mLastMotionY = ev.getY();
+
+ // Update the parent down so that our zoom animations take this new movement into
+ // account
+ float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+ mParentDownMotionX = pt[0];
+ mParentDownMotionY = pt[1];
+ updateDragViewTranslationDuringDrag();
+ boolean handledFling = false;
if (!DISABLE_FLING_TO_DELETE) {
// Check the velocity and see if we are flinging-to-delete
PointF flingToDeleteVector = isFlingingToDelete();
if (flingToDeleteVector != null) {
onFlingToDelete(flingToDeleteVector);
+ handledFling = true;
}
}
+ if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
+ (int) mParentDownMotionY)) {
+ onDropToDelete();
+ }
} else {
onUnhandledTap(ev);
}
@@ -1776,6 +1809,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
computeScroll();
}
+ mForceScreenScrolled = true;
invalidate();
}
@@ -1999,6 +2033,23 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mZoomInOutAnim.playTogether(
ObjectAnimator.ofFloat(this, "scaleX", mMinScale),
ObjectAnimator.ofFloat(this, "scaleY", mMinScale));
+ mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Show the delete drop target
+ if (mDeleteDropTarget != null) {
+ mDeleteDropTarget.setVisibility(View.VISIBLE);
+ mDeleteDropTarget.animate().alpha(1f)
+ .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mDeleteDropTarget.setAlpha(0f);
+ }
+ });
+ }
+ }
+ });
mZoomInOutAnim.start();
return true;
}
@@ -2015,6 +2066,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mTouchState = TOUCH_STATE_REORDERING;
mIsReordering = true;
+ // Mark all the non-widget pages as invisible
+ getVisiblePages(mTempVisiblePagesRange);
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ for (int i = 0; i < getPageCount(); ++i) {
+ if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+ getPageAt(i).setAlpha(0f);
+ }
+ }
+
// We must invalidate to trigger a redraw to update the layers such that the drag view
// is always drawn on top
invalidate();
@@ -2036,6 +2096,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
R.string.keyguard_accessibility_widget_reorder_end));
}
mIsReordering = false;
+
+ // Mark all the non-widget pages as visible again
+ getVisiblePages(mTempVisiblePagesRange);
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ for (int i = 0; i < getPageCount(); ++i) {
+ if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+ getPageAt(i).setAlpha(1f);
+ }
+ }
}
public boolean startReordering() {
@@ -2080,7 +2149,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
onEndReordering();
}
};
- if (!mIsFlingingToDelete) {
+ if (!mDeferringForDelete) {
mPostReorderingPreZoomInRunnable = new Runnable() {
public void run() {
zoomIn(onCompleteRunnable);
@@ -2094,7 +2163,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Animate the drag view back to the front position
animateDragViewToOriginalPosition();
} else {
- zoomIn(onCompleteRunnable);
+ // Handled in post-delete-animation-callbacks
}
}
@@ -2111,6 +2180,20 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
ObjectAnimator.ofFloat(this, "scaleY", 1f));
mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationStart(Animator animation) {
+ // Hide the delete drop target
+ if (mDeleteDropTarget != null) {
+ mDeleteDropTarget.animate().alpha(0f)
+ .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDeleteDropTarget.setVisibility(View.GONE);
+ }
+ });
+ }
+ }
+ @Override
public void onAnimationCancel(Animator animation) {
mDragView = null;
}
@@ -2194,6 +2277,97 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
};
+ private Runnable createPostDeleteAnimationRunnable(final View dragView) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ int dragViewIndex = indexOfChild(dragView);
+
+ // For each of the pages around the drag view, animate them from the previous
+ // position to the new position in the layout (as a result of the drag view moving
+ // in the layout)
+ // NOTE: We can make an assumption here because we have side-bound pages that we
+ // will always have pages to animate in from the left
+ getVisiblePages(mTempVisiblePagesRange);
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
+ boolean slideFromLeft = (isLastWidgetPage ||
+ dragViewIndex > mTempVisiblePagesRange[0]);
+
+ // Setup the scroll to the correct page before we swap the views
+ if (slideFromLeft) {
+ snapToPageImmediately(dragViewIndex - 1);
+ }
+
+ int firstIndex = (isLastWidgetPage ? 0 : mTempVisiblePagesRange[0]);
+ int lastIndex = Math.min(mTempVisiblePagesRange[1], getPageCount() - 1);
+ int lowerIndex = (slideFromLeft ? firstIndex : dragViewIndex + 1 );
+ int upperIndex = (slideFromLeft ? dragViewIndex - 1 : lastIndex);
+ ArrayList<Animator> animations = new ArrayList<Animator>();
+ for (int i = lowerIndex; i <= upperIndex; ++i) {
+ View v = getChildAt(i);
+ // dragViewIndex < pageUnderPointIndex, so after we remove the
+ // drag view all subsequent views to pageUnderPointIndex will
+ // shift down.
+ int oldX = 0;
+ int newX = 0;
+ if (slideFromLeft) {
+ if (i == 0) {
+ // Simulate the page being offscreen with the page spacing
+ oldX = getViewportOffsetX() + getChildOffset(i) - getChildWidth(i)
+ - mPageSpacing;
+ } else {
+ oldX = getViewportOffsetX() + getChildOffset(i - 1);
+ }
+ newX = getViewportOffsetX() + getChildOffset(i);
+ } else {
+ oldX = getChildOffset(i) - getChildOffset(i - 1);
+ newX = 0;
+ }
+
+ // Animate the view translation from its old position to its new
+ // position
+ AnimatorSet anim = (AnimatorSet) v.getTag();
+ if (anim != null) {
+ anim.cancel();
+ }
+
+ // Note: Hacky, but we want to skip any optimizations to not draw completely
+ // hidden views
+ v.setAlpha(Math.max(v.getAlpha(), 0.01f));
+ v.setTranslationX(oldX - newX);
+ anim = new AnimatorSet();
+ anim.playTogether(
+ ObjectAnimator.ofFloat(v, "translationX", 0f),
+ ObjectAnimator.ofFloat(v, "alpha", 1f));
+ animations.add(anim);
+ v.setTag(anim);
+ }
+
+ AnimatorSet slideAnimations = new AnimatorSet();
+ slideAnimations.playTogether(animations);
+ slideAnimations.setDuration(DELETE_SLIDE_IN_SIDE_PAGE_DURATION);
+ slideAnimations.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ final Runnable onCompleteRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mDeferringForDelete = false;
+ onEndReordering();
+ }
+ };
+ zoomIn(onCompleteRunnable);
+ }
+ });
+ slideAnimations.start();
+
+ removeView(dragView);
+ onRemoveView(dragView);
+ }
+ };
+ }
+
public void onFlingToDelete(PointF vel) {
final long startTime = AnimationUtils.currentAnimationTimeMillis();
@@ -2230,59 +2404,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
AnimatorUpdateListener updateCb = new FlingAlongVectorAnimatorUpdateListener(dragView, vel,
from, startTime, FLING_TO_DELETE_FRICTION);
- final Runnable onAnimationEndRunnable = new Runnable() {
- @Override
- public void run() {
- int dragViewIndex = indexOfChild(dragView);
- // Setup the scroll to the correct page before we swap the views
- snapToPageImmediately(dragViewIndex - 1);
-
- // For each of the pages around the drag view, animate them from the previous
- // position to the new position in the layout (as a result of the drag view moving
- // in the layout)
- // NOTE: We can make an assumption here because we have side-bound pages that we
- // will always have pages to animate in from the left
- int lowerIndex = 0;
- int upperIndex = dragViewIndex - 1;
- for (int i = lowerIndex; i <= upperIndex; ++i) {
- View v = getChildAt(i);
- // dragViewIndex < pageUnderPointIndex, so after we remove the
- // drag view all subsequent views to pageUnderPointIndex will
- // shift down.
- int oldX = 0;
- if (i == 0) {
- oldX = -(getViewportOffsetX() + getChildOffset(i));
- } else {
- oldX = getViewportOffsetX() + getChildOffset(i - 1);
- }
- int newX = getViewportOffsetX() + getChildOffset(i);
-
- // Animate the view translation from its old position to its new
- // position
- AnimatorSet anim = (AnimatorSet) v.getTag();
- if (anim != null) {
- anim.cancel();
- }
-
- v.setTranslationX(oldX - newX);
- anim = new AnimatorSet();
- anim.setDuration(FLING_TO_DELETE_SLIDE_IN_SIDE_PAGE_DURATION);
- anim.playTogether(
- ObjectAnimator.ofFloat(v, "translationX", 0f));
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mIsFlingingToDelete = false;
- }
- });
- anim.start();
- v.setTag(anim);
- }
-
- removeView(dragView);
- onRemoveView(dragView);
- }
- };
+ final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
// Create and start the animation
ValueAnimator mDropAnim = new ValueAnimator();
@@ -2296,11 +2418,57 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
});
mDropAnim.start();
- mIsFlingingToDelete = true;
+ mDeferringForDelete = true;
}
- /* Accessibility */
+ /* Drag to delete */
+ private boolean isHoveringOverDeleteDropTarget(int x, int y) {
+ if (mDeleteDropTarget != null) {
+ mDeleteDropTarget.getGlobalVisibleRect(mTmpRect);
+ return mTmpRect.contains(x, y);
+ }
+ return false;
+ }
+
+ protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {}
+
+ private void onDropToDelete() {
+ final View dragView = mDragView;
+ final float toScale = 0f;
+ final float toAlpha = 0f;
+
+ // Create and start the complex animation
+ ArrayList<Animator> animations = new ArrayList<Animator>();
+ AnimatorSet motionAnim = new AnimatorSet();
+ motionAnim.setInterpolator(new DecelerateInterpolator(2));
+ motionAnim.playTogether(
+ ObjectAnimator.ofFloat(dragView, "scaleX", toScale),
+ ObjectAnimator.ofFloat(dragView, "scaleY", toScale));
+ animations.add(motionAnim);
+
+ AnimatorSet alphaAnim = new AnimatorSet();
+ alphaAnim.setInterpolator(new LinearInterpolator());
+ alphaAnim.playTogether(
+ ObjectAnimator.ofFloat(dragView, "alpha", toAlpha));
+ animations.add(alphaAnim);
+
+ final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
+
+ AnimatorSet anim = new AnimatorSet();
+ anim.playTogether(animations);
+ anim.setDuration(DRAG_TO_DELETE_FADE_OUT_DURATION);
+ anim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ onAnimationEndRunnable.run();
+ }
+ });
+ anim.start();
+
+ mDeferringForDelete = true;
+ }
+
+ /* Accessibility */
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);