DragLayer.java revision 8b805b17158886035b38261eb611d8641701ae43
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; 21716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.TimeInterpolator; 22716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator; 23716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 25716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.content.res.Resources; 266788269814a678af976dfc7d6135993e172ce586Adam Cohenimport android.graphics.Rect; 2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.KeyEvent; 290e26059548e429e5d1c973bebe4c561bead2926fMichael Jurkaimport android.view.MotionEvent; 30ea3763c2672f77539538af8cdd395ad97058eaabRomain Guyimport android.view.View; 318b805b17158886035b38261eb611d8641701ae43Michael Jurkaimport android.view.ViewGroup; 3276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.ViewParent; 333371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityEvent; 343371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityManager; 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 */ 478b805b17158886035b38261eb611d8641701ae43Michael Jurkapublic class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChangeListener { 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); 637bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung private DragView mDropView = null; 646441de0ec2a71862798dd51180d0811b42edd514Adam Cohen private int mAnchorViewInitialScrollX = 0; 656441de0ec2a71862798dd51180d0811b42edd514Adam Cohen private View mAnchorView = null; 668dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 673371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean mHoverPointClosesFolder = false; 683371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private Rect mHitRect = new Rect(); 6921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen private int mWorkspaceIndex = -1; 70ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen private int mQsbIndex = -1; 71ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public static final int ANIMATION_END_DISAPPEAR = 0; 72ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public static final int ANIMATION_END_FADE_OUT = 1; 73ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public static final int ANIMATION_END_REMAIN_VISIBLE = 2; 746788269814a678af976dfc7d6135993e172ce586Adam Cohen 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to create a new DragLayer from XML. 7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 790e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public DragLayer(Context context, AttributeSet attrs) { 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 83be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung 84be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung // Disable multitouch across the workspace/all apps/customize tray 85be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung setMotionEventSplittingEnabled(false); 8621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen setChildrenDrawingOrderEnabled(true); 878b805b17158886035b38261eb611d8641701ae43Michael Jurka setOnHierarchyChangeListener(this); 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 904c98d9235d164680186180974719f551cf935d08Winson Chung public void setup(Launcher launcher, DragController controller) { 914c98d9235d164680186180974719f551cf935d08Winson Chung mLauncher = launcher; 9200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = controller; 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 9700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1003371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) { 1013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect); 1023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 1033371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1053371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1063371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1073371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 1083371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolder(Folder folder, MotionEvent ev) { 1093371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen getDescendantRectRelativeToSelf(folder, mHitRect); 1103371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 1113371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1123371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1133371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1143371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1153371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 11676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean handleTouchDown(MotionEvent ev, boolean intercept) { 1176788269814a678af976dfc7d6135993e172ce586Adam Cohen Rect hitRect = new Rect(); 1186788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 1196788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 1206788269814a678af976dfc7d6135993e172ce586Adam Cohen 1216788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame child: mResizeFrames) { 1226788269814a678af976dfc7d6135993e172ce586Adam Cohen child.getHitRect(hitRect); 1236788269814a678af976dfc7d6135993e172ce586Adam Cohen if (hitRect.contains(x, y)) { 1246788269814a678af976dfc7d6135993e172ce586Adam Cohen if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) { 1256788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = child; 1266788269814a678af976dfc7d6135993e172ce586Adam Cohen mXDown = x; 1276788269814a678af976dfc7d6135993e172ce586Adam Cohen mYDown = y; 1286788269814a678af976dfc7d6135993e172ce586Adam Cohen requestDisallowInterceptTouchEvent(true); 1296788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 1306788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1316788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1326788269814a678af976dfc7d6135993e172ce586Adam Cohen } 13376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1341d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 1357d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung if (currentFolder != null && !mLauncher.isFolderClingVisible() && intercept) { 1361d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen if (currentFolder.isEditingName()) { 1373371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isEventOverFolderTextRegion(currentFolder, ev)) { 1381d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen currentFolder.dismissEditingName(); 13976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 1402801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 14276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1431d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen getDescendantRectRelativeToSelf(currentFolder, hitRect); 1443371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isEventOverFolder(currentFolder, ev)) { 14576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mLauncher.closeFolder(); 14676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 14776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 1482801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1496788269814a678af976dfc7d6135993e172ce586Adam Cohen return false; 1506788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1516788269814a678af976dfc7d6135993e172ce586Adam Cohen 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 1546788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 15576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, true)) { 1566788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 157d1837cc69eb222371afdd30890f7215d117510f2Patrick Dubroy } 1581b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen } 1596788269814a678af976dfc7d6135993e172ce586Adam Cohen clearAllResizeFrames(); 1604db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onInterceptTouchEvent(ev); 16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 1643371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onInterceptHoverEvent(MotionEvent ev) { 1653371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 1663371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (currentFolder == null) { 1673371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1683371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 1698b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 1708b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 1718b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isTouchExplorationEnabled()) { 1723371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen final int action = ev.getAction(); 1733371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen boolean isOverFolder; 1743371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen switch (action) { 1753371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_ENTER: 1763371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen isOverFolder = isEventOverFolder(currentFolder, ev); 1773371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isOverFolder) { 1783371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 1793371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 1803371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1813371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else if (isOverFolder) { 1823371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = false; 1833371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 1843371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1853371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1863371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_MOVE: 1873371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen isOverFolder = isEventOverFolder(currentFolder, ev); 1883371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isOverFolder && !mHoverPointClosesFolder) { 1893371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 1903371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 1913371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1923371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else if (isOverFolder) { 1933371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = false; 1943371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 1953371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1963371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1973371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1983371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1993371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2003371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 2013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 2033371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) { 2048b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 2058b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 2068b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isEnabled()) { 2073371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close; 2083371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent event = AccessibilityEvent.obtain( 2093371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent.TYPE_VIEW_FOCUSED); 2103371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen onInitializeAccessibilityEvent(event); 2118b805b17158886035b38261eb611d8641701ae43Michael Jurka event.getText().add(getContext().getString(stringId)); 2128b805b17158886035b38261eb611d8641701ae43Michael Jurka accessibilityManager.sendAccessibilityEvent(event); 2133371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2143371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2153371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 2163371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 2173371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onHoverEvent(MotionEvent ev) { 2183371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // If we've received this, we've already done the necessary handling 2193371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // in onInterceptHoverEvent. Return true to consume the event. 2203371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 2213371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2223371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 2233371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 2256788269814a678af976dfc7d6135993e172ce586Adam Cohen boolean handled = false; 2266788269814a678af976dfc7d6135993e172ce586Adam Cohen int action = ev.getAction(); 2276788269814a678af976dfc7d6135993e172ce586Adam Cohen 2286788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 2296788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 2306788269814a678af976dfc7d6135993e172ce586Adam Cohen 2316788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 2326788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 23376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, false)) { 2346788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 2356788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2366788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2376788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2386788269814a678af976dfc7d6135993e172ce586Adam Cohen 2396788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mCurrentResizeFrame != null) { 2406788269814a678af976dfc7d6135993e172ce586Adam Cohen handled = true; 2416788269814a678af976dfc7d6135993e172ce586Adam Cohen switch (action) { 2426788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_MOVE: 2436788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 2446788269814a678af976dfc7d6135993e172ce586Adam Cohen break; 2456788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_CANCEL: 2466788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_UP: 247bebf042666cffe52039b875a549a582abd78a431Adam Cohen mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 248bebf042666cffe52039b875a549a582abd78a431Adam Cohen mCurrentResizeFrame.onTouchUp(); 2496788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = null; 2506788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2516788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2526788269814a678af976dfc7d6135993e172ce586Adam Cohen if (handled) return true; 2534db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onTouchEvent(ev); 25491a9c9636f10f1e12cd1f660b2e330634fbdc7dcRomain Guy } 255ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 25635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 25735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Determine the rect of the descendant in this DragLayer's coordinates 25835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 25935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant whose coordinates we want to find. 26035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param r The rect into which to place the results. 26135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. 26235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 263ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen public float getDescendantRectRelativeToSelf(View descendant, Rect r) { 264716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[0] = 0; 265716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[1] = 0; 266ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY); 2678dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen r.set(mTmpXY[0], mTmpXY[1], 2688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mTmpXY[0] + descendant.getWidth(), mTmpXY[1] + descendant.getHeight()); 269ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen return scale; 270716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 27176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 27235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen public void getLocationInDragLayer(View child, int[] loc) { 27335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[0] = 0; 27435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[1] = 0; 27535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen getDescendantCoordRelativeToSelf(child, loc); 27635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 27735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 27835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 27935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Given a coordinate relative to the descendant, find the coordinate in this DragLayer's 28035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * coordinates. 28135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 28235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant to which the passed coordinate is relative. 28335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param coord The coordinate that we want mapped. 28435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. 28535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 286b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) { 287557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = 1.0f; 288557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float[] pt = {coord[0], coord[1]}; 289557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung descendant.getMatrix().mapPoints(pt); 290557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung scale *= descendant.getScaleX(); 291557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[0] += descendant.getLeft(); 292557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[1] += descendant.getTop(); 29376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen ViewParent viewParent = descendant.getParent(); 29476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen while (viewParent instanceof View && viewParent != this) { 29576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen final View view = (View)viewParent; 296557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung view.getMatrix().mapPoints(pt); 297557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung scale *= view.getScaleX(); 298557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[0] += view.getLeft() - view.getScrollX(); 299557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[1] += view.getTop() - view.getScrollY(); 30076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen viewParent = view.getParent(); 30176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 302fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen coord[0] = (int) Math.round(pt[0]); 303fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen coord[1] = (int) Math.round(pt[1]); 304557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung return scale; 30576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 30676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 3073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void getViewRectRelativeToSelf(View v, Rect r) { 3083e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int[] loc = new int[2]; 3098dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen getLocationInWindow(loc); 3103e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int x = loc[0]; 3113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int y = loc[1]; 312716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 3138dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen v.getLocationInWindow(loc); 3143e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vX = loc[0]; 3153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vY = loc[1]; 316716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 3173e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int left = vX - x; 3183e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int top = vY - y; 3193e8f811f31a2275e778244427271f77f4116c08bAdam Cohen r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight()); 320716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 321716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 322ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy @Override 323ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy public boolean dispatchUnhandledMove(View focused, int direction) { 324ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy return mDragController.dispatchUnhandledMove(focused, direction); 325ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 326120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen 3276788269814a678af976dfc7d6135993e172ce586Adam Cohen public static class LayoutParams extends FrameLayout.LayoutParams { 3286788269814a678af976dfc7d6135993e172ce586Adam Cohen public int x, y; 3296788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean customPosition = false; 3306788269814a678af976dfc7d6135993e172ce586Adam Cohen 3316788269814a678af976dfc7d6135993e172ce586Adam Cohen /** 3326788269814a678af976dfc7d6135993e172ce586Adam Cohen * {@inheritDoc} 3336788269814a678af976dfc7d6135993e172ce586Adam Cohen */ 3346788269814a678af976dfc7d6135993e172ce586Adam Cohen public LayoutParams(int width, int height) { 3356788269814a678af976dfc7d6135993e172ce586Adam Cohen super(width, height); 3366788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3376788269814a678af976dfc7d6135993e172ce586Adam Cohen 3386788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setWidth(int width) { 3396788269814a678af976dfc7d6135993e172ce586Adam Cohen this.width = width; 3406788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3416788269814a678af976dfc7d6135993e172ce586Adam Cohen 3426788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getWidth() { 3436788269814a678af976dfc7d6135993e172ce586Adam Cohen return width; 3446788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3456788269814a678af976dfc7d6135993e172ce586Adam Cohen 3466788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setHeight(int height) { 3476788269814a678af976dfc7d6135993e172ce586Adam Cohen this.height = height; 3486788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3496788269814a678af976dfc7d6135993e172ce586Adam Cohen 3506788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getHeight() { 3516788269814a678af976dfc7d6135993e172ce586Adam Cohen return height; 3526788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3536788269814a678af976dfc7d6135993e172ce586Adam Cohen 3546788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setX(int x) { 3556788269814a678af976dfc7d6135993e172ce586Adam Cohen this.x = x; 3566788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3576788269814a678af976dfc7d6135993e172ce586Adam Cohen 3586788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getX() { 3596788269814a678af976dfc7d6135993e172ce586Adam Cohen return x; 3606788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3616788269814a678af976dfc7d6135993e172ce586Adam Cohen 3626788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setY(int y) { 3636788269814a678af976dfc7d6135993e172ce586Adam Cohen this.y = y; 3646788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3656788269814a678af976dfc7d6135993e172ce586Adam Cohen 3666788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getY() { 3676788269814a678af976dfc7d6135993e172ce586Adam Cohen return y; 3686788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3696788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3706788269814a678af976dfc7d6135993e172ce586Adam Cohen 3716788269814a678af976dfc7d6135993e172ce586Adam Cohen protected void onLayout(boolean changed, int l, int t, int r, int b) { 3726788269814a678af976dfc7d6135993e172ce586Adam Cohen super.onLayout(changed, l, t, r, b); 3736788269814a678af976dfc7d6135993e172ce586Adam Cohen int count = getChildCount(); 3746788269814a678af976dfc7d6135993e172ce586Adam Cohen for (int i = 0; i < count; i++) { 3756788269814a678af976dfc7d6135993e172ce586Adam Cohen View child = getChildAt(i); 3766788269814a678af976dfc7d6135993e172ce586Adam Cohen final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams(); 3776788269814a678af976dfc7d6135993e172ce586Adam Cohen if (flp instanceof LayoutParams) { 3786788269814a678af976dfc7d6135993e172ce586Adam Cohen final LayoutParams lp = (LayoutParams) flp; 3796788269814a678af976dfc7d6135993e172ce586Adam Cohen if (lp.customPosition) { 3806788269814a678af976dfc7d6135993e172ce586Adam Cohen child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height); 3816788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3826788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3836788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3846788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3856788269814a678af976dfc7d6135993e172ce586Adam Cohen 3866788269814a678af976dfc7d6135993e172ce586Adam Cohen public void clearAllResizeFrames() { 3876788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mResizeFrames.size() > 0) { 3886788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame frame: mResizeFrames) { 389bebf042666cffe52039b875a549a582abd78a431Adam Cohen frame.commitResize(); 3906788269814a678af976dfc7d6135993e172ce586Adam Cohen removeView(frame); 3916788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3926788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.clear(); 3936788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3946788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3956788269814a678af976dfc7d6135993e172ce586Adam Cohen 3966788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean hasResizeFrames() { 3976788269814a678af976dfc7d6135993e172ce586Adam Cohen return mResizeFrames.size() > 0; 3986788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3996788269814a678af976dfc7d6135993e172ce586Adam Cohen 4006788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean isWidgetBeingResized() { 4016788269814a678af976dfc7d6135993e172ce586Adam Cohen return mCurrentResizeFrame != null; 4026788269814a678af976dfc7d6135993e172ce586Adam Cohen } 4036788269814a678af976dfc7d6135993e172ce586Adam Cohen 4046788269814a678af976dfc7d6135993e172ce586Adam Cohen public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, 4056788269814a678af976dfc7d6135993e172ce586Adam Cohen CellLayout cellLayout) { 4066788269814a678af976dfc7d6135993e172ce586Adam Cohen AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(), 4073a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka widget, cellLayout, this); 4086788269814a678af976dfc7d6135993e172ce586Adam Cohen 4096788269814a678af976dfc7d6135993e172ce586Adam Cohen LayoutParams lp = new LayoutParams(-1, -1); 4106788269814a678af976dfc7d6135993e172ce586Adam Cohen lp.customPosition = true; 4116788269814a678af976dfc7d6135993e172ce586Adam Cohen 4126788269814a678af976dfc7d6135993e172ce586Adam Cohen addView(resizeFrame, lp); 4136788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.add(resizeFrame); 4146788269814a678af976dfc7d6135993e172ce586Adam Cohen 4156788269814a678af976dfc7d6135993e172ce586Adam Cohen resizeFrame.snapToWidget(false); 4166788269814a678af976dfc7d6135993e172ce586Adam Cohen } 417716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 418716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child) { 419557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung animateViewIntoPosition(dragView, child, null); 420557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 421ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 4227bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha, 4237bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable, 4247bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int duration) { 425b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen Rect r = new Rect(); 426b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen getViewRectRelativeToSelf(dragView, r); 427b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromX = r.left; 428b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromY = r.top; 429b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen 4307bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], alpha, 1, 1, scaleX, scaleY, 431ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen onFinishRunnable, animationEndStyle, duration, null); 432ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 433ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 434557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung public void animateViewIntoPosition(DragView dragView, final View child, 435557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung final Runnable onFinishAnimationRunnable) { 4366441de0ec2a71862798dd51180d0811b42edd514Adam Cohen animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable, null); 437ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen } 438ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen 439ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child, int duration, 4406441de0ec2a71862798dd51180d0811b42edd514Adam Cohen final Runnable onFinishAnimationRunnable, View anchorView) { 441a52570f8f9ad65b85e33a2f2e87722f9edd6c6f4Michael Jurka ShortcutAndWidgetContainer parentChildren = (ShortcutAndWidgetContainer) child.getParent(); 442eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung CellLayout parent = (CellLayout) (CellLayout) parentChildren.getParent(); 443716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 444eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung parentChildren.measureChild(child); 445716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4463e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect r = new Rect(); 4473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen getViewRectRelativeToSelf(dragView, r); 448716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 449716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int coord[] = new int[2]; 450ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen coord[0] = lp.x; 451ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen coord[1] = lp.y; 452eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung 4538dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen // Since the child hasn't necessarily been laid out, we force the lp to be updated with 454ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // the correct coordinates (above) and use these to determine the final location 455557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord); 456ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toX = coord[0]; 457ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toY = coord[1]; 458ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen if (child instanceof TextView) { 459eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung float childrenScale = parent.getChildrenScale(); 460ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen TextView tv = (TextView) child; 461ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 462eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung // The child may be scaled (always about the center of the view) so to account for it, 463eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung // we have to offset the position by the scaled size. Once we do that, we can center 464eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung // the drag view about the scaled child view. 465eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung toY += Math.round(((1f - childrenScale) * child.getMeasuredHeight()) / 2 + 466eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung scale * childrenScale * tv.getPaddingTop()); 467eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung toY -= dragView.getMeasuredHeight() * (1 - scale * childrenScale) / 2; 468ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 469eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung 470eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung scale *= childrenScale; 471ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung } else if (child instanceof FolderIcon) { 472ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Account for holographic blur padding on the drag view 473d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen toY -= Workspace.DRAG_BITMAP_PADDING / 2; 474ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Center in the x coordinate about the target's drawable 475ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 476ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } else { 477ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (Math.round(scale * (dragView.getHeight() - child.getMeasuredHeight()))) / 2; 478ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (Math.round(scale * (dragView.getMeasuredWidth() 479ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen - child.getMeasuredWidth()))) / 2; 480ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 481716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 482ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromX = r.left; 483ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromY = r.top; 484716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen child.setVisibility(INVISIBLE); 4858dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Runnable onCompleteRunnable = new Runnable() { 4868dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void run() { 4878dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setVisibility(VISIBLE); 488d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen if (onFinishAnimationRunnable != null) { 489d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onFinishAnimationRunnable.run(); 490d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen } 4918dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 4928dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }; 493ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, scale, scale, 494d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView); 495557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 496557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung 497d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen public void animateViewIntoPosition(final DragView view, final int fromX, final int fromY, 498ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen final int toX, final int toY, float finalAlpha, float initScaleX, float initScaleY, 499ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, 500ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int animationEndStyle, int duration, View anchorView) { 5018dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Rect from = new Rect(fromX, fromY, fromX + 5028dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen view.getMeasuredWidth(), fromY + view.getMeasuredHeight()); 5033e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); 504ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen animateView(view, from, to, finalAlpha, initScaleX, initScaleY, finalScaleX, finalScaleY, duration, 505ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen null, null, onCompleteRunnable, animationEndStyle, anchorView); 5063e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 5073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 508b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen /** 509b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * This method animates a view at the end of a drag and drop animation. 510b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * 511b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param view The view to be animated. This view is drawn directly into DragLayer, and so 512b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * doesn't need to be a child of DragLayer. 513b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param from The initial location of the view. Only the left and top parameters are used. 514b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param to The final location of the view. Only the left and top parameters are used. This 515b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * location doesn't account for scaling, and so should be centered about the desired 516b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * final location (including scaling). 517b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. 518b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalScale The final scale of the view. The view is scaled about its center. 519b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param duration The duration of the animation. 520b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param motionInterpolator The interpolator to use for the location of the view. 521b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param alphaInterpolator The interpolator to use for the alpha of the view. 522b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param onCompleteRunnable Optional runnable to run on animation completion. 523b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param fadeOut Whether or not to fade out the view once the animation completes. If true, 524b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * the runnable will execute after the view is faded out. 5256441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * @param anchorView If not null, this represents the view which the animated view stays 5266441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * anchored to in case scrolling is currently taking place. Note: currently this is 5276441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * only used for the X dimension for the case of the workspace. 528b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen */ 5297bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateView(final DragView view, final Rect from, final Rect to, 5307bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalAlpha, final float initScaleX, final float initScaleY, 5317bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalScaleX, final float finalScaleY, int duration, 5327bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Interpolator motionInterpolator, final Interpolator alphaInterpolator, 5337bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Runnable onCompleteRunnable, final int animationEndStyle, View anchorView) { 5347bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 535716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Calculate the duration of the animation based on the object's distance 5363e8f811f31a2275e778244427271f77f4116c08bAdam Cohen final float dist = (float) Math.sqrt(Math.pow(to.left - from.left, 2) + 5373e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Math.pow(to.top - from.top, 2)); 538716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final Resources res = getResources(); 539716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); 5403e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 5413e8f811f31a2275e778244427271f77f4116c08bAdam Cohen // If duration < 0, this is a cue to compute the duration based on the distance 5423e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (duration < 0) { 5433e8f811f31a2275e778244427271f77f4116c08bAdam Cohen duration = res.getInteger(R.integer.config_dropAnimMaxDuration); 5443e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (dist < maxDist) { 5458dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist); 5463e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 54761b0c69d3fe331d3de338322396d5de691d58613Winson Chung duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration)); 548716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 549716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 550043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Fall back to cubic ease out interpolator for the animation if none is specified 551043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung TimeInterpolator interpolator = null; 5523e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (alphaInterpolator == null || motionInterpolator == null) { 553043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung interpolator = mCubicEaseOutInterpolator; 5543e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 555716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 556043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Animate the view 5577bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float initAlpha = view.getAlpha(); 558043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final float dropViewScale = view.getScaleX(); 559043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung AnimatorUpdateListener updateCb = new AnimatorUpdateListener() { 560043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung @Override 561716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 562716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 5637bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int width = view.getMeasuredWidth(); 5647bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int height = view.getMeasuredHeight(); 565716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 5663e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float alphaPercent = alphaInterpolator == null ? percent : 5673e8f811f31a2275e778244427271f77f4116c08bAdam Cohen alphaInterpolator.getInterpolation(percent); 5683e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float motionPercent = motionInterpolator == null ? percent : 5693e8f811f31a2275e778244427271f77f4116c08bAdam Cohen motionInterpolator.getInterpolation(percent); 570a1cdab039292f3d809528c0e2e38580b37864d8dWinson Chung 5717bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleX = initScaleX * dropViewScale; 5727bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleY = initScaleY * dropViewScale; 5737bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX = finalScaleX * percent + initialScaleX * (1 - percent); 5747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleY = finalScaleY * percent + initialScaleY * (1 - percent); 5757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float alpha = finalAlpha * alphaPercent + initAlpha * (1 - alphaPercent); 5767bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromLeft = from.left + (initialScaleX - 1f) * width / 2; 5787bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromTop = from.top + (initialScaleY - 1f) * height / 2; 5797bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5807bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent))); 5817bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent))); 5827bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5837bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int xPos = x - mDropView.getScrollX() + (mAnchorView != null 5847bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung ? (mAnchorViewInitialScrollX - mAnchorView.getScrollX()) : 0); 5857bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int yPos = y - mDropView.getScrollY(); 5867bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5877bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationX(xPos); 5887bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationY(yPos); 5897bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleX(scaleX); 5907bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleY(scaleY); 5917bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setAlpha(alpha); 592716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 593043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung }; 594043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung animateView(view, updateCb, duration, interpolator, onCompleteRunnable, animationEndStyle, 595043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung anchorView); 596043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 597043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 598043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public void animateView(final DragView view, AnimatorUpdateListener updateCb, int duration, 599043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung TimeInterpolator interpolator, final Runnable onCompleteRunnable, 600043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final int animationEndStyle, View anchorView) { 601043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Clean up the previous animations 602043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mDropAnim != null) mDropAnim.cancel(); 603043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mFadeOutAnim != null) mFadeOutAnim.cancel(); 604043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 605043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Show the drop view if it was previously hidden 606043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView = view; 607043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView.cancelAnimation(); 608043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView.resetLayoutParams(); 609043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 610043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Set the anchor view if the page is scrolling 611043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (anchorView != null) { 612043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mAnchorViewInitialScrollX = anchorView.getScrollX(); 613043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 614043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mAnchorView = anchorView; 615043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 616043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Create and start the animation 617043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim = new ValueAnimator(); 618043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setInterpolator(interpolator); 619043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setDuration(duration); 620043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setFloatValues(0f, 1f); 621043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.addUpdateListener(updateCb); 6223e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim.addListener(new AnimatorListenerAdapter() { 6233e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onAnimationEnd(Animator animation) { 6248dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (onCompleteRunnable != null) { 6258dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen onCompleteRunnable.run(); 6268dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 627ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen switch (animationEndStyle) { 628ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_DISAPPEAR: 629ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen clearAnimatedView(); 630ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 631ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_FADE_OUT: 6328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen fadeOutDragView(); 633ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 634ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_REMAIN_VISIBLE: 635ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 6363e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 6373e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 6383e8f811f31a2275e778244427271f77f4116c08bAdam Cohen }); 639716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.start(); 640716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 641716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 642ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void clearAnimatedView() { 6437bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropAnim != null) { 6447bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropAnim.cancel(); 6457bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 6467bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropView != null) { 647043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDragController.onDeferredEndDrag(mDropView); 6487bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 649ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mDropView = null; 650ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen invalidate(); 651ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 652ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 653ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public View getAnimatedView() { 654ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen return mDropView; 655ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 656ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 6578dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private void fadeOutDragView() { 6588dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim = new ValueAnimator(); 6598dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.setDuration(150); 6608dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.setFloatValues(0f, 1f); 6618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.removeAllUpdateListeners(); 6628dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.addUpdateListener(new AnimatorUpdateListener() { 6638dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 6648dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 6657bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 6667bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float alpha = 1 - percent; 6677bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setAlpha(alpha); 6688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }); 6708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.addListener(new AnimatorListenerAdapter() { 6718dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void onAnimationEnd(Animator animation) { 6727bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropView != null) { 673043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDragController.onDeferredEndDrag(mDropView); 6747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 6758dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropView = null; 676ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen invalidate(); 6778dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6788dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }); 6798dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.start(); 6808dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6818dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 682716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen @Override 6838b805b17158886035b38261eb611d8641701ae43Michael Jurka public void onChildViewAdded(View parent, View child) { 68421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 68521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 68621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 68721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 6888b805b17158886035b38261eb611d8641701ae43Michael Jurka public void onChildViewRemoved(View parent, View child) { 68921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 69021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 69121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 69221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen private void updateChildIndices() { 69321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen if (mLauncher != null) { 69421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen mWorkspaceIndex = indexOfChild(mLauncher.getWorkspace()); 695ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen mQsbIndex = indexOfChild(mLauncher.getSearchBar()); 69621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 69721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 69821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 69921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 70021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen protected int getChildDrawingOrder(int childCount, int i) { 701e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung // We don't want to prioritize the workspace drawing on top of the other children in 702e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung // landscape for the overscroll event. 703e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung if (LauncherApplication.isScreenLandscape(getContext())) { 704e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung return super.getChildDrawingOrder(childCount, i); 705e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung } 706e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung 707ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen if (mWorkspaceIndex == -1 || mQsbIndex == -1 || 70821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen mLauncher.getWorkspace().isDrawingBackgroundGradient()) { 70921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 71021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 71121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 71221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen // This ensures that the workspace is drawn above the hotseat and qsb, 71321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen // except when the workspace is drawing a background gradient, in which 71421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen // case we want the workspace to stay behind these elements. 715ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen if (i == mQsbIndex) { 71621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return mWorkspaceIndex; 71721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } else if (i == mWorkspaceIndex) { 718ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen return mQsbIndex; 71921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } else { 72021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 72121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 72221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 72331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 724