Winson Chung | 7dd3b52 | 2018-05-14 10:07:15 -0700 | [diff] [blame] | 1 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (C) 2008 The Android Open Source Project |
| 4 | * |
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | */ |
| 17 | |
Vadim Tryshev | fedca43 | 2015-08-19 17:55:02 -0700 | [diff] [blame] | 18 | package com.android.launcher3.dragndrop; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 19 | |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 20 | import static android.animation.ObjectAnimator.ofFloat; |
| 21 | |
Kateryna Ivanova | 7120373 | 2023-05-24 15:09:00 +0000 | [diff] [blame] | 22 | import static com.android.app.animation.Interpolators.DECELERATE_1_5; |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 23 | import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; |
| 24 | import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; |
| 25 | import static com.android.launcher3.Utilities.mapRange; |
| 26 | import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; |
Sunny Goyal | d0030b0 | 2017-12-08 15:07:24 -0800 | [diff] [blame] | 27 | import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; |
| 28 | |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 29 | import android.animation.Animator; |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 30 | import android.animation.ObjectAnimator; |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 31 | import android.animation.TimeInterpolator; |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 32 | import android.animation.TypeEvaluator; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 33 | import android.content.Context; |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 34 | import android.content.res.Resources; |
Winson Chung | 360e63f | 2012-04-27 13:48:05 -0700 | [diff] [blame] | 35 | import android.graphics.Canvas; |
Adam Cohen | 6788269 | 2011-03-11 15:29:03 -0800 | [diff] [blame] | 36 | import android.graphics.Rect; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 37 | import android.util.AttributeSet; |
Dave Hawkey | 26279c6 | 2013-11-07 14:26:19 -0700 | [diff] [blame] | 38 | import android.view.KeyEvent; |
| 39 | import android.view.MotionEvent; |
| 40 | import android.view.View; |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 41 | import android.view.accessibility.AccessibilityEvent; |
| 42 | import android.view.accessibility.AccessibilityManager; |
Adam Cohen | 3e8f811 | 2011-07-02 18:03:00 -0700 | [diff] [blame] | 43 | import android.view.animation.Interpolator; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 44 | |
Kateryna Ivanova | 7120373 | 2023-05-24 15:09:00 +0000 | [diff] [blame] | 45 | import com.android.app.animation.Interpolators; |
Sunny Goyal | 740ac7f | 2016-09-28 16:47:32 -0700 | [diff] [blame] | 46 | import com.android.launcher3.AbstractFloatingView; |
Tony Wickham | 1bce7fd | 2016-04-28 17:39:03 -0700 | [diff] [blame] | 47 | import com.android.launcher3.DropTargetBar; |
Vadim Tryshev | fedca43 | 2015-08-19 17:55:02 -0700 | [diff] [blame] | 48 | import com.android.launcher3.Launcher; |
Adam Cohen | f9c184a | 2016-01-15 16:47:43 -0800 | [diff] [blame] | 49 | import com.android.launcher3.R; |
Vadim Tryshev | fedca43 | 2015-08-19 17:55:02 -0700 | [diff] [blame] | 50 | import com.android.launcher3.ShortcutAndWidgetContainer; |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 51 | import com.android.launcher3.Utilities; |
Sunny Goyal | 5d1873a | 2018-05-08 11:10:44 -0700 | [diff] [blame] | 52 | import com.android.launcher3.Workspace; |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 53 | import com.android.launcher3.anim.PendingAnimation; |
| 54 | import com.android.launcher3.anim.SpringProperty; |
Sebastian Franco | d468299 | 2022-10-05 13:03:09 -0500 | [diff] [blame] | 55 | import com.android.launcher3.celllayout.CellLayoutLayoutParams; |
Sunny Goyal | 2611943 | 2016-02-18 22:09:23 +0000 | [diff] [blame] | 56 | import com.android.launcher3.folder.Folder; |
Adam Cohen | f7ca3b4 | 2021-02-22 11:03:58 -0800 | [diff] [blame] | 57 | import com.android.launcher3.graphics.Scrim; |
Sunny Goyal | 3333b0c | 2016-05-09 20:43:21 -0700 | [diff] [blame] | 58 | import com.android.launcher3.keyboard.ViewGroupFocusHelper; |
Sunny Goyal | 0b0847b | 2018-03-14 12:30:11 -0700 | [diff] [blame] | 59 | import com.android.launcher3.views.BaseDragLayer; |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 60 | import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks; |
Adam Cohen | bc927f9 | 2014-10-28 16:16:02 -0700 | [diff] [blame] | 61 | |
Adam Cohen | 1d9af7d | 2011-06-22 15:26:58 -0700 | [diff] [blame] | 62 | import java.util.ArrayList; |
Adam Cohen | 6788269 | 2011-03-11 15:29:03 -0800 | [diff] [blame] | 63 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 64 | /** |
Michael Jurka | 0e26059 | 2010-06-30 17:07:39 -0700 | [diff] [blame] | 65 | * A ViewGroup that coordinates dragging across its descendants |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 66 | */ |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 67 | public class DragLayer extends BaseDragLayer<Launcher> implements LauncherOverlayCallbacks { |
Sunny Goyal | 0fa93bc | 2015-05-13 11:23:24 -0700 | [diff] [blame] | 68 | |
Sunny Goyal | 6001ea2 | 2018-05-10 16:31:00 -0700 | [diff] [blame] | 69 | public static final int ALPHA_INDEX_OVERLAY = 0; |
Sunny Goyal | 7b8d63f | 2022-04-14 16:37:32 -0700 | [diff] [blame] | 70 | private static final int ALPHA_CHANNEL_COUNT = 1; |
Sunny Goyal | 6001ea2 | 2018-05-10 16:31:00 -0700 | [diff] [blame] | 71 | |
Sunny Goyal | b135956 | 2015-05-19 19:07:29 -0700 | [diff] [blame] | 72 | public static final int ANIMATION_END_DISAPPEAR = 0; |
Sunny Goyal | b135956 | 2015-05-19 19:07:29 -0700 | [diff] [blame] | 73 | public static final int ANIMATION_END_REMAIN_VISIBLE = 2; |
| 74 | |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 75 | private final boolean mIsRtl; |
| 76 | |
Sunny Goyal | deb91c4 | 2020-03-24 02:17:59 -0700 | [diff] [blame] | 77 | private DragController mDragController; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 78 | |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 79 | // Variables relating to animation of views after drop |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 80 | private Animator mDropAnim = null; |
Sunny Goyal | deb91c4 | 2020-03-24 02:17:59 -0700 | [diff] [blame] | 81 | |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 82 | private DragView mDropView = null; |
Adam Cohen | 8dfcba4 | 2011-07-07 16:38:18 -0700 | [diff] [blame] | 83 | |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 84 | private boolean mHoverPointClosesFolder = false; |
Adam Cohen | b0f3d74 | 2013-10-08 19:16:14 -0700 | [diff] [blame] | 85 | |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 86 | private int mTopViewIndex; |
Adam Cohen | 2d783ce | 2014-04-07 14:11:48 -0700 | [diff] [blame] | 87 | private int mChildCountOnLastUpdate = -1; |
Jorim Jaggi | 55bd972 | 2014-01-16 15:30:42 -0800 | [diff] [blame] | 88 | |
Tony Wickham | 0f97b78 | 2015-12-02 17:55:07 -0800 | [diff] [blame] | 89 | // Related to adjacent page hints |
Sunny Goyal | 3333b0c | 2016-05-09 20:43:21 -0700 | [diff] [blame] | 90 | private final ViewGroupFocusHelper mFocusIndicatorHelper; |
Adam Cohen | f7ca3b4 | 2021-02-22 11:03:58 -0800 | [diff] [blame] | 91 | private Scrim mWorkspaceDragScrim; |
Sunny Goyal | 3333b0c | 2016-05-09 20:43:21 -0700 | [diff] [blame] | 92 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 93 | /** |
| 94 | * Used to create a new DragLayer from XML. |
| 95 | * |
| 96 | * @param context The application's context. |
Michael Jurka | 0e26059 | 2010-06-30 17:07:39 -0700 | [diff] [blame] | 97 | * @param attrs The attributes set containing the Workspace's customization values. |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 98 | */ |
| 99 | public DragLayer(Context context, AttributeSet attrs) { |
Sunny Goyal | 6001ea2 | 2018-05-10 16:31:00 -0700 | [diff] [blame] | 100 | super(context, attrs, ALPHA_CHANNEL_COUNT); |
Winson Chung | be62afa | 2011-02-03 23:14:57 -0800 | [diff] [blame] | 101 | |
| 102 | // Disable multitouch across the workspace/all apps/customize tray |
| 103 | setMotionEventSplittingEnabled(false); |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 104 | setChildrenDrawingOrderEnabled(true); |
Winson Chung | 360e63f | 2012-04-27 13:48:05 -0700 | [diff] [blame] | 105 | |
Sunny Goyal | 3333b0c | 2016-05-09 20:43:21 -0700 | [diff] [blame] | 106 | mFocusIndicatorHelper = new ViewGroupFocusHelper(this); |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 107 | mIsRtl = Utilities.isRtl(getResources()); |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 108 | } |
| 109 | |
Shikha Malhotra | f78da1b | 2022-04-11 10:23:18 +0000 | [diff] [blame] | 110 | /** |
| 111 | * Set up the drag layer with the parameters. |
| 112 | */ |
| 113 | public void setup(DragController dragController, Workspace<?> workspace) { |
Hyunyoung Song | 645764e | 2016-06-06 14:19:02 -0700 | [diff] [blame] | 114 | mDragController = dragController; |
Sunny Goyal | 5d1873a | 2018-05-08 11:10:44 -0700 | [diff] [blame] | 115 | recreateControllers(); |
Adam Cohen | f7ca3b4 | 2021-02-22 11:03:58 -0800 | [diff] [blame] | 116 | mWorkspaceDragScrim = new Scrim(this); |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 117 | workspace.addOverlayCallback(this); |
Sunny Goyal | 5d1873a | 2018-05-08 11:10:44 -0700 | [diff] [blame] | 118 | } |
| 119 | |
Sunny Goyal | 4e82f5b | 2020-03-12 12:29:33 -0700 | [diff] [blame] | 120 | @Override |
Sunny Goyal | 5d1873a | 2018-05-08 11:10:44 -0700 | [diff] [blame] | 121 | public void recreateControllers() { |
Sunny Goyal | 210e174 | 2019-10-17 12:05:38 -0700 | [diff] [blame] | 122 | mControllers = mActivity.createTouchControllers(); |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 123 | } |
Adam Cohen | 76fc085 | 2011-06-17 13:26:23 -0700 | [diff] [blame] | 124 | |
Sunny Goyal | 3333b0c | 2016-05-09 20:43:21 -0700 | [diff] [blame] | 125 | public ViewGroupFocusHelper getFocusIndicatorHelper() { |
| 126 | return mFocusIndicatorHelper; |
| 127 | } |
| 128 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 129 | @Override |
| 130 | public boolean dispatchKeyEvent(KeyEvent event) { |
Joe Onorato | 00acb12 | 2009-08-04 16:04:30 -0400 | [diff] [blame] | 131 | return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 132 | } |
| 133 | |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 134 | private boolean isEventOverAccessibleDropTargetBar(MotionEvent ev) { |
| 135 | return isInAccessibleDrag() && isEventOverView(mActivity.getDropTargetBar(), ev); |
| 136 | } |
| 137 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 138 | @Override |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 139 | public boolean onInterceptHoverEvent(MotionEvent ev) { |
Sunny Goyal | 0b0847b | 2018-03-14 12:30:11 -0700 | [diff] [blame] | 140 | if (mActivity == null || mActivity.getWorkspace() == null) { |
Michael Jurka | 023c71e | 2012-10-19 17:32:24 +0200 | [diff] [blame] | 141 | return false; |
| 142 | } |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 143 | AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); |
| 144 | if (!(topView instanceof Folder)) { |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 145 | return false; |
| 146 | } else { |
Sunny Goyal | 0b0847b | 2018-03-14 12:30:11 -0700 | [diff] [blame] | 147 | AccessibilityManager accessibilityManager = (AccessibilityManager) |
| 148 | getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); |
Michael Jurka | 8b805b1 | 2012-04-18 14:23:14 -0700 | [diff] [blame] | 149 | if (accessibilityManager.isTouchExplorationEnabled()) { |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 150 | Folder currentFolder = (Folder) topView; |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 151 | final int action = ev.getAction(); |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 152 | boolean isOverFolderOrSearchBar; |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 153 | switch (action) { |
| 154 | case MotionEvent.ACTION_HOVER_ENTER: |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 155 | isOverFolderOrSearchBar = isEventOverView(topView, ev) || |
| 156 | isEventOverAccessibleDropTargetBar(ev); |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 157 | if (!isOverFolderOrSearchBar) { |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 158 | sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); |
| 159 | mHoverPointClosesFolder = true; |
| 160 | return true; |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 161 | } |
Mihail Dumitrescu | 693fbc7 | 2014-01-03 12:40:22 +0000 | [diff] [blame] | 162 | mHoverPointClosesFolder = false; |
| 163 | break; |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 164 | case MotionEvent.ACTION_HOVER_MOVE: |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 165 | isOverFolderOrSearchBar = isEventOverView(topView, ev) || |
| 166 | isEventOverAccessibleDropTargetBar(ev); |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 167 | if (!isOverFolderOrSearchBar && !mHoverPointClosesFolder) { |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 168 | sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); |
| 169 | mHoverPointClosesFolder = true; |
| 170 | return true; |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 171 | } else if (!isOverFolderOrSearchBar) { |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 172 | return true; |
| 173 | } |
Mihail Dumitrescu | 693fbc7 | 2014-01-03 12:40:22 +0000 | [diff] [blame] | 174 | mHoverPointClosesFolder = false; |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 175 | } |
| 176 | } |
| 177 | } |
| 178 | return false; |
| 179 | } |
| 180 | |
| 181 | private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) { |
Sunny Goyal | 52851aa | 2016-09-02 10:41:43 -0700 | [diff] [blame] | 182 | int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close; |
Sunny Goyal | d0030b0 | 2017-12-08 15:07:24 -0800 | [diff] [blame] | 183 | sendCustomAccessibilityEvent( |
Sunny Goyal | 52851aa | 2016-09-02 10:41:43 -0700 | [diff] [blame] | 184 | this, AccessibilityEvent.TYPE_VIEW_FOCUSED, getContext().getString(stringId)); |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 185 | } |
| 186 | |
Sunny Goyal | 0b0847b | 2018-03-14 12:30:11 -0700 | [diff] [blame] | 187 | @Override |
| 188 | public boolean onHoverEvent(MotionEvent ev) { |
| 189 | // If we've received this, we've already done the necessary handling |
| 190 | // in onInterceptHoverEvent. Return true to consume the event. |
| 191 | return false; |
| 192 | } |
| 193 | |
| 194 | |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 195 | private boolean isInAccessibleDrag() { |
Sunny Goyal | 0b0847b | 2018-03-14 12:30:11 -0700 | [diff] [blame] | 196 | return mActivity.getAccessibilityDelegate().isInAccessibleDrag(); |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 197 | } |
| 198 | |
Adam Cohen | 3371da0 | 2011-10-25 21:38:29 -0700 | [diff] [blame] | 199 | @Override |
Winson Chung | 83ca480 | 2013-04-12 15:10:52 -0700 | [diff] [blame] | 200 | public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 201 | if (isInAccessibleDrag() && child instanceof DropTargetBar) { |
| 202 | return true; |
Winson Chung | 83ca480 | 2013-04-12 15:10:52 -0700 | [diff] [blame] | 203 | } |
| 204 | return super.onRequestSendAccessibilityEvent(child, event); |
| 205 | } |
| 206 | |
| 207 | @Override |
| 208 | public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) { |
Vadim Tryshev | 17839d5 | 2018-05-23 14:45:56 -0700 | [diff] [blame] | 209 | View topView = AbstractFloatingView.getTopOpenViewWithType(mActivity, |
| 210 | AbstractFloatingView.TYPE_ACCESSIBLE); |
Sunny Goyal | 52851aa | 2016-09-02 10:41:43 -0700 | [diff] [blame] | 211 | if (topView != null) { |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 212 | addAccessibleChildToList(topView, childrenForAccessibility); |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 213 | if (isInAccessibleDrag()) { |
Sunny Goyal | de75321 | 2018-05-15 13:55:57 -0700 | [diff] [blame] | 214 | addAccessibleChildToList(mActivity.getDropTargetBar(), childrenForAccessibility); |
Sunny Goyal | ccc414b | 2015-04-30 12:28:16 -0700 | [diff] [blame] | 215 | } |
Winson Chung | 83ca480 | 2013-04-12 15:10:52 -0700 | [diff] [blame] | 216 | } else { |
| 217 | super.addChildrenForAccessibility(childrenForAccessibility); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | @Override |
Sunny Goyal | 19d32b7 | 2018-01-19 14:26:18 -0800 | [diff] [blame] | 222 | public boolean dispatchTouchEvent(MotionEvent ev) { |
| 223 | ev.offsetLocation(getTranslationX(), 0); |
| 224 | try { |
| 225 | return super.dispatchTouchEvent(ev); |
| 226 | } finally { |
| 227 | ev.offsetLocation(-getTranslationX(), 0); |
| 228 | } |
| 229 | } |
| 230 | |
Winson Chung | 7bd1bbb | 2012-02-13 18:29:29 -0800 | [diff] [blame] | 231 | public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha, |
| 232 | float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable, |
| 233 | int duration) { |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 234 | animateViewIntoPosition(dragView, pos[0], pos[1], alpha, scaleX, scaleY, |
Adam Cohen | ed66b2b | 2012-01-23 17:28:51 -0800 | [diff] [blame] | 235 | onFinishRunnable, animationEndStyle, duration, null); |
| 236 | } |
| 237 | |
Sunny Goyal | 1797af4 | 2017-10-06 13:29:57 -0700 | [diff] [blame] | 238 | public void animateViewIntoPosition(DragView dragView, final View child, View anchorView) { |
| 239 | animateViewIntoPosition(dragView, child, -1, anchorView); |
Adam Cohen | ed51cc9 | 2011-08-01 20:28:08 -0700 | [diff] [blame] | 240 | } |
| 241 | |
| 242 | public void animateViewIntoPosition(DragView dragView, final View child, int duration, |
Sunny Goyal | 1797af4 | 2017-10-06 13:29:57 -0700 | [diff] [blame] | 243 | View anchorView) { |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 244 | |
Michael Jurka | a52570f | 2012-03-20 03:18:20 -0700 | [diff] [blame] | 245 | ShortcutAndWidgetContainer parentChildren = (ShortcutAndWidgetContainer) child.getParent(); |
Sebastian Franco | d468299 | 2022-10-05 13:03:09 -0500 | [diff] [blame] | 246 | CellLayoutLayoutParams lp = (CellLayoutLayoutParams) child.getLayoutParams(); |
Winson Chung | eecf02d | 2012-03-02 17:14:58 -0800 | [diff] [blame] | 247 | parentChildren.measureChild(child); |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 248 | parentChildren.layoutChild(child); |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 249 | |
Sunny Goyal | ae6e318 | 2019-04-30 12:04:37 -0700 | [diff] [blame] | 250 | float coord[] = new float[2]; |
Adam Cohen | 307fe23 | 2012-08-16 17:55:58 -0700 | [diff] [blame] | 251 | float childScale = child.getScaleX(); |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 252 | |
Sunny Goyal | ae6e318 | 2019-04-30 12:04:37 -0700 | [diff] [blame] | 253 | coord[0] = lp.x + (child.getMeasuredWidth() * (1 - childScale) / 2); |
| 254 | coord[1] = lp.y + (child.getMeasuredHeight() * (1 - childScale) / 2); |
Winson Chung | eecf02d | 2012-03-02 17:14:58 -0800 | [diff] [blame] | 255 | |
Adam Cohen | 8dfcba4 | 2011-07-07 16:38:18 -0700 | [diff] [blame] | 256 | // Since the child hasn't necessarily been laid out, we force the lp to be updated with |
Adam Cohen | ac8c876 | 2011-07-13 11:15:27 -0700 | [diff] [blame] | 257 | // the correct coordinates (above) and use these to determine the final location |
Winson Chung | 557d6ed | 2011-07-08 15:34:52 -0700 | [diff] [blame] | 258 | float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord); |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 259 | |
Adam Cohen | 307fe23 | 2012-08-16 17:55:58 -0700 | [diff] [blame] | 260 | // We need to account for the scale of the child itself, as the above only accounts for |
| 261 | // for the scale in parents. |
| 262 | scale *= childScale; |
Sunny Goyal | ae6e318 | 2019-04-30 12:04:37 -0700 | [diff] [blame] | 263 | int toX = Math.round(coord[0]); |
| 264 | int toY = Math.round(coord[1]); |
Adam Cohen | c77bc45 | 2020-05-07 11:55:19 -0700 | [diff] [blame] | 265 | |
Winson Chung | eeb5bbc | 2013-11-13 15:47:05 -0800 | [diff] [blame] | 266 | float toScale = scale; |
Andrew Flynn | 4497ebf | 2012-05-09 11:28:00 -0700 | [diff] [blame] | 267 | |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 268 | if (child instanceof DraggableView) { |
Adam Cohen | c77bc45 | 2020-05-07 11:55:19 -0700 | [diff] [blame] | 269 | // This code is fairly subtle. Please verify drag and drop is pixel-perfect in a number |
| 270 | // of scenarios before modifying (from all apps, from workspace, different grid-sizes, |
| 271 | // shortcuts from in and out of Launcher etc). |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 272 | DraggableView d = (DraggableView) child; |
Adam Cohen | c77bc45 | 2020-05-07 11:55:19 -0700 | [diff] [blame] | 273 | Rect destRect = new Rect(); |
| 274 | d.getWorkspaceVisualDragBounds(destRect); |
| 275 | |
| 276 | // In most cases this additional scale factor should be a no-op (1). It mainly accounts |
| 277 | // for alternate grids where the source and destination icon sizes are different |
| 278 | toScale *= ((1f * destRect.width()) |
| 279 | / (dragView.getMeasuredWidth() - dragView.getBlurSizeOutline())); |
Sunny Goyal | 95abbb3 | 2014-08-04 10:53:22 -0700 | [diff] [blame] | 280 | |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 281 | // This accounts for the offset of the DragView created by scaling it about its |
| 282 | // center as it animates into place. |
Adam Cohen | c77bc45 | 2020-05-07 11:55:19 -0700 | [diff] [blame] | 283 | float scaleShiftX = dragView.getMeasuredWidth() * (1 - toScale) / 2; |
| 284 | float scaleShiftY = dragView.getMeasuredHeight() * (1 - toScale) / 2; |
Adam Cohen | 6508699 | 2020-02-19 08:40:49 -0800 | [diff] [blame] | 285 | |
Adam Cohen | c77bc45 | 2020-05-07 11:55:19 -0700 | [diff] [blame] | 286 | toX += scale * destRect.left - toScale * dragView.getBlurSizeOutline() / 2 - scaleShiftX; |
| 287 | toY += scale * destRect.top - toScale * dragView.getBlurSizeOutline() / 2 - scaleShiftY; |
Adam Cohen | ac8c876 | 2011-07-13 11:15:27 -0700 | [diff] [blame] | 288 | } |
| 289 | |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 290 | child.setVisibility(INVISIBLE); |
Sunny Goyal | 6639a5d | 2018-02-28 15:09:36 -0800 | [diff] [blame] | 291 | Runnable onCompleteRunnable = () -> child.setVisibility(VISIBLE); |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 292 | animateViewIntoPosition(dragView, toX, toY, 1, toScale, toScale, |
Adam Cohen | d41fbf5 | 2012-02-16 23:53:59 -0800 | [diff] [blame] | 293 | onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView); |
Winson Chung | 557d6ed | 2011-07-08 15:34:52 -0700 | [diff] [blame] | 294 | } |
| 295 | |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 296 | /** |
| 297 | * This method animates a view at the end of a drag and drop animation. |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 298 | */ |
| 299 | public void animateViewIntoPosition(final DragView view, |
| 300 | final int toX, final int toY, float finalAlpha, |
| 301 | float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, |
| 302 | int animationEndStyle, int duration, View anchorView) { |
| 303 | Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); |
| 304 | animateView(view, to, finalAlpha, finalScaleX, finalScaleY, duration, |
| 305 | null, onCompleteRunnable, animationEndStyle, anchorView); |
| 306 | } |
| 307 | |
| 308 | /** |
| 309 | * This method animates a view at the end of a drag and drop animation. |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 310 | * @param view The view to be animated. This view is drawn directly into DragLayer, and so |
| 311 | * doesn't need to be a child of DragLayer. |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 312 | * @param to The final location of the view. Only the left and top parameters are used. This |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 313 | * location doesn't account for scaling, and so should be centered about the desired |
| 314 | * final location (including scaling). |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 315 | * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. |
Sunny Goyal | 6178f13 | 2016-07-11 17:30:03 -0700 | [diff] [blame] | 316 | * @param finalScaleX The final scale of the view. The view is scaled about its center. |
| 317 | * @param finalScaleY The final scale of the view. The view is scaled about its center. |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 318 | * @param duration The duration of the animation. |
| 319 | * @param motionInterpolator The interpolator to use for the location of the view. |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 320 | * @param onCompleteRunnable Optional runnable to run on animation completion. |
Sunny Goyal | 6178f13 | 2016-07-11 17:30:03 -0700 | [diff] [blame] | 321 | * @param animationEndStyle Whether or not to fade out the view once the animation completes. |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 322 | * {@link #ANIMATION_END_DISAPPEAR} or {@link #ANIMATION_END_REMAIN_VISIBLE}. |
Adam Cohen | 6441de0 | 2011-12-14 14:25:32 -0800 | [diff] [blame] | 323 | * @param anchorView If not null, this represents the view which the animated view stays |
Adam Cohen | b7e1618 | 2011-07-15 17:55:02 -0700 | [diff] [blame] | 324 | */ |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 325 | public void animateView(final DragView view, final Rect to, |
| 326 | final float finalAlpha, final float finalScaleX, final float finalScaleY, int duration, |
| 327 | final Interpolator motionInterpolator, final Runnable onCompleteRunnable, |
| 328 | final int animationEndStyle, View anchorView) { |
| 329 | view.cancelAnimation(); |
| 330 | view.requestLayout(); |
| 331 | |
| 332 | final int[] from = getViewLocationRelativeToSelf(view); |
Winson Chung | 7bd1bbb | 2012-02-13 18:29:29 -0800 | [diff] [blame] | 333 | |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 334 | // Calculate the duration of the animation based on the object's distance |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 335 | final float dist = (float) Math.hypot(to.left - from[0], to.top - from[1]); |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 336 | final Resources res = getResources(); |
| 337 | final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); |
Adam Cohen | 3e8f811 | 2011-07-02 18:03:00 -0700 | [diff] [blame] | 338 | |
| 339 | // If duration < 0, this is a cue to compute the duration based on the distance |
| 340 | if (duration < 0) { |
Sunny Goyal | dec3a90 | 2017-01-25 18:23:36 -0800 | [diff] [blame] | 341 | duration = res.getInteger(R.integer.config_dropAnimMaxDuration); |
| 342 | if (dist < maxDist) { |
Kateryna Ivanova | 7120373 | 2023-05-24 15:09:00 +0000 | [diff] [blame] | 343 | duration *= DECELERATE_1_5.getInterpolation(dist / maxDist); |
Adam Cohen | 3e8f811 | 2011-07-02 18:03:00 -0700 | [diff] [blame] | 344 | } |
Sunny Goyal | dec3a90 | 2017-01-25 18:23:36 -0800 | [diff] [blame] | 345 | duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration)); |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 346 | } |
| 347 | |
Winson Chung | 043f2af | 2012-03-01 16:09:54 -0800 | [diff] [blame] | 348 | // Fall back to cubic ease out interpolator for the animation if none is specified |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 349 | TimeInterpolator interpolator = |
Kateryna Ivanova | 7120373 | 2023-05-24 15:09:00 +0000 | [diff] [blame] | 350 | motionInterpolator == null ? DECELERATE_1_5 : motionInterpolator; |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 351 | |
Winson Chung | 043f2af | 2012-03-01 16:09:54 -0800 | [diff] [blame] | 352 | // Animate the view |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 353 | PendingAnimation anim = new PendingAnimation(duration); |
| 354 | anim.add(ofFloat(view, View.SCALE_X, finalScaleX), interpolator, SpringProperty.DEFAULT); |
| 355 | anim.add(ofFloat(view, View.SCALE_Y, finalScaleY), interpolator, SpringProperty.DEFAULT); |
| 356 | anim.setViewAlpha(view, finalAlpha, interpolator); |
| 357 | anim.setFloat(view, VIEW_TRANSLATE_Y, to.top, interpolator); |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 358 | |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 359 | ObjectAnimator xMotion = ofFloat(view, VIEW_TRANSLATE_X, to.left); |
| 360 | if (anchorView != null) { |
| 361 | final int startScroll = anchorView.getScrollX(); |
| 362 | TypeEvaluator<Float> evaluator = (f, s, e) -> mapRange(f, s, e) |
| 363 | + (anchorView.getScaleX() * (startScroll - anchorView.getScrollX())); |
| 364 | xMotion.setEvaluator(evaluator); |
| 365 | } |
| 366 | anim.add(xMotion, interpolator, SpringProperty.DEFAULT); |
| 367 | if (onCompleteRunnable != null) { |
| 368 | anim.addListener(forEndCallback(onCompleteRunnable)); |
| 369 | } |
| 370 | playDropAnimation(view, anim.buildAnim(), animationEndStyle); |
Winson Chung | 043f2af | 2012-03-01 16:09:54 -0800 | [diff] [blame] | 371 | } |
| 372 | |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 373 | /** |
| 374 | * Runs a previously constructed drop animation |
| 375 | */ |
| 376 | public void playDropAnimation(final DragView view, Animator animator, int animationEndStyle) { |
Winson Chung | 043f2af | 2012-03-01 16:09:54 -0800 | [diff] [blame] | 377 | // Clean up the previous animations |
| 378 | if (mDropAnim != null) mDropAnim.cancel(); |
Winson Chung | 043f2af | 2012-03-01 16:09:54 -0800 | [diff] [blame] | 379 | |
| 380 | // Show the drop view if it was previously hidden |
| 381 | mDropView = view; |
Winson Chung | 043f2af | 2012-03-01 16:09:54 -0800 | [diff] [blame] | 382 | // Create and start the animation |
Sunny Goyal | 1721ccf | 2021-06-08 12:57:40 -0700 | [diff] [blame] | 383 | mDropAnim = animator; |
| 384 | mDropAnim.addListener(forEndCallback(() -> mDropAnim = null)); |
| 385 | if (animationEndStyle == ANIMATION_END_DISAPPEAR) { |
| 386 | mDropAnim.addListener(forEndCallback(this::clearAnimatedView)); |
| 387 | } |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 388 | mDropAnim.start(); |
| 389 | } |
| 390 | |
Adam Cohen | ed66b2b | 2012-01-23 17:28:51 -0800 | [diff] [blame] | 391 | public void clearAnimatedView() { |
Winson Chung | 7bd1bbb | 2012-02-13 18:29:29 -0800 | [diff] [blame] | 392 | if (mDropAnim != null) { |
| 393 | mDropAnim.cancel(); |
| 394 | } |
Winson Chung | 7dd3b52 | 2018-05-14 10:07:15 -0700 | [diff] [blame] | 395 | mDropAnim = null; |
Winson Chung | 7bd1bbb | 2012-02-13 18:29:29 -0800 | [diff] [blame] | 396 | if (mDropView != null) { |
Adam Cohen | 2d783ce | 2014-04-07 14:11:48 -0700 | [diff] [blame] | 397 | mDragController.onDeferredEndDrag(mDropView); |
Winson Chung | 7bd1bbb | 2012-02-13 18:29:29 -0800 | [diff] [blame] | 398 | } |
Adam Cohen | ed66b2b | 2012-01-23 17:28:51 -0800 | [diff] [blame] | 399 | mDropView = null; |
Adam Cohen | ed66b2b | 2012-01-23 17:28:51 -0800 | [diff] [blame] | 400 | invalidate(); |
| 401 | } |
| 402 | |
| 403 | public View getAnimatedView() { |
| 404 | return mDropView; |
| 405 | } |
| 406 | |
Adam Cohen | 716b51e | 2011-06-30 12:09:54 -0700 | [diff] [blame] | 407 | @Override |
Jon Miranda | 758d504 | 2017-11-08 14:38:23 -0800 | [diff] [blame] | 408 | public void onViewAdded(View child) { |
| 409 | super.onViewAdded(child); |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 410 | updateChildIndices(); |
Sunny Goyal | 210e174 | 2019-10-17 12:05:38 -0700 | [diff] [blame] | 411 | mActivity.onDragLayerHierarchyChanged(); |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 412 | } |
| 413 | |
| 414 | @Override |
Jon Miranda | 758d504 | 2017-11-08 14:38:23 -0800 | [diff] [blame] | 415 | public void onViewRemoved(View child) { |
| 416 | super.onViewRemoved(child); |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 417 | updateChildIndices(); |
Sunny Goyal | 210e174 | 2019-10-17 12:05:38 -0700 | [diff] [blame] | 418 | mActivity.onDragLayerHierarchyChanged(); |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 419 | } |
| 420 | |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 421 | @Override |
| 422 | public void bringChildToFront(View child) { |
| 423 | super.bringChildToFront(child); |
| 424 | updateChildIndices(); |
| 425 | } |
| 426 | |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 427 | private void updateChildIndices() { |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 428 | mTopViewIndex = -1; |
Jorim Jaggi | 55bd972 | 2014-01-16 15:30:42 -0800 | [diff] [blame] | 429 | int childCount = getChildCount(); |
| 430 | for (int i = 0; i < childCount; i++) { |
Adam Cohen | b670f19 | 2014-04-08 15:34:17 -0700 | [diff] [blame] | 431 | if (getChildAt(i) instanceof DragView) { |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 432 | mTopViewIndex = i; |
Jorim Jaggi | 55bd972 | 2014-01-16 15:30:42 -0800 | [diff] [blame] | 433 | } |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 434 | } |
Adam Cohen | 2d783ce | 2014-04-07 14:11:48 -0700 | [diff] [blame] | 435 | mChildCountOnLastUpdate = childCount; |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 436 | } |
| 437 | |
| 438 | @Override |
| 439 | protected int getChildDrawingOrder(int childCount, int i) { |
Adam Cohen | 2d783ce | 2014-04-07 14:11:48 -0700 | [diff] [blame] | 440 | if (mChildCountOnLastUpdate != childCount) { |
| 441 | // between platform versions 17 and 18, behavior for onChildViewRemoved / Added changed. |
| 442 | // Pre-18, the child was not added / removed by the time of those callbacks. We need to |
| 443 | // force update our representation of things here to avoid crashing on pre-18 devices |
| 444 | // in certain instances. |
| 445 | updateChildIndices(); |
| 446 | } |
| 447 | |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 448 | // i represents the current draw iteration |
| 449 | if (mTopViewIndex == -1) { |
| 450 | // in general we do nothing |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 451 | return i; |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 452 | } else if (i == childCount - 1) { |
| 453 | // if we have a top index, we return it when drawing last item (highest z-order) |
| 454 | return mTopViewIndex; |
| 455 | } else if (i < mTopViewIndex) { |
Jorim Jaggi | 55bd972 | 2014-01-16 15:30:42 -0800 | [diff] [blame] | 456 | return i; |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 457 | } else { |
Adam Cohen | 432609a | 2014-03-13 17:03:22 -0700 | [diff] [blame] | 458 | // for indexes greater than the top index, we fetch one item above to shift for the |
| 459 | // displacement of the top index |
| 460 | return i + 1; |
Adam Cohen | 21b4110 | 2011-11-01 17:29:52 -0700 | [diff] [blame] | 461 | } |
| 462 | } |
Winson Chung | 360e63f | 2012-04-27 13:48:05 -0700 | [diff] [blame] | 463 | |
Winson Chung | 360e63f | 2012-04-27 13:48:05 -0700 | [diff] [blame] | 464 | @Override |
| 465 | protected void dispatchDraw(Canvas canvas) { |
Sunny Goyal | 0fa93bc | 2015-05-13 11:23:24 -0700 | [diff] [blame] | 466 | // Draw the background below children. |
Adam Cohen | 501e139 | 2021-02-02 16:45:07 -0800 | [diff] [blame] | 467 | mWorkspaceDragScrim.draw(canvas); |
Sunny Goyal | 3333b0c | 2016-05-09 20:43:21 -0700 | [diff] [blame] | 468 | mFocusIndicatorHelper.draw(canvas); |
Winson Chung | 360e63f | 2012-04-27 13:48:05 -0700 | [diff] [blame] | 469 | super.dispatchDraw(canvas); |
Tony Wickham | c088051 | 2019-07-24 17:32:08 -0700 | [diff] [blame] | 470 | } |
| 471 | |
Adam Cohen | f7ca3b4 | 2021-02-22 11:03:58 -0800 | [diff] [blame] | 472 | public Scrim getWorkspaceDragScrim() { |
Adam Cohen | 501e139 | 2021-02-02 16:45:07 -0800 | [diff] [blame] | 473 | return mWorkspaceDragScrim; |
| 474 | } |
Bill Lin | 945bb34 | 2021-06-03 01:29:39 +0800 | [diff] [blame] | 475 | |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 476 | @Override |
| 477 | public void onOverlayScrollChanged(float progress) { |
Kateryna Ivanova | 7120373 | 2023-05-24 15:09:00 +0000 | [diff] [blame] | 478 | float alpha = 1 - Interpolators.DECELERATE_3.getInterpolation(progress); |
Sunny Goyal | 8237918 | 2022-11-02 18:58:49 -0700 | [diff] [blame] | 479 | float transX = getMeasuredWidth() * progress; |
| 480 | |
| 481 | if (mIsRtl) { |
| 482 | transX = -transX; |
| 483 | } |
| 484 | setTranslationX(transX); |
| 485 | getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha); |
| 486 | } |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 487 | } |