OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.widget; | 5 package org.chromium.chrome.browser.widget.bottomsheet; |
6 | 6 |
7 import android.animation.Animator; | 7 import android.animation.Animator; |
8 import android.animation.AnimatorListenerAdapter; | 8 import android.animation.AnimatorListenerAdapter; |
9 import android.animation.ValueAnimator; | 9 import android.animation.ValueAnimator; |
10 import android.content.Context; | 10 import android.content.Context; |
11 import android.graphics.Region; | 11 import android.graphics.Region; |
12 import android.support.annotation.IntDef; | 12 import android.support.annotation.IntDef; |
13 import android.support.annotation.Nullable; | 13 import android.support.annotation.Nullable; |
14 import android.util.AttributeSet; | 14 import android.util.AttributeSet; |
15 import android.view.GestureDetector; | 15 import android.view.GestureDetector; |
16 import android.view.MotionEvent; | 16 import android.view.MotionEvent; |
17 import android.view.VelocityTracker; | 17 import android.view.VelocityTracker; |
18 import android.view.View; | 18 import android.view.View; |
19 import android.view.animation.DecelerateInterpolator; | 19 import android.view.animation.DecelerateInterpolator; |
20 import android.view.animation.Interpolator; | 20 import android.view.animation.Interpolator; |
21 import android.widget.FrameLayout; | 21 import android.widget.FrameLayout; |
22 | 22 |
23 import org.chromium.base.ApiCompatibilityUtils; | 23 import org.chromium.base.ApiCompatibilityUtils; |
24 import org.chromium.base.ObserverList; | 24 import org.chromium.base.ObserverList; |
25 import org.chromium.base.VisibleForTesting; | 25 import org.chromium.base.VisibleForTesting; |
26 import org.chromium.chrome.R; | 26 import org.chromium.chrome.R; |
27 import org.chromium.chrome.browser.NativePageHost; | 27 import org.chromium.chrome.browser.NativePageHost; |
28 import org.chromium.chrome.browser.TabLoadStatus; | 28 import org.chromium.chrome.browser.TabLoadStatus; |
29 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; | 29 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; |
30 import org.chromium.chrome.browser.ntp.NativePageFactory; | 30 import org.chromium.chrome.browser.ntp.NativePageFactory; |
31 import org.chromium.chrome.browser.tab.Tab; | 31 import org.chromium.chrome.browser.tab.Tab; |
32 import org.chromium.chrome.browser.tabmodel.TabModel; | 32 import org.chromium.chrome.browser.tabmodel.TabModel; |
33 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | 33 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
34 import org.chromium.chrome.browser.util.MathUtils; | 34 import org.chromium.chrome.browser.util.MathUtils; |
| 35 import org.chromium.chrome.browser.widget.FadingBackgroundView; |
35 import org.chromium.content_public.browser.LoadUrlParams; | 36 import org.chromium.content_public.browser.LoadUrlParams; |
36 | 37 |
37 import java.lang.annotation.Retention; | 38 import java.lang.annotation.Retention; |
38 import java.lang.annotation.RetentionPolicy; | 39 import java.lang.annotation.RetentionPolicy; |
39 | 40 |
40 /** | 41 /** |
41 * This class defines the bottom sheet that has multiple states and a persistent
ly showing toolbar. | 42 * This class defines the bottom sheet that has multiple states and a persistent
ly showing toolbar. |
42 * Namely, the states are: | 43 * Namely, the states are: |
43 * - PEEK: Only the toolbar is visible at the bottom of the screen. | 44 * - PEEK: Only the toolbar is visible at the bottom of the screen. |
44 * - HALF: The sheet is expanded to consume around half of the screen. | 45 * - HALF: The sheet is expanded to consume around half of the screen. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 * This class is responsible for detecting swipe and scroll events on the bo
ttom sheet or | 188 * This class is responsible for detecting swipe and scroll events on the bo
ttom sheet or |
188 * ignoring them when appropriate. | 189 * ignoring them when appropriate. |
189 */ | 190 */ |
190 private class BottomSheetSwipeDetector extends GestureDetector.SimpleOnGestu
reListener { | 191 private class BottomSheetSwipeDetector extends GestureDetector.SimpleOnGestu
reListener { |
191 @Override | 192 @Override |
192 public boolean onDown(MotionEvent e) { | 193 public boolean onDown(MotionEvent e) { |
193 return true; | 194 return true; |
194 } | 195 } |
195 | 196 |
196 @Override | 197 @Override |
197 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, | 198 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) { |
198 float distanceY) { | |
199 // Only start scrolling if the scroll is up or down. If the user is
already scrolling, | 199 // Only start scrolling if the scroll is up or down. If the user is
already scrolling, |
200 // continue moving the sheet. | 200 // continue moving the sheet. |
201 float slope = Math.abs(distanceX) > 0f ? Math.abs(distanceY) / Math.
abs(distanceX) : 0f; | 201 float slope = Math.abs(distanceX) > 0f ? Math.abs(distanceY) / Math.
abs(distanceX) : 0f; |
202 if (!mIsScrolling && slope < MIN_VERTICAL_SCROLL_SLOPE) { | 202 if (!mIsScrolling && slope < MIN_VERTICAL_SCROLL_SLOPE) { |
203 mVelocityTracker.clear(); | 203 mVelocityTracker.clear(); |
204 return false; | 204 return false; |
205 } | 205 } |
206 | 206 |
207 // Cancel the settling animation if it is running so it doesn't conf
lict with where the | 207 // Cancel the settling animation if it is running so it doesn't conf
lict with where the |
208 // user wants to move the sheet. | 208 // user wants to move the sheet. |
(...skipping 27 matching lines...) Expand all Loading... |
236 } | 236 } |
237 | 237 |
238 float newOffset = getSheetOffsetFromBottom() + distanceY; | 238 float newOffset = getSheetOffsetFromBottom() + distanceY; |
239 setSheetOffsetFromBottom(MathUtils.clamp(newOffset, getMinOffset(),
getMaxOffset())); | 239 setSheetOffsetFromBottom(MathUtils.clamp(newOffset, getMinOffset(),
getMaxOffset())); |
240 | 240 |
241 mIsScrolling = true; | 241 mIsScrolling = true; |
242 return true; | 242 return true; |
243 } | 243 } |
244 | 244 |
245 @Override | 245 @Override |
246 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, | 246 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { |
247 float velocityY) { | |
248 cancelAnimation(); | 247 cancelAnimation(); |
249 | 248 |
250 // Figure out the projected state of the sheet and animate there. No
te that a swipe up | 249 // Figure out the projected state of the sheet and animate there. No
te that a swipe up |
251 // will have a negative velocity, swipe down will have a positive ve
locity. Negate this | 250 // will have a negative velocity, swipe down will have a positive ve
locity. Negate this |
252 // values so that the logic is more intuitive. | 251 // values so that the logic is more intuitive. |
253 @SheetState | 252 @SheetState |
254 int targetState = getTargetSheetState( | 253 int targetState = getTargetSheetState( |
255 getSheetOffsetFromBottom() + getFlingDistance(-velocityY), -
velocityY); | 254 getSheetOffsetFromBottom() + getFlingDistance(-velocityY), -
velocityY); |
256 setSheetState(targetState, true); | 255 setSheetState(targetState, true); |
257 mIsScrolling = false; | 256 mIsScrolling = false; |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 mSettleAnimator.cancel(); | 581 mSettleAnimator.cancel(); |
583 mSettleAnimator = null; | 582 mSettleAnimator = null; |
584 } | 583 } |
585 | 584 |
586 /** | 585 /** |
587 * Creates the sheet's animation to a target state. | 586 * Creates the sheet's animation to a target state. |
588 * @param targetState The target state. | 587 * @param targetState The target state. |
589 */ | 588 */ |
590 private void createSettleAnimation(@SheetState int targetState) { | 589 private void createSettleAnimation(@SheetState int targetState) { |
591 mCurrentState = targetState; | 590 mCurrentState = targetState; |
592 mSettleAnimator = ValueAnimator.ofFloat(getSheetOffsetFromBottom(), | 591 mSettleAnimator = ValueAnimator.ofFloat( |
593 getSheetHeightForState(targetState)); | 592 getSheetOffsetFromBottom(), getSheetHeightForState(targetState))
; |
594 mSettleAnimator.setDuration(BASE_ANIMATION_DURATION_MS); | 593 mSettleAnimator.setDuration(BASE_ANIMATION_DURATION_MS); |
595 mSettleAnimator.setInterpolator(mInterpolator); | 594 mSettleAnimator.setInterpolator(mInterpolator); |
596 | 595 |
597 // When the animation is canceled or ends, reset the handle to null. | 596 // When the animation is canceled or ends, reset the handle to null. |
598 mSettleAnimator.addListener(new AnimatorListenerAdapter() { | 597 mSettleAnimator.addListener(new AnimatorListenerAdapter() { |
599 @Override | 598 @Override |
600 public void onAnimationEnd(Animator animator) { | 599 public void onAnimationEnd(Animator animator) { |
601 mSettleAnimator = null; | 600 mSettleAnimator = null; |
602 } | 601 } |
603 }); | 602 }); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 @Override | 826 @Override |
828 public void onFadingViewVisibilityChanged(boolean visible) {} | 827 public void onFadingViewVisibilityChanged(boolean visible) {} |
829 | 828 |
830 private boolean canMoveSheet() { | 829 private boolean canMoveSheet() { |
831 boolean isInOverviewMode = mTabModelSelector != null | 830 boolean isInOverviewMode = mTabModelSelector != null |
832 && (mTabModelSelector.getCurrentTab() == null | 831 && (mTabModelSelector.getCurrentTab() == null |
833 || mTabModelSelector.getCurrentTab().getActivity().is
InOverviewMode()); | 832 || mTabModelSelector.getCurrentTab().getActivity().is
InOverviewMode()); |
834 return !isToolbarAndroidViewHidden() && !isInOverviewMode; | 833 return !isToolbarAndroidViewHidden() && !isInOverviewMode; |
835 } | 834 } |
836 } | 835 } |
OLD | NEW |