DragLayer.java revision d41fbf5680750e34335bba6b38298186c144a4b7
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; 353371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityEvent; 363371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityManager; 37716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.view.animation.DecelerateInterpolator; 383e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.Interpolator; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.FrameLayout; 40ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohenimport android.widget.TextView; 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 42716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport com.android.launcher.R; 43716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 441d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohenimport java.util.ArrayList; 456788269814a678af976dfc7d6135993e172ce586Adam Cohen 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 470e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * A ViewGroup that coordinates dragging across its descendants 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragLayer extends FrameLayout { 50120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen private DragController mDragController; 51120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen private int[] mTmpXY = new int[2]; 5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 53716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private int mXDown, mYDown; 54716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private Launcher mLauncher; 55716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 566788269814a678af976dfc7d6135993e172ce586Adam Cohen // Variables relating to resizing widgets 576788269814a678af976dfc7d6135993e172ce586Adam Cohen private final ArrayList<AppWidgetResizeFrame> mResizeFrames = 586788269814a678af976dfc7d6135993e172ce586Adam Cohen new ArrayList<AppWidgetResizeFrame>(); 596788269814a678af976dfc7d6135993e172ce586Adam Cohen private AppWidgetResizeFrame mCurrentResizeFrame; 60716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 61716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Variables relating to animation of views after drop 62716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private ValueAnimator mDropAnim = null; 638dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private ValueAnimator mFadeOutAnim = null; 648dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private TimeInterpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f); 657bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung private DragView mDropView = null; 666441de0ec2a71862798dd51180d0811b42edd514Adam Cohen private int mAnchorViewInitialScrollX = 0; 676441de0ec2a71862798dd51180d0811b42edd514Adam Cohen private View mAnchorView = null; 688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 693371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean mHoverPointClosesFolder = false; 703371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private Rect mHitRect = new Rect(); 7121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen private int mWorkspaceIndex = -1; 72ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen private int mQsbIndex = -1; 73ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public static final int ANIMATION_END_DISAPPEAR = 0; 74ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public static final int ANIMATION_END_FADE_OUT = 1; 75ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public static final int ANIMATION_END_REMAIN_VISIBLE = 2; 766788269814a678af976dfc7d6135993e172ce586Adam Cohen 7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to create a new DragLayer from XML. 7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 810e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public DragLayer(Context context, AttributeSet attrs) { 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 85be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung 86be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung // Disable multitouch across the workspace/all apps/customize tray 87be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung setMotionEventSplittingEnabled(false); 8821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen setChildrenDrawingOrderEnabled(true); 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 914c98d9235d164680186180974719f551cf935d08Winson Chung public void setup(Launcher launcher, DragController controller) { 924c98d9235d164680186180974719f551cf935d08Winson Chung mLauncher = launcher; 9300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = controller; 9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 9800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); 9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) { 1023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect); 1033371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 1043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1053371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1063371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1073371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1083371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 1093371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolder(Folder folder, MotionEvent ev) { 1103371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen getDescendantRectRelativeToSelf(folder, mHitRect); 1113371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 1123371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1133371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1143371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1153371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1163371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 11776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean handleTouchDown(MotionEvent ev, boolean intercept) { 1186788269814a678af976dfc7d6135993e172ce586Adam Cohen Rect hitRect = new Rect(); 1196788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 1206788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 1216788269814a678af976dfc7d6135993e172ce586Adam Cohen 1226788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame child: mResizeFrames) { 1236788269814a678af976dfc7d6135993e172ce586Adam Cohen child.getHitRect(hitRect); 1246788269814a678af976dfc7d6135993e172ce586Adam Cohen if (hitRect.contains(x, y)) { 1256788269814a678af976dfc7d6135993e172ce586Adam Cohen if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) { 1266788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = child; 1276788269814a678af976dfc7d6135993e172ce586Adam Cohen mXDown = x; 1286788269814a678af976dfc7d6135993e172ce586Adam Cohen mYDown = y; 1296788269814a678af976dfc7d6135993e172ce586Adam Cohen requestDisallowInterceptTouchEvent(true); 1306788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 1316788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1326788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1336788269814a678af976dfc7d6135993e172ce586Adam Cohen } 13476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1351d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 1367d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung if (currentFolder != null && !mLauncher.isFolderClingVisible() && intercept) { 1371d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen if (currentFolder.isEditingName()) { 1383371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isEventOverFolderTextRegion(currentFolder, ev)) { 1391d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen currentFolder.dismissEditingName(); 14076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 1412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1422801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 14376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1441d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen getDescendantRectRelativeToSelf(currentFolder, hitRect); 1453371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isEventOverFolder(currentFolder, ev)) { 14676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mLauncher.closeFolder(); 14776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 14876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 1492801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1506788269814a678af976dfc7d6135993e172ce586Adam Cohen return false; 1516788269814a678af976dfc7d6135993e172ce586Adam Cohen } 1526788269814a678af976dfc7d6135993e172ce586Adam Cohen 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 1556788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 15676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, true)) { 1576788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 158d1837cc69eb222371afdd30890f7215d117510f2Patrick Dubroy } 1591b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen } 1606788269814a678af976dfc7d6135993e172ce586Adam Cohen clearAllResizeFrames(); 1614db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onInterceptTouchEvent(ev); 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 1653371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onInterceptHoverEvent(MotionEvent ev) { 1663371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 1673371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (currentFolder == null) { 1683371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1693371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 1703371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) { 1713371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen final int action = ev.getAction(); 1723371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen boolean isOverFolder; 1733371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen switch (action) { 1743371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_ENTER: 1753371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen isOverFolder = isEventOverFolder(currentFolder, ev); 1763371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isOverFolder) { 1773371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 1783371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 1793371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1803371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else if (isOverFolder) { 1813371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = false; 1823371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 1833371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1843371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1853371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_MOVE: 1863371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen isOverFolder = isEventOverFolder(currentFolder, ev); 1873371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isOverFolder && !mHoverPointClosesFolder) { 1883371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 1893371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 1903371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1913371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else if (isOverFolder) { 1923371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = false; 1933371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 1943371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1953371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1963371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1973371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1983371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1993371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 2003371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 2023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) { 2033371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (AccessibilityManager.getInstance(mContext).isEnabled()) { 2043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close; 2053371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent event = AccessibilityEvent.obtain( 2063371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent.TYPE_VIEW_FOCUSED); 2073371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen onInitializeAccessibilityEvent(event); 2083371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen event.getText().add(mContext.getString(stringId)); 2093371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event); 2103371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2113371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2123371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 2133371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 2143371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onHoverEvent(MotionEvent ev) { 2153371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // If we've received this, we've already done the necessary handling 2163371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // in onInterceptHoverEvent. Return true to consume the event. 2173371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 2183371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 2193371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 2203371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 2226788269814a678af976dfc7d6135993e172ce586Adam Cohen boolean handled = false; 2236788269814a678af976dfc7d6135993e172ce586Adam Cohen int action = ev.getAction(); 2246788269814a678af976dfc7d6135993e172ce586Adam Cohen 2256788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 2266788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 2276788269814a678af976dfc7d6135993e172ce586Adam Cohen 2286788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 2296788269814a678af976dfc7d6135993e172ce586Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 23076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, false)) { 2316788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 2326788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2336788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2346788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2356788269814a678af976dfc7d6135993e172ce586Adam Cohen 2366788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mCurrentResizeFrame != null) { 2376788269814a678af976dfc7d6135993e172ce586Adam Cohen handled = true; 2386788269814a678af976dfc7d6135993e172ce586Adam Cohen switch (action) { 2396788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_MOVE: 2406788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 2416788269814a678af976dfc7d6135993e172ce586Adam Cohen break; 2426788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_CANCEL: 2436788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_UP: 2446788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown); 2456788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = null; 2466788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2476788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2486788269814a678af976dfc7d6135993e172ce586Adam Cohen if (handled) return true; 2494db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onTouchEvent(ev); 25091a9c9636f10f1e12cd1f660b2e330634fbdc7dcRomain Guy } 251ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 25235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 25335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Determine the rect of the descendant in this DragLayer's coordinates 25435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 25535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant whose coordinates we want to find. 25635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param r The rect into which to place the results. 25735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. 25835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 259ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen public float getDescendantRectRelativeToSelf(View descendant, Rect r) { 260716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[0] = 0; 261716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[1] = 0; 262ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY); 2638dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen r.set(mTmpXY[0], mTmpXY[1], 2648dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mTmpXY[0] + descendant.getWidth(), mTmpXY[1] + descendant.getHeight()); 265ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen return scale; 266716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 26776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 26835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen public void getLocationInDragLayer(View child, int[] loc) { 26935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[0] = 0; 27035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[1] = 0; 27135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen getDescendantCoordRelativeToSelf(child, loc); 27235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 27335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 27435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 27535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Given a coordinate relative to the descendant, find the coordinate in this DragLayer's 27635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * coordinates. 27735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 27835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant to which the passed coordinate is relative. 27935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param coord The coordinate that we want mapped. 28035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. 28135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 282b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) { 283557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = 1.0f; 284557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float[] pt = {coord[0], coord[1]}; 285557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung descendant.getMatrix().mapPoints(pt); 286557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung scale *= descendant.getScaleX(); 287557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[0] += descendant.getLeft(); 288557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[1] += descendant.getTop(); 28976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen ViewParent viewParent = descendant.getParent(); 29076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen while (viewParent instanceof View && viewParent != this) { 29176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen final View view = (View)viewParent; 292557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung view.getMatrix().mapPoints(pt); 293557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung scale *= view.getScaleX(); 294557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[0] += view.getLeft() - view.getScrollX(); 295557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung pt[1] += view.getTop() - view.getScrollY(); 29676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen viewParent = view.getParent(); 29776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 298fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen coord[0] = (int) Math.round(pt[0]); 299fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen coord[1] = (int) Math.round(pt[1]); 300557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung return scale; 30176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 30276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 3033e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void getViewRectRelativeToSelf(View v, Rect r) { 3043e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int[] loc = new int[2]; 3058dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen getLocationInWindow(loc); 3063e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int x = loc[0]; 3073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int y = loc[1]; 308716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 3098dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen v.getLocationInWindow(loc); 3103e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vX = loc[0]; 3113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vY = loc[1]; 312716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 3133e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int left = vX - x; 3143e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int top = vY - y; 3153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight()); 316716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 317716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 318ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy @Override 319ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy public boolean dispatchUnhandledMove(View focused, int direction) { 320ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy return mDragController.dispatchUnhandledMove(focused, direction); 321ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 322120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen 3236788269814a678af976dfc7d6135993e172ce586Adam Cohen public static class LayoutParams extends FrameLayout.LayoutParams { 3246788269814a678af976dfc7d6135993e172ce586Adam Cohen public int x, y; 3256788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean customPosition = false; 3266788269814a678af976dfc7d6135993e172ce586Adam Cohen 3276788269814a678af976dfc7d6135993e172ce586Adam Cohen /** 3286788269814a678af976dfc7d6135993e172ce586Adam Cohen * {@inheritDoc} 3296788269814a678af976dfc7d6135993e172ce586Adam Cohen */ 3306788269814a678af976dfc7d6135993e172ce586Adam Cohen public LayoutParams(int width, int height) { 3316788269814a678af976dfc7d6135993e172ce586Adam Cohen super(width, height); 3326788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3336788269814a678af976dfc7d6135993e172ce586Adam Cohen 3346788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setWidth(int width) { 3356788269814a678af976dfc7d6135993e172ce586Adam Cohen this.width = width; 3366788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3376788269814a678af976dfc7d6135993e172ce586Adam Cohen 3386788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getWidth() { 3396788269814a678af976dfc7d6135993e172ce586Adam Cohen return width; 3406788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3416788269814a678af976dfc7d6135993e172ce586Adam Cohen 3426788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setHeight(int height) { 3436788269814a678af976dfc7d6135993e172ce586Adam Cohen this.height = height; 3446788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3456788269814a678af976dfc7d6135993e172ce586Adam Cohen 3466788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getHeight() { 3476788269814a678af976dfc7d6135993e172ce586Adam Cohen return height; 3486788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3496788269814a678af976dfc7d6135993e172ce586Adam Cohen 3506788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setX(int x) { 3516788269814a678af976dfc7d6135993e172ce586Adam Cohen this.x = x; 3526788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3536788269814a678af976dfc7d6135993e172ce586Adam Cohen 3546788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getX() { 3556788269814a678af976dfc7d6135993e172ce586Adam Cohen return x; 3566788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3576788269814a678af976dfc7d6135993e172ce586Adam Cohen 3586788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setY(int y) { 3596788269814a678af976dfc7d6135993e172ce586Adam Cohen this.y = y; 3606788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3616788269814a678af976dfc7d6135993e172ce586Adam Cohen 3626788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getY() { 3636788269814a678af976dfc7d6135993e172ce586Adam Cohen return y; 3646788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3656788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3666788269814a678af976dfc7d6135993e172ce586Adam Cohen 3676788269814a678af976dfc7d6135993e172ce586Adam Cohen protected void onLayout(boolean changed, int l, int t, int r, int b) { 3686788269814a678af976dfc7d6135993e172ce586Adam Cohen super.onLayout(changed, l, t, r, b); 3696788269814a678af976dfc7d6135993e172ce586Adam Cohen int count = getChildCount(); 3706788269814a678af976dfc7d6135993e172ce586Adam Cohen for (int i = 0; i < count; i++) { 3716788269814a678af976dfc7d6135993e172ce586Adam Cohen View child = getChildAt(i); 3726788269814a678af976dfc7d6135993e172ce586Adam Cohen final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams(); 3736788269814a678af976dfc7d6135993e172ce586Adam Cohen if (flp instanceof LayoutParams) { 3746788269814a678af976dfc7d6135993e172ce586Adam Cohen final LayoutParams lp = (LayoutParams) flp; 3756788269814a678af976dfc7d6135993e172ce586Adam Cohen if (lp.customPosition) { 3766788269814a678af976dfc7d6135993e172ce586Adam Cohen child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height); 3776788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3786788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3796788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3806788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3816788269814a678af976dfc7d6135993e172ce586Adam Cohen 3826788269814a678af976dfc7d6135993e172ce586Adam Cohen public void clearAllResizeFrames() { 3836788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mResizeFrames.size() > 0) { 3846788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame frame: mResizeFrames) { 3856788269814a678af976dfc7d6135993e172ce586Adam Cohen removeView(frame); 3866788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3876788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.clear(); 3886788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3896788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3906788269814a678af976dfc7d6135993e172ce586Adam Cohen 3916788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean hasResizeFrames() { 3926788269814a678af976dfc7d6135993e172ce586Adam Cohen return mResizeFrames.size() > 0; 3936788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3946788269814a678af976dfc7d6135993e172ce586Adam Cohen 3956788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean isWidgetBeingResized() { 3966788269814a678af976dfc7d6135993e172ce586Adam Cohen return mCurrentResizeFrame != null; 3976788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3986788269814a678af976dfc7d6135993e172ce586Adam Cohen 3996788269814a678af976dfc7d6135993e172ce586Adam Cohen public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, 4006788269814a678af976dfc7d6135993e172ce586Adam Cohen CellLayout cellLayout) { 4016788269814a678af976dfc7d6135993e172ce586Adam Cohen AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(), 4026788269814a678af976dfc7d6135993e172ce586Adam Cohen itemInfo, widget, cellLayout, this); 4036788269814a678af976dfc7d6135993e172ce586Adam Cohen 4046788269814a678af976dfc7d6135993e172ce586Adam Cohen LayoutParams lp = new LayoutParams(-1, -1); 4056788269814a678af976dfc7d6135993e172ce586Adam Cohen lp.customPosition = true; 4066788269814a678af976dfc7d6135993e172ce586Adam Cohen 4076788269814a678af976dfc7d6135993e172ce586Adam Cohen addView(resizeFrame, lp); 4086788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.add(resizeFrame); 4096788269814a678af976dfc7d6135993e172ce586Adam Cohen 4106788269814a678af976dfc7d6135993e172ce586Adam Cohen resizeFrame.snapToWidget(false); 4116788269814a678af976dfc7d6135993e172ce586Adam Cohen } 412716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 413716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child) { 414557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung animateViewIntoPosition(dragView, child, null); 415557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 416ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 4177bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha, 4187bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable, 4197bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int duration) { 420b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen Rect r = new Rect(); 421b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen getViewRectRelativeToSelf(dragView, r); 422b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromX = r.left; 423b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromY = r.top; 424b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen 4257bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], alpha, 1, 1, scaleX, scaleY, 426ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen onFinishRunnable, animationEndStyle, duration, null); 427ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 428ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 429557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung public void animateViewIntoPosition(DragView dragView, final View child, 430557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung final Runnable onFinishAnimationRunnable) { 4316441de0ec2a71862798dd51180d0811b42edd514Adam Cohen animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable, null); 432ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen } 433ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen 434ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child, int duration, 4356441de0ec2a71862798dd51180d0811b42edd514Adam Cohen final Runnable onFinishAnimationRunnable, View anchorView) { 436716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen ((CellLayoutChildren) child.getParent()).measureChild(child); 437716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 438716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4393e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect r = new Rect(); 4403e8f811f31a2275e778244427271f77f4116c08bAdam Cohen getViewRectRelativeToSelf(dragView, r); 441716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 442716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int coord[] = new int[2]; 443ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen coord[0] = lp.x; 444ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen coord[1] = lp.y; 4458dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen // Since the child hasn't necessarily been laid out, we force the lp to be updated with 446ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // the correct coordinates (above) and use these to determine the final location 447557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord); 448ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toX = coord[0]; 449ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toY = coord[1]; 450ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen if (child instanceof TextView) { 451ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen TextView tv = (TextView) child; 452ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen Drawable d = tv.getCompoundDrawables()[1]; 453ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 454ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // Center in the y coordinate about the target's drawable 455ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY += Math.round(scale * tv.getPaddingTop()); 456ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (dragView.getHeight() - (int) Math.round(scale * d.getIntrinsicHeight())) / 2; 457ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // Center in the x coordinate about the target's drawable 458ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 459ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung } else if (child instanceof FolderIcon) { 460ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Account for holographic blur padding on the drag view 461d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen toY -= Workspace.DRAG_BITMAP_PADDING / 2; 462ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Center in the x coordinate about the target's drawable 463ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 464ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } else { 465ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (Math.round(scale * (dragView.getHeight() - child.getMeasuredHeight()))) / 2; 466ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (Math.round(scale * (dragView.getMeasuredWidth() 467ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen - child.getMeasuredWidth()))) / 2; 468ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 469716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 470ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromX = r.left; 471ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromY = r.top; 472716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen child.setVisibility(INVISIBLE); 4738dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Runnable onCompleteRunnable = new Runnable() { 4748dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void run() { 4758dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setVisibility(VISIBLE); 476d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen if (onFinishAnimationRunnable != null) { 477d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onFinishAnimationRunnable.run(); 478d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen } 4798dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 4808dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }; 481ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, scale, scale, 482d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView); 483557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 484557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung 485d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen public void animateViewIntoPosition(final DragView view, final int fromX, final int fromY, 486ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen final int toX, final int toY, float finalAlpha, float initScaleX, float initScaleY, 487ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, 488ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int animationEndStyle, int duration, View anchorView) { 4898dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Rect from = new Rect(fromX, fromY, fromX + 4908dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen view.getMeasuredWidth(), fromY + view.getMeasuredHeight()); 4913e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); 492ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen animateView(view, from, to, finalAlpha, initScaleX, initScaleY, finalScaleX, finalScaleY, duration, 493ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen null, null, onCompleteRunnable, animationEndStyle, anchorView); 4943e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 4953e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 496b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen /** 497b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * This method animates a view at the end of a drag and drop animation. 498b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * 499b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param view The view to be animated. This view is drawn directly into DragLayer, and so 500b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * doesn't need to be a child of DragLayer. 501b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param from The initial location of the view. Only the left and top parameters are used. 502b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param to The final location of the view. Only the left and top parameters are used. This 503b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * location doesn't account for scaling, and so should be centered about the desired 504b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * final location (including scaling). 505b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. 506b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalScale The final scale of the view. The view is scaled about its center. 507b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param duration The duration of the animation. 508b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param motionInterpolator The interpolator to use for the location of the view. 509b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param alphaInterpolator The interpolator to use for the alpha of the view. 510b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param onCompleteRunnable Optional runnable to run on animation completion. 511b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param fadeOut Whether or not to fade out the view once the animation completes. If true, 512b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * the runnable will execute after the view is faded out. 5136441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * @param anchorView If not null, this represents the view which the animated view stays 5146441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * anchored to in case scrolling is currently taking place. Note: currently this is 5156441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * only used for the X dimension for the case of the workspace. 516b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen */ 5177bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateView(final DragView view, final Rect from, final Rect to, 5187bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalAlpha, final float initScaleX, final float initScaleY, 5197bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalScaleX, final float finalScaleY, int duration, 5207bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Interpolator motionInterpolator, final Interpolator alphaInterpolator, 5217bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Runnable onCompleteRunnable, final int animationEndStyle, View anchorView) { 5227bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 523716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Calculate the duration of the animation based on the object's distance 5243e8f811f31a2275e778244427271f77f4116c08bAdam Cohen final float dist = (float) Math.sqrt(Math.pow(to.left - from.left, 2) + 5253e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Math.pow(to.top - from.top, 2)); 526716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final Resources res = getResources(); 527716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); 5283e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 5293e8f811f31a2275e778244427271f77f4116c08bAdam Cohen // If duration < 0, this is a cue to compute the duration based on the distance 5303e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (duration < 0) { 5313e8f811f31a2275e778244427271f77f4116c08bAdam Cohen duration = res.getInteger(R.integer.config_dropAnimMaxDuration); 5323e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (dist < maxDist) { 5338dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist); 5343e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 53561b0c69d3fe331d3de338322396d5de691d58613Winson Chung duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration)); 536716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 537716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 538716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen if (mDropAnim != null) { 5398dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropAnim.cancel(); 540716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 541716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 542ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen if (mFadeOutAnim != null) { 543ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mFadeOutAnim.cancel(); 544ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 545ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 5467bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung // Show the drop view if it was previously hidden 5473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropView = view; 5487bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.cancelAnimation(); 5497bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.resetLayoutParams(); 5503e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim = new ValueAnimator(); 5513e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (alphaInterpolator == null || motionInterpolator == null) { 5528dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropAnim.setInterpolator(mCubicEaseOutInterpolator); 5533e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 554716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 5556441de0ec2a71862798dd51180d0811b42edd514Adam Cohen if (anchorView != null) { 5566441de0ec2a71862798dd51180d0811b42edd514Adam Cohen mAnchorViewInitialScrollX = anchorView.getScrollX(); 5576441de0ec2a71862798dd51180d0811b42edd514Adam Cohen } 5586441de0ec2a71862798dd51180d0811b42edd514Adam Cohen mAnchorView = anchorView; 5596441de0ec2a71862798dd51180d0811b42edd514Adam Cohen 5607bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float initAlpha = view.getAlpha(); 5617bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float dropViewScale = mDropView.getScaleX(); 5627bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 563716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.setDuration(duration); 564716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.setFloatValues(0.0f, 1.0f); 565716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.removeAllUpdateListeners(); 566716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.addUpdateListener(new AnimatorUpdateListener() { 567716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 568716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 5697bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int width = view.getMeasuredWidth(); 5707bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int height = view.getMeasuredHeight(); 571716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 5723e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float alphaPercent = alphaInterpolator == null ? percent : 5733e8f811f31a2275e778244427271f77f4116c08bAdam Cohen alphaInterpolator.getInterpolation(percent); 5743e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float motionPercent = motionInterpolator == null ? percent : 5753e8f811f31a2275e778244427271f77f4116c08bAdam Cohen motionInterpolator.getInterpolation(percent); 576a1cdab039292f3d809528c0e2e38580b37864d8dWinson Chung 5777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleX = initScaleX * dropViewScale; 5787bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleY = initScaleY * dropViewScale; 5797bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX = finalScaleX * percent + initialScaleX * (1 - percent); 5807bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleY = finalScaleY * percent + initialScaleY * (1 - percent); 5817bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float alpha = finalAlpha * alphaPercent + initAlpha * (1 - alphaPercent); 5827bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5837bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromLeft = from.left + (initialScaleX - 1f) * width / 2; 5847bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromTop = from.top + (initialScaleY - 1f) * height / 2; 5857bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5867bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent))); 5877bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent))); 5887bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5897bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int xPos = x - mDropView.getScrollX() + (mAnchorView != null 5907bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung ? (mAnchorViewInitialScrollX - mAnchorView.getScrollX()) : 0); 5917bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int yPos = y - mDropView.getScrollY(); 5927bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 5937bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationX(xPos); 5947bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationY(yPos); 5957bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleX(scaleX); 5967bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleY(scaleY); 5977bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setAlpha(alpha); 598716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 599716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen }); 6003e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim.addListener(new AnimatorListenerAdapter() { 6013e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onAnimationEnd(Animator animation) { 6028dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (onCompleteRunnable != null) { 6038dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen onCompleteRunnable.run(); 6048dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 605ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen switch (animationEndStyle) { 606ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_DISAPPEAR: 607ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen clearAnimatedView(); 608ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 609ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_FADE_OUT: 6108dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen fadeOutDragView(); 611ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 612ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_REMAIN_VISIBLE: 613ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 6143e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 6153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 6163e8f811f31a2275e778244427271f77f4116c08bAdam Cohen }); 617716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.start(); 618716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 619716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 620ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void clearAnimatedView() { 6217bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropAnim != null) { 6227bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropAnim.cancel(); 6237bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 6247bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropView != null) { 6257bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.remove(); 6267bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 627ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mDropView = null; 628ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen invalidate(); 629ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 630ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 631ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public View getAnimatedView() { 632ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen return mDropView; 633ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 634ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 6358dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private void fadeOutDragView() { 6368dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim = new ValueAnimator(); 6378dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.setDuration(150); 6388dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.setFloatValues(0f, 1f); 6398dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.removeAllUpdateListeners(); 6408dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.addUpdateListener(new AnimatorUpdateListener() { 6418dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 6428dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 6437bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 6447bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float alpha = 1 - percent; 6457bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setAlpha(alpha); 6468dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6478dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }); 6488dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.addListener(new AnimatorListenerAdapter() { 6498dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void onAnimationEnd(Animator animation) { 6507bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropView != null) { 6517bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.remove(); 6527bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 6538dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDropView = null; 654ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen invalidate(); 6558dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6568dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }); 6578dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFadeOutAnim.start(); 6588dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6598dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 660716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen @Override 66121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen protected void onViewAdded(View child) { 66221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen super.onViewAdded(child); 66321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 66421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 66521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 66621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 66721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen protected void onViewRemoved(View child) { 66821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen super.onViewRemoved(child); 66921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 67021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 67121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 67221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen private void updateChildIndices() { 67321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen if (mLauncher != null) { 67421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen mWorkspaceIndex = indexOfChild(mLauncher.getWorkspace()); 675ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen mQsbIndex = indexOfChild(mLauncher.getSearchBar()); 67621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 67721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 67821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 67921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 68021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen protected int getChildDrawingOrder(int childCount, int i) { 681e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung // We don't want to prioritize the workspace drawing on top of the other children in 682e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung // landscape for the overscroll event. 683e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung if (LauncherApplication.isScreenLandscape(getContext())) { 684e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung return super.getChildDrawingOrder(childCount, i); 685e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung } 686e96e5cb768fcc6f1211c8c31fa2da4dcd4e465ccWinson Chung 687ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen if (mWorkspaceIndex == -1 || mQsbIndex == -1 || 68821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen mLauncher.getWorkspace().isDrawingBackgroundGradient()) { 68921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 69021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 69121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 69221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen // This ensures that the workspace is drawn above the hotseat and qsb, 69321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen // except when the workspace is drawing a background gradient, in which 69421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen // case we want the workspace to stay behind these elements. 695ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen if (i == mQsbIndex) { 69621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return mWorkspaceIndex; 69721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } else if (i == mWorkspaceIndex) { 698ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen return mQsbIndex; 69921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } else { 70021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 70121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 70221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 70331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 704