DragLayer.java revision b7e1618c627c6471c565f4f599228648d9e70a10
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.Animator; 20716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.AnimatorListenerAdapter; 218dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohenimport android.animation.ObjectAnimator; 22716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.TimeInterpolator; 23716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator; 24716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 26716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.content.res.Resources; 27716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.graphics.Canvas; 286788269814a678af976dfc7d6135993e172ce586Adam Cohenimport android.graphics.Rect; 29ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohenimport android.graphics.drawable.Drawable; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.KeyEvent; 320e26059548e429e5d1c973bebe4c561bead2926fMichael Jurkaimport android.view.MotionEvent; 33ea3763c2672f77539538af8cdd395ad97058eaabRomain Guyimport android.view.View; 3476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.ViewParent; 35716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.view.animation.DecelerateInterpolator; 363e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.Interpolator; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.FrameLayout; 38ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohenimport android.widget.TextView; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 40716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport com.android.launcher.R; 41716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 421d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohenimport java.util.ArrayList; 436788269814a678af976dfc7d6135993e172ce586Adam Cohen 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 450e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * A ViewGroup that coordinates dragging across its descendants 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 4700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragLayer extends FrameLayout { 48120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen private DragController mDragController; 49120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen private int[] mTmpXY = new int[2]; 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 51716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private int mXDown, mYDown; 52716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private Launcher mLauncher; 53716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 546788269814a678af976dfc7d6135993e172ce586Adam Cohen // Variables relating to resizing widgets 556788269814a678af976dfc7d6135993e172ce586Adam Cohen private final ArrayList<AppWidgetResizeFrame> mResizeFrames = 566788269814a678af976dfc7d6135993e172ce586Adam Cohen new ArrayList<AppWidgetResizeFrame>(); 576788269814a678af976dfc7d6135993e172ce586Adam Cohen private AppWidgetResizeFrame mCurrentResizeFrame; 58716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 59716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Variables relating to animation of views after drop 60716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private ValueAnimator mDropAnim = null; 618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private ValueAnimator mFadeOutAnim = null; 628dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private TimeInterpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f); 63716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private View mDropView = null; 648dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 653e8f811f31a2275e778244427271f77f4116c08bAdam Cohen private int[] mDropViewPos = new int[2]; 663e8f811f31a2275e778244427271f77f4116c08bAdam Cohen private float mDropViewScale; 673e8f811f31a2275e778244427271f77f4116c08bAdam Cohen private float mDropViewAlpha; 686788269814a678af976dfc7d6135993e172ce586Adam Cohen 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to create a new DragLayer from XML. 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 730e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public DragLayer(Context context, AttributeSet attrs) { 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 77be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung 78be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung // Disable multitouch across the workspace/all apps/customize tray 79be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung setMotionEventSplittingEnabled(false); 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 824c98d9235d164680186180974719f551cf935d08Winson Chung public void setup(Launcher launcher, DragController controller) { 834c98d9235d164680186180974719f551cf935d08Winson Chung mLauncher = launcher; 8400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = controller; 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 8900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean handleTouchDown(MotionEvent ev, boolean intercept) { 936788269814a678af976dfc7d6135993e172ce586Adam Cohen Rect hitRect = new Rect(); 946788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 956788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 966788269814a678af976dfc7d6135993e172ce586Adam Cohen 976788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame child: mResizeFrames) { 986788269814a678af976dfc7d6135993e172ce586Adam Cohen child.getHitRect(hitRect); 996788269814a678af976dfc7d6135993e172ce586Adam Cohen if (hitRect.contains(x, y)) { 1006788269814a678af976dfc7d6135993e172ce586Adam Cohen if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) { 1016788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = child; 1026788269814a678af976dfc7d6135993e172ce586Adam Cohen mXDown = x; 1036788269814a678af976dfc7d6135993e172ce586Adam Cohen mYDown = y; 1046788269814a678af976dfc7d6135993e172ce586Adam Cohen requestDisallowInterceptTouchEvent(true); 1056788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 1066788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1076788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1086788269814a678af976dfc7d6135993e172ce586Adam Cohen } 10976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1101d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 1111d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen if (currentFolder != null && intercept) { 1121d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen if (currentFolder.isEditingName()) { 1131d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen getDescendantRectRelativeToSelf(currentFolder.getEditTextRegion(), hitRect); 1142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (!hitRect.contains(x, y)) { 1151d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen currentFolder.dismissEditingName(); 11676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 1172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 11976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1201d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen getDescendantRectRelativeToSelf(currentFolder, hitRect); 12176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (!hitRect.contains(x, y)) { 12276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mLauncher.closeFolder(); 12376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 12476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 1252801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1266788269814a678af976dfc7d6135993e172ce586Adam Cohen return false; 1276788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1286788269814a678af976dfc7d6135993e172ce586Adam Cohen 12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 1316788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 13276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, true)) { 1336788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 134d1837cc69eb222371afdd30890f7215d117510f2Patrick Dubroy } 1351b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen } 1366788269814a678af976dfc7d6135993e172ce586Adam Cohen clearAllResizeFrames(); 1374db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onInterceptTouchEvent(ev); 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 1426788269814a678af976dfc7d6135993e172ce586Adam Cohen boolean handled = false; 1436788269814a678af976dfc7d6135993e172ce586Adam Cohen int action = ev.getAction(); 1446788269814a678af976dfc7d6135993e172ce586Adam Cohen 1456788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 1466788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 1476788269814a678af976dfc7d6135993e172ce586Adam Cohen 1486788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 1496788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 15076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, false)) { 1516788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 1526788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1536788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1546788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1556788269814a678af976dfc7d6135993e172ce586Adam Cohen 1566788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mCurrentResizeFrame != null) { 1576788269814a678af976dfc7d6135993e172ce586Adam Cohen handled = true; 1586788269814a678af976dfc7d6135993e172ce586Adam Cohen switch (action) { 1596788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_MOVE: 1606788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 1616788269814a678af976dfc7d6135993e172ce586Adam Cohen break; 1626788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_CANCEL: 1636788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_UP: 1646788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown); 1656788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = null; 1666788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1676788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1686788269814a678af976dfc7d6135993e172ce586Adam Cohen if (handled) return true; 1694db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onTouchEvent(ev); 17091a9c9636f10f1e12cd1f660b2e330634fbdc7dcRomain Guy } 171ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 172ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen public float getDescendantRectRelativeToSelf(View descendant, Rect r) { 173716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[0] = 0; 174716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[1] = 0; 175ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY); 1768dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen r.set(mTmpXY[0], mTmpXY[1], 1778dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mTmpXY[0] + descendant.getWidth(), mTmpXY[1] + descendant.getHeight()); 178ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen return scale; 179716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 18076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 181b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) { 182557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = 1.0f; 183557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float[] pt = {coord[0], coord[1]}; 184557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung descendant.getMatrix().mapPoints(pt); 185557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung scale *= descendant.getScaleX(); 186557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[0] += descendant.getLeft(); 187557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[1] += descendant.getTop(); 18876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen ViewParent viewParent = descendant.getParent(); 18976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen while (viewParent instanceof View && viewParent != this) { 19076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen final View view = (View)viewParent; 191557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung view.getMatrix().mapPoints(pt); 192557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung scale *= view.getScaleX(); 193557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[0] += view.getLeft() - view.getScrollX(); 194557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[1] += view.getTop() - view.getScrollY(); 19576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen viewParent = view.getParent(); 19676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 197557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung coord[0] = (int) pt[0]; 198557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung coord[1] = (int) pt[1]; 199557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung return scale; 20076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 20176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 2028dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void getLocationInDragLayer(View child, int[] loc) { 2038dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen loc[0] = 0; 2048dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen loc[1] = 0; 2058dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen getDescendantCoordRelativeToSelf(child, loc); 2068dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 2078dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 2083e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void getViewRectRelativeToSelf(View v, Rect r) { 2093e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int[] loc = new int[2]; 2108dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen getLocationInWindow(loc); 2113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int x = loc[0]; 2123e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int y = loc[1]; 213716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 2148dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen v.getLocationInWindow(loc); 2153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vX = loc[0]; 2163e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vY = loc[1]; 217716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 2183e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int left = vX - x; 2193e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int top = vY - y; 2203e8f811f31a2275e778244427271f77f4116c08bAdam Cohen r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight()); 221716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 222716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 223ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy @Override 224ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy public boolean dispatchUnhandledMove(View focused, int direction) { 225ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy return mDragController.dispatchUnhandledMove(focused, direction); 226ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 227120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen 2286788269814a678af976dfc7d6135993e172ce586Adam Cohen public static class LayoutParams extends FrameLayout.LayoutParams { 2296788269814a678af976dfc7d6135993e172ce586Adam Cohen public int x, y; 2306788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean customPosition = false; 2316788269814a678af976dfc7d6135993e172ce586Adam Cohen 2326788269814a678af976dfc7d6135993e172ce586Adam Cohen /** 2336788269814a678af976dfc7d6135993e172ce586Adam Cohen * {@inheritDoc} 2346788269814a678af976dfc7d6135993e172ce586Adam Cohen */ 2356788269814a678af976dfc7d6135993e172ce586Adam Cohen public LayoutParams(int width, int height) { 2366788269814a678af976dfc7d6135993e172ce586Adam Cohen super(width, height); 2376788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2386788269814a678af976dfc7d6135993e172ce586Adam Cohen 2396788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setWidth(int width) { 2406788269814a678af976dfc7d6135993e172ce586Adam Cohen this.width = width; 2416788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2426788269814a678af976dfc7d6135993e172ce586Adam Cohen 2436788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getWidth() { 2446788269814a678af976dfc7d6135993e172ce586Adam Cohen return width; 2456788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2466788269814a678af976dfc7d6135993e172ce586Adam Cohen 2476788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setHeight(int height) { 2486788269814a678af976dfc7d6135993e172ce586Adam Cohen this.height = height; 2496788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2506788269814a678af976dfc7d6135993e172ce586Adam Cohen 2516788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getHeight() { 2526788269814a678af976dfc7d6135993e172ce586Adam Cohen return height; 2536788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2546788269814a678af976dfc7d6135993e172ce586Adam Cohen 2556788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setX(int x) { 2566788269814a678af976dfc7d6135993e172ce586Adam Cohen this.x = x; 2576788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2586788269814a678af976dfc7d6135993e172ce586Adam Cohen 2596788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getX() { 2606788269814a678af976dfc7d6135993e172ce586Adam Cohen return x; 2616788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2626788269814a678af976dfc7d6135993e172ce586Adam Cohen 2636788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setY(int y) { 2646788269814a678af976dfc7d6135993e172ce586Adam Cohen this.y = y; 2656788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2666788269814a678af976dfc7d6135993e172ce586Adam Cohen 2676788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getY() { 2686788269814a678af976dfc7d6135993e172ce586Adam Cohen return y; 2696788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2706788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2716788269814a678af976dfc7d6135993e172ce586Adam Cohen 2726788269814a678af976dfc7d6135993e172ce586Adam Cohen protected void onLayout(boolean changed, int l, int t, int r, int b) { 2736788269814a678af976dfc7d6135993e172ce586Adam Cohen super.onLayout(changed, l, t, r, b); 2746788269814a678af976dfc7d6135993e172ce586Adam Cohen int count = getChildCount(); 2756788269814a678af976dfc7d6135993e172ce586Adam Cohen for (int i = 0; i < count; i++) { 2766788269814a678af976dfc7d6135993e172ce586Adam Cohen View child = getChildAt(i); 2776788269814a678af976dfc7d6135993e172ce586Adam Cohen final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams(); 2786788269814a678af976dfc7d6135993e172ce586Adam Cohen if (flp instanceof LayoutParams) { 2796788269814a678af976dfc7d6135993e172ce586Adam Cohen final LayoutParams lp = (LayoutParams) flp; 2806788269814a678af976dfc7d6135993e172ce586Adam Cohen if (lp.customPosition) { 2816788269814a678af976dfc7d6135993e172ce586Adam Cohen child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height); 2826788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2836788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2846788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2856788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2866788269814a678af976dfc7d6135993e172ce586Adam Cohen 2876788269814a678af976dfc7d6135993e172ce586Adam Cohen public void clearAllResizeFrames() { 2886788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mResizeFrames.size() > 0) { 2896788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame frame: mResizeFrames) { 2906788269814a678af976dfc7d6135993e172ce586Adam Cohen removeView(frame); 2916788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2926788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.clear(); 2936788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2946788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2956788269814a678af976dfc7d6135993e172ce586Adam Cohen 2966788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean hasResizeFrames() { 2976788269814a678af976dfc7d6135993e172ce586Adam Cohen return mResizeFrames.size() > 0; 2986788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2996788269814a678af976dfc7d6135993e172ce586Adam Cohen 3006788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean isWidgetBeingResized() { 3016788269814a678af976dfc7d6135993e172ce586Adam Cohen return mCurrentResizeFrame != null; 3026788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3036788269814a678af976dfc7d6135993e172ce586Adam Cohen 3046788269814a678af976dfc7d6135993e172ce586Adam Cohen public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, 3056788269814a678af976dfc7d6135993e172ce586Adam Cohen CellLayout cellLayout) { 3066788269814a678af976dfc7d6135993e172ce586Adam Cohen AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(), 3076788269814a678af976dfc7d6135993e172ce586Adam Cohen itemInfo, widget, cellLayout, this); 3086788269814a678af976dfc7d6135993e172ce586Adam Cohen 3096788269814a678af976dfc7d6135993e172ce586Adam Cohen LayoutParams lp = new LayoutParams(-1, -1); 3106788269814a678af976dfc7d6135993e172ce586Adam Cohen lp.customPosition = true; 3116788269814a678af976dfc7d6135993e172ce586Adam Cohen 3126788269814a678af976dfc7d6135993e172ce586Adam Cohen addView(resizeFrame, lp); 3136788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.add(resizeFrame); 3146788269814a678af976dfc7d6135993e172ce586Adam Cohen 3156788269814a678af976dfc7d6135993e172ce586Adam Cohen resizeFrame.snapToWidget(false); 3166788269814a678af976dfc7d6135993e172ce586Adam Cohen } 317716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 318716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child) { 319557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung animateViewIntoPosition(dragView, child, null); 320557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 321ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 322b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen public void animateViewIntoPosition(DragView dragView, final int[] pos, float scale, 323b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen Runnable onFinishRunnable) { 324b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen Rect r = new Rect(); 325b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen getViewRectRelativeToSelf(dragView, r); 326b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromX = r.left; 327b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromY = r.top; 328b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen 329b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], scale, 330b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen onFinishRunnable, true); 331b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen } 332b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen 333557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung public void animateViewIntoPosition(DragView dragView, final View child, 334557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung final Runnable onFinishAnimationRunnable) { 335716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen ((CellLayoutChildren) child.getParent()).measureChild(child); 336716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 337716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 3383e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect r = new Rect(); 3393e8f811f31a2275e778244427271f77f4116c08bAdam Cohen getViewRectRelativeToSelf(dragView, r); 340716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 341716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int coord[] = new int[2]; 342ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen coord[0] = lp.x; 343ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen coord[1] = lp.y; 3448dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen // Since the child hasn't necessarily been laid out, we force the lp to be updated with 345ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // the correct coordinates (above) and use these to determine the final location 346557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord); 347ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toX = coord[0]; 348ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toY = coord[1]; 349ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen if (child instanceof TextView) { 350ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen TextView tv = (TextView) child; 351ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen Drawable d = tv.getCompoundDrawables()[1]; 352ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 353ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // Center in the y coordinate about the target's drawable 354ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY += Math.round(scale * tv.getPaddingTop()); 355ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (dragView.getHeight() - (int) Math.round(scale * d.getIntrinsicHeight())) / 2; 356ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // Center in the x coordinate about the target's drawable 357ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 358ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } else { 359ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (Math.round(scale * (dragView.getHeight() - child.getMeasuredHeight()))) / 2; 360ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (Math.round(scale * (dragView.getMeasuredWidth() 361ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen - child.getMeasuredWidth()))) / 2; 362ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 363716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 364ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromX = r.left; 365ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromY = r.top; 366716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen child.setVisibility(INVISIBLE); 3678dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setAlpha(0); 3688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Runnable onCompleteRunnable = new Runnable() { 3698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void run() { 3708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setVisibility(VISIBLE); 3718dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen ObjectAnimator oa = ObjectAnimator.ofFloat(child, "alpha", 0f, 1f); 3728dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen oa.setDuration(60); 373557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung oa.addListener(new AnimatorListenerAdapter() { 374557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung @Override 375557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung public void onAnimationEnd(android.animation.Animator animation) { 376557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung if (onFinishAnimationRunnable != null) { 377557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung onFinishAnimationRunnable.run(); 378557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 379557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 380557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung }); 3818dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen oa.start(); 3828dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 3838dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }; 384557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung animateViewIntoPosition(dragView, fromX, fromY, toX, toY, scale, onCompleteRunnable, true); 385557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 386557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung 387716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private void animateViewIntoPosition(final View view, final int fromX, final int fromY, 388557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung final int toX, final int toY, float finalScale, Runnable onCompleteRunnable, 389557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung boolean fadeOut) { 3908dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Rect from = new Rect(fromX, fromY, fromX + 3918dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen view.getMeasuredWidth(), fromY + view.getMeasuredHeight()); 3923e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); 393557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung animateView(view, from, to, 1f, finalScale, -1, null, null, onCompleteRunnable, true); 3943e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 3953e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 396b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen /** 397b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * This method animates a view at the end of a drag and drop animation. 398b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * 399b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param view The view to be animated. This view is drawn directly into DragLayer, and so 400b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * doesn't need to be a child of DragLayer. 401b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param from The initial location of the view. Only the left and top parameters are used. 402b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param to The final location of the view. Only the left and top parameters are used. This 403b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * location doesn't account for scaling, and so should be centered about the desired 404b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * final location (including scaling). 405b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. 406b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalScale The final scale of the view. The view is scaled about its center. 407b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param duration The duration of the animation. 408b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param motionInterpolator The interpolator to use for the location of the view. 409b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param alphaInterpolator The interpolator to use for the alpha of the view. 410b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param onCompleteRunnable Optional runnable to run on animation completion. 411b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param fadeOut Whether or not to fade out the view once the animation completes. If true, 412b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * the runnable will execute after the view is faded out. 413b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen */ 4143e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void animateView(final View view, final Rect from, final Rect to, final float finalAlpha, 4153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen final float finalScale, int duration, final Interpolator motionInterpolator, 4168dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final Interpolator alphaInterpolator, final Runnable onCompleteRunnable, 4178dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final boolean fadeOut) { 418716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Calculate the duration of the animation based on the object's distance 4193e8f811f31a2275e778244427271f77f4116c08bAdam Cohen final float dist = (float) Math.sqrt(Math.pow(to.left - from.left, 2) + 4203e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Math.pow(to.top - from.top, 2)); 421716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final Resources res = getResources(); 422716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); 4233e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 4243e8f811f31a2275e778244427271f77f4116c08bAdam Cohen // If duration < 0, this is a cue to compute the duration based on the distance 4253e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (duration < 0) { 4263e8f811f31a2275e778244427271f77f4116c08bAdam Cohen duration = res.getInteger(R.integer.config_dropAnimMaxDuration); 4273e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (dist < maxDist) { 4288dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist); 4293e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 430716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 431716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 432716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen if (mDropAnim != null) { 4338dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropAnim.cancel(); 434716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 435716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 436ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen if (mFadeOutAnim != null) { 437ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mFadeOutAnim.cancel(); 438ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 439ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 4403e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropView = view; 4413e8f811f31a2275e778244427271f77f4116c08bAdam Cohen final float initialAlpha = view.getAlpha(); 4423e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim = new ValueAnimator(); 4433e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (alphaInterpolator == null || motionInterpolator == null) { 4448dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropAnim.setInterpolator(mCubicEaseOutInterpolator); 4453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 446716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 447716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.setDuration(duration); 448716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.setFloatValues(0.0f, 1.0f); 449716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.removeAllUpdateListeners(); 450716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.addUpdateListener(new AnimatorUpdateListener() { 451716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 452716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 453716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Invalidate the old position 454716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int width = view.getMeasuredWidth(); 455716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int height = view.getMeasuredHeight(); 456716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen invalidate(mDropViewPos[0], mDropViewPos[1], 457716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropViewPos[0] + width, mDropViewPos[1] + height); 458716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4593e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float alphaPercent = alphaInterpolator == null ? percent : 4603e8f811f31a2275e778244427271f77f4116c08bAdam Cohen alphaInterpolator.getInterpolation(percent); 4613e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float motionPercent = motionInterpolator == null ? percent : 4623e8f811f31a2275e778244427271f77f4116c08bAdam Cohen motionInterpolator.getInterpolation(percent); 4633e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 464ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mDropViewPos[0] = from.left + (int) Math.round(((to.left - from.left) * motionPercent)); 465ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mDropViewPos[1] = from.top + (int) Math.round(((to.top - from.top) * motionPercent)); 4663e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropViewScale = percent * finalScale + (1 - percent); 4673e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropViewAlpha = alphaPercent * finalAlpha + (1 - alphaPercent) * initialAlpha; 468716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen invalidate(mDropViewPos[0], mDropViewPos[1], 469716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropViewPos[0] + width, mDropViewPos[1] + height); 470716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 471716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen }); 4723e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim.addListener(new AnimatorListenerAdapter() { 4733e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onAnimationEnd(Animator animation) { 4748dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (onCompleteRunnable != null) { 4758dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen onCompleteRunnable.run(); 4768dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 4778dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (fadeOut) { 4788dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen fadeOutDragView(); 4798dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } else { 4803e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropView = null; 4813e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 4823e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 4833e8f811f31a2275e778244427271f77f4116c08bAdam Cohen }); 484716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.start(); 485716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 486716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4878dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private void fadeOutDragView() { 4888dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim = new ValueAnimator(); 4898dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.setDuration(150); 4908dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.setFloatValues(0f, 1f); 4918dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.removeAllUpdateListeners(); 4928dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.addUpdateListener(new AnimatorUpdateListener() { 4938dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 4948dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 4958dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropViewAlpha = 1 - percent; 4968dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen int width = mDropView.getMeasuredWidth(); 4978dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen int height = mDropView.getMeasuredHeight(); 4988dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen invalidate(mDropViewPos[0], mDropViewPos[1], 4998dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropViewPos[0] + width, mDropViewPos[1] + height); 5008dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 5018dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }); 5028dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.addListener(new AnimatorListenerAdapter() { 5038dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void onAnimationEnd(Animator animation) { 5048dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropView = null; 5058dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 5068dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }); 5078dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.start(); 5088dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 5098dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 510716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen @Override 511716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen protected void dispatchDraw(Canvas canvas) { 512716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen super.dispatchDraw(canvas); 513716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen if (mDropView != null) { 514716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // We are animating an item that was just dropped on the home screen. 515716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Render its View in the current animation position. 516716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen canvas.save(Canvas.MATRIX_SAVE_FLAG); 517716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final int xPos = mDropViewPos[0] - mDropView.getScrollX(); 518716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final int yPos = mDropViewPos[1] - mDropView.getScrollY(); 5193e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int width = mDropView.getMeasuredWidth(); 5203e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int height = mDropView.getMeasuredHeight(); 521716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen canvas.translate(xPos, yPos); 5223e8f811f31a2275e778244427271f77f4116c08bAdam Cohen canvas.translate((1 - mDropViewScale) * width / 2, (1 - mDropViewScale) * height / 2); 5233e8f811f31a2275e778244427271f77f4116c08bAdam Cohen canvas.scale(mDropViewScale, mDropViewScale); 5243e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropView.setAlpha(mDropViewAlpha); 525716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropView.draw(canvas); 526716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen canvas.restore(); 527716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 528716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 52931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 530