| 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 |