1ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi/* 2ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Copyright (C) 2014 The Android Open Source Project 3ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 4ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * you may not use this file except in compliance with the License. 6ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * You may obtain a copy of the License at 7ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 8ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 10ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Unless required by applicable law or agreed to in writing, software 11ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * See the License for the specific language governing permissions and 14ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * limitations under the License 15ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi */ 16ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 17ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggipackage com.android.systemui.statusbar; 18ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 194222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggiimport android.animation.Animator; 204222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggiimport android.animation.AnimatorListenerAdapter; 214222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggiimport android.animation.ObjectAnimator; 2248bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggiimport android.animation.ValueAnimator; 23ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.content.Context; 24ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.view.MotionEvent; 25ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.view.View; 26ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.view.ViewConfiguration; 27c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek 28ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport com.android.systemui.ExpandHelper; 29ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport com.android.systemui.Gefingerpoken; 30c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.Interpolators; 31ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport com.android.systemui.R; 320e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport com.android.systemui.classifier.FalsingManager; 33ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 34ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi/** 35ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand 36ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * the notification where the drag started. 37ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi */ 38ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggipublic class DragDownHelper implements Gefingerpoken { 39ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 404222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private static final float RUBBERBAND_FACTOR_EXPANDABLE = 0.5f; 414222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private static final float RUBBERBAND_FACTOR_STATIC = 0.15f; 424222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi 434222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private static final int SPRING_BACK_ANIMATION_LENGTH_MS = 375; 444222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi 45ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private int mMinDragDistance; 46ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private ExpandHelper.Callback mCallback; 47ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private float mInitialTouchX; 48ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private float mInitialTouchY; 49ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private boolean mDraggingDown; 50ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private float mTouchSlop; 5148bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi private DragDownCallback mDragDownCallback; 52ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private View mHost; 53ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private final int[] mTemp2 = new int[2]; 54ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private boolean mDraggedFarEnough; 554222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private ExpandableView mStartingChild; 5648bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi private float mLastHeight; 570e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private FalsingManager mFalsingManager; 58ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 59ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public DragDownHelper(Context context, View host, ExpandHelper.Callback callback, 6048bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi DragDownCallback dragDownCallback) { 61ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mMinDragDistance = context.getResources().getDimensionPixelSize( 62ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi R.dimen.keyguard_drag_down_min_distance); 63ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 64ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mCallback = callback; 6548bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mDragDownCallback = dragDownCallback; 66ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mHost = host; 670e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mFalsingManager = FalsingManager.getInstance(context); 68ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 69ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 70ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi @Override 71ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public boolean onInterceptTouchEvent(MotionEvent event) { 72ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float x = event.getX(); 73ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float y = event.getY(); 74ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 75ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi switch (event.getActionMasked()) { 76ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_DOWN: 77ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggedFarEnough = false; 78ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggingDown = false; 79ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mStartingChild = null; 80ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchY = y; 81ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchX = x; 82ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi break; 83ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 84ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_MOVE: 85ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float h = y - mInitialTouchY; 86ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) { 870e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mFalsingManager.onNotificatonStartDraggingDown(); 88ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggingDown = true; 894222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi captureStartingChild(mInitialTouchX, mInitialTouchY); 90ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchY = y; 91ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchX = x; 9248bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mDragDownCallback.onTouchSlopExceeded(); 93ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return true; 94ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 95ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi break; 96ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 97ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 98ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 99ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 100ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi @Override 101ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public boolean onTouchEvent(MotionEvent event) { 102ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (!mDraggingDown) { 103ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 104ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 105ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float x = event.getX(); 106ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float y = event.getY(); 107ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 108ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi switch (event.getActionMasked()) { 109ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_MOVE: 11048bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mLastHeight = y - mInitialTouchY; 1114222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi captureStartingChild(mInitialTouchX, mInitialTouchY); 1124222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi if (mStartingChild != null) { 11348bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi handleExpansion(mLastHeight, mStartingChild); 11448bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi } else { 11548bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mDragDownCallback.setEmptyDragAmount(mLastHeight); 116ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 11748bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi if (mLastHeight > mMinDragDistance) { 118ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (!mDraggedFarEnough) { 119ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggedFarEnough = true; 120177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek mDragDownCallback.onCrossedThreshold(true); 121ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 122ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } else { 123ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (mDraggedFarEnough) { 124ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggedFarEnough = false; 125177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek mDragDownCallback.onCrossedThreshold(false); 126ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 127ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 128ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return true; 129ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_UP: 1306dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski if (!isFalseTouch() && mDragDownCallback.onDraggedDown(mStartingChild, 131b018399a3a2762e95126acbe14397eca15bad772Christoph Studer (int) (y - mInitialTouchY))) { 132dbc3dce886cb7abba23a9f18e60d0f5af5c93226Jorim Jaggi if (mStartingChild == null) { 13348bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mDragDownCallback.setEmptyDragAmount(0f); 1345243c12f49fbe0ab8fe6b3b2be368783cd2b2a7bSelim Cinek } else { 1355243c12f49fbe0ab8fe6b3b2be368783cd2b2a7bSelim Cinek mCallback.setUserLockedChild(mStartingChild, false); 136f306d9b498c2c81ad52083a0825e037f2757daf7Selim Cinek mStartingChild = null; 1374222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 13898fb09c2b2dbf57803a8737ee7b73cf167721312Jorim Jaggi mDraggingDown = false; 139ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } else { 140ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi stopDragging(); 141ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 142ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 143ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi break; 144ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_CANCEL: 145ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi stopDragging(); 146ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 147ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 148ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 149ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 150ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 1516dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski private boolean isFalseTouch() { 15252af6b646bd3abc8223ed01a36f6da785b35085dBlazej Magnowski return mFalsingManager.isFalseTouch() || !mDraggedFarEnough; 1536dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski } 1546dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski 1554222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private void captureStartingChild(float x, float y) { 1564222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi if (mStartingChild == null) { 1574222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi mStartingChild = findView(x, y); 1584222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi if (mStartingChild != null) { 1594222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi mCallback.setUserLockedChild(mStartingChild, true); 1604222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 1614222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 162ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 163ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 1644222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private void handleExpansion(float heightDelta, ExpandableView child) { 1654222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi if (heightDelta < 0) { 1664222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi heightDelta = 0; 167ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 1684222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi boolean expandable = child.isContentExpandable(); 1694222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi float rubberbandFactor = expandable 1704222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi ? RUBBERBAND_FACTOR_EXPANDABLE 1714222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi : RUBBERBAND_FACTOR_STATIC; 1724222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi float rubberband = heightDelta * rubberbandFactor; 1732c58461daf909fae5a2605f0ba63da3f9c897731Selim Cinek if (expandable 174567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek && (rubberband + child.getCollapsedHeight()) > child.getMaxContentHeight()) { 1752c58461daf909fae5a2605f0ba63da3f9c897731Selim Cinek float overshoot = 176567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek (rubberband + child.getCollapsedHeight()) - child.getMaxContentHeight(); 1774222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi overshoot *= (1 - RUBBERBAND_FACTOR_STATIC); 1784222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi rubberband -= overshoot; 179ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 180567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek child.setActualHeight((int) (child.getCollapsedHeight() + rubberband)); 1814222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 1824222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi 1834222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private void cancelExpansion(final ExpandableView child) { 184567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek if (child.getActualHeight() == child.getCollapsedHeight()) { 1855243c12f49fbe0ab8fe6b3b2be368783cd2b2a7bSelim Cinek mCallback.setUserLockedChild(child, false); 1864222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi return; 1874222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 188eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek ObjectAnimator anim = ObjectAnimator.ofInt(child, "actualHeight", 189567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek child.getActualHeight(), child.getCollapsedHeight()); 190c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); 1914222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS); 1924222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi anim.addListener(new AnimatorListenerAdapter() { 1934222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi @Override 1944222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi public void onAnimationEnd(Animator animation) { 1954222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi mCallback.setUserLockedChild(child, false); 1964222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 1974222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi }); 1984222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi anim.start(); 1994222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 2004222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi 20148bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi private void cancelExpansion() { 20248bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0); 203c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); 20448bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS); 20548bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 20648bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi @Override 20748bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi public void onAnimationUpdate(ValueAnimator animation) { 20848bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue()); 20948bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi } 21048bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi }); 21148bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi anim.start(); 21248bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi } 21348bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi 2144222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private void stopDragging() { 2150e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mFalsingManager.onNotificatonStopDraggingDown(); 2164222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi if (mStartingChild != null) { 2174222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi cancelExpansion(mStartingChild); 218f306d9b498c2c81ad52083a0825e037f2757daf7Selim Cinek mStartingChild = null; 21948bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi } else { 22048bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi cancelExpansion(); 2214222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi } 2224222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi mDraggingDown = false; 22348bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi mDragDownCallback.onDragDownReset(); 224ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 225ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 2264222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi private ExpandableView findView(float x, float y) { 227ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mHost.getLocationOnScreen(mTemp2); 228ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi x += mTemp2[0]; 229ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi y += mTemp2[1]; 230ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return mCallback.getChildAtRawPosition(x, y); 231ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 232ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 233740c1114764e341857d32b486d3b1ad985033a3bSelim Cinek public boolean isDraggingDown() { 234740c1114764e341857d32b486d3b1ad985033a3bSelim Cinek return mDraggingDown; 235740c1114764e341857d32b486d3b1ad985033a3bSelim Cinek } 236740c1114764e341857d32b486d3b1ad985033a3bSelim Cinek 23748bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi public interface DragDownCallback { 23848bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi 23948bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi /** 24048bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi * @return true if the interaction is accepted, false if it should be cancelled 24148bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi */ 242b018399a3a2762e95126acbe14397eca15bad772Christoph Studer boolean onDraggedDown(View startingChild, int dragLengthY); 243d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi void onDragDownReset(); 244177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek 245177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek /** 246177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek * The user has dragged either above or below the threshold 247177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek * @param above whether he dragged above it 248177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek */ 249177fd4324ab89dc138b3d4c7472623ae9dc8c9d8Selim Cinek void onCrossedThreshold(boolean above); 2501408eb5a58d669933c701e347fd3498ceab70f3cSelim Cinek void onTouchSlopExceeded(); 25148bc36af053885daf091bcca6d99411e0438ba83Jorim Jaggi void setEmptyDragAmount(float amount); 252ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 253ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi} 254