Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java

Issue 2759823002: 🏠 Separate bottom sheet current from target state (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.bottomsheet; 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;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 * - 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.
46 * - FULL: The sheet is expanded to its full height. 46 * - FULL: The sheet is expanded to its full height.
47 * 47 *
48 * All the computation in this file is based off of the bottom of the screen ins tead of the top 48 * All the computation in this file is based off of the bottom of the screen ins tead of the top
49 * for simplicity. This means that the bottom of the screen is 0 on the Y axis. 49 * for simplicity. This means that the bottom of the screen is 0 on the Y axis.
50 */ 50 */
51 51
52 public class BottomSheet 52 public class BottomSheet
53 extends FrameLayout implements FadingBackgroundView.FadingViewObserver, NativePageHost { 53 extends FrameLayout implements FadingBackgroundView.FadingViewObserver, NativePageHost {
54 /** The different states that the bottom sheet can have. */ 54 /** The different states that the bottom sheet can have. */
55 @IntDef({SHEET_STATE_PEEK, SHEET_STATE_HALF, SHEET_STATE_FULL}) 55 @IntDef({SHEET_STATE_PEEK, SHEET_STATE_HALF, SHEET_STATE_FULL, SHEET_STATE_S CROLLING})
56 @Retention(RetentionPolicy.SOURCE) 56 @Retention(RetentionPolicy.SOURCE)
57 public @interface SheetState {} 57 public @interface SheetState {}
58 public static final int SHEET_STATE_PEEK = 0; 58 public static final int SHEET_STATE_PEEK = 0;
59 public static final int SHEET_STATE_HALF = 1; 59 public static final int SHEET_STATE_HALF = 1;
60 public static final int SHEET_STATE_FULL = 2; 60 public static final int SHEET_STATE_FULL = 2;
61 public static final int SHEET_STATE_SCROLLING = 3;
61 62
62 /** 63 /**
63 * The base duration of the settling animation of the sheet. 218 ms is a spe c for material 64 * The base duration of the settling animation of the sheet. 218 ms is a spe c for material
64 * design (this is the minimum time a user is guaranteed to pay attention to something). 65 * design (this is the minimum time a user is guaranteed to pay attention to something).
65 */ 66 */
66 private static final long BASE_ANIMATION_DURATION_MS = 218; 67 private static final long BASE_ANIMATION_DURATION_MS = 218;
67 68
68 /** 69 /**
69 * The fraction of the way to the next state the sheet must be swiped to ani mate there when 70 * The fraction of the way to the next state the sheet must be swiped to ani mate there when
70 * released. A smaller value here means a smaller swipe is needed to move th e sheet around. 71 * released. A smaller value here means a smaller swipe is needed to move th e sheet around.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 106
106 /** The height of the toolbar. */ 107 /** The height of the toolbar. */
107 private float mToolbarHeight; 108 private float mToolbarHeight;
108 109
109 /** The width of the view that contains the bottom sheet. */ 110 /** The width of the view that contains the bottom sheet. */
110 private float mContainerWidth; 111 private float mContainerWidth;
111 112
112 /** The height of the view that contains the bottom sheet. */ 113 /** The height of the view that contains the bottom sheet. */
113 private float mContainerHeight; 114 private float mContainerHeight;
114 115
115 /** The current sheet state. If the sheet is moving, this will be the target state. */ 116 /** The current state that the sheet is in. */
116 private int mCurrentState; 117 private int mCurrentState;
117 118
119 /** The target sheet state. This is the state that the sheet is currently mo ving to. */
120 private int mTargetState;
121
118 /** Used for getting the current tab. */ 122 /** Used for getting the current tab. */
119 private TabModelSelector mTabModelSelector; 123 private TabModelSelector mTabModelSelector;
120 124
121 /** The fullscreen manager for information about toolbar offsets. */ 125 /** The fullscreen manager for information about toolbar offsets. */
122 private ChromeFullscreenManager mFullscreenManager; 126 private ChromeFullscreenManager mFullscreenManager;
123 127
124 /** A handle to the content being shown by the sheet. */ 128 /** A handle to the content being shown by the sheet. */
125 private BottomSheetContent mSheetContent; 129 private BottomSheetContent mSheetContent;
126 130
127 /** A handle to the toolbar control container. */ 131 /** A handle to the toolbar control container. */
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 235
232 // Similarly, if the sheet is in the min position, don't move if the scroll is downward. 236 // Similarly, if the sheet is in the min position, don't move if the scroll is downward.
233 if (currentShownRatio <= getPeekRatio() && distanceY < 0) { 237 if (currentShownRatio <= getPeekRatio() && distanceY < 0) {
234 mIsScrolling = false; 238 mIsScrolling = false;
235 return false; 239 return false;
236 } 240 }
237 241
238 float newOffset = getSheetOffsetFromBottom() + distanceY; 242 float newOffset = getSheetOffsetFromBottom() + distanceY;
239 setSheetOffsetFromBottom(MathUtils.clamp(newOffset, getMinOffset(), getMaxOffset())); 243 setSheetOffsetFromBottom(MathUtils.clamp(newOffset, getMinOffset(), getMaxOffset()));
240 244
245 setInternalCurrentState(SHEET_STATE_SCROLLING);
241 mIsScrolling = true; 246 mIsScrolling = true;
242 return true; 247 return true;
243 } 248 }
244 249
245 @Override 250 @Override
246 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 251 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
247 cancelAnimation(); 252 cancelAnimation();
248 253
249 // Figure out the projected state of the sheet and animate there. No te that a swipe up 254 // Figure out the projected state of the sheet and animate there. No te that a swipe up
250 // will have a negative velocity, swipe down will have a positive ve locity. Negate this 255 // will have a negative velocity, swipe down will have a positive ve locity. Negate this
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 * calculations in this class. 357 * calculations in this class.
353 * @param root The container of the bottom sheet. 358 * @param root The container of the bottom sheet.
354 * @param controlContainer The container for the toolbar. 359 * @param controlContainer The container for the toolbar.
355 */ 360 */
356 public void init(View root, View controlContainer) { 361 public void init(View root, View controlContainer) {
357 mControlContainer = controlContainer; 362 mControlContainer = controlContainer;
358 mToolbarHeight = mControlContainer.getHeight(); 363 mToolbarHeight = mControlContainer.getHeight();
359 364
360 mBottomSheetContentContainer = (FrameLayout) findViewById(R.id.bottom_sh eet_content); 365 mBottomSheetContentContainer = (FrameLayout) findViewById(R.id.bottom_sh eet_content);
361 366
362 mCurrentState = SHEET_STATE_PEEK; 367 setInternalCurrentState(SHEET_STATE_SCROLLING);
Theresa 2017/03/17 23:36:19 I would have expected this to stay SHEET_STATE_PEE
mdjones 2017/03/20 16:09:16 Whoops, definitely a mistake. Fixed.
363 368
364 // Listen to height changes on the root. 369 // Listen to height changes on the root.
365 root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 370 root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
366 @Override 371 @Override
367 public void onLayoutChange(View v, int left, int top, int right, int bottom, 372 public void onLayoutChange(View v, int left, int top, int right, int bottom,
368 int oldLeft, int oldTop, int oldRight, int oldBottom) { 373 int oldLeft, int oldTop, int oldRight, int oldBottom) {
369 // Make sure the size of the layout actually changed. 374 // Make sure the size of the layout actually changed.
370 if (bottom - top == oldBottom - oldTop && right - left == oldRig ht - oldLeft) { 375 if (bottom - top == oldBottom - oldTop && right - left == oldRig ht - oldLeft) {
371 return; 376 return;
372 } 377 }
373 378
374 mContainerWidth = right - left; 379 mContainerWidth = right - left;
375 mContainerHeight = bottom - top; 380 mContainerHeight = bottom - top;
376 updateSheetDimensions(); 381 updateSheetDimensions();
377 382
378 cancelAnimation(); 383 cancelAnimation();
379 setSheetState(mCurrentState, false); 384 setSheetState(mTargetState, false);
380 } 385 }
381 }); 386 });
382 387
383 // Listen to height changes on the toolbar. 388 // Listen to height changes on the toolbar.
384 controlContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListen er() { 389 controlContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListen er() {
385 @Override 390 @Override
386 public void onLayoutChange(View v, int left, int top, int right, int bottom, 391 public void onLayoutChange(View v, int left, int top, int right, int bottom,
387 int oldLeft, int oldTop, int oldRight, int oldBottom) { 392 int oldLeft, int oldTop, int oldRight, int oldBottom) {
388 // Make sure the size of the layout actually changed. 393 // Make sure the size of the layout actually changed.
389 if (bottom - top == oldBottom - oldTop && right - left == oldRig ht - oldLeft) { 394 if (bottom - top == oldBottom - oldTop && right - left == oldRig ht - oldLeft) {
390 return; 395 return;
391 } 396 }
392 397
393 mToolbarHeight = bottom - top; 398 mToolbarHeight = bottom - top;
394 updateSheetDimensions(); 399 updateSheetDimensions();
395 400
396 cancelAnimation(); 401 cancelAnimation();
397 setSheetState(mCurrentState, false); 402 setSheetState(mTargetState, false);
398 } 403 }
399 }); 404 });
400 405
401 mPlaceholder = new View(getContext()); 406 mPlaceholder = new View(getContext());
402 LayoutParams placeHolderParams = 407 LayoutParams placeHolderParams =
403 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_P ARENT); 408 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_P ARENT);
404 mPlaceholder.setBackgroundColor( 409 mPlaceholder.setBackgroundColor(
405 ApiCompatibilityUtils.getColor(getResources(), android.R.color.w hite)); 410 ApiCompatibilityUtils.getColor(getResources(), android.R.color.w hite));
406 mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams); 411 mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams);
407 412
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 if (mSettleAnimator == null) return; 585 if (mSettleAnimator == null) return;
581 mSettleAnimator.cancel(); 586 mSettleAnimator.cancel();
582 mSettleAnimator = null; 587 mSettleAnimator = null;
583 } 588 }
584 589
585 /** 590 /**
586 * Creates the sheet's animation to a target state. 591 * Creates the sheet's animation to a target state.
587 * @param targetState The target state. 592 * @param targetState The target state.
588 */ 593 */
589 private void createSettleAnimation(@SheetState int targetState) { 594 private void createSettleAnimation(@SheetState int targetState) {
590 mCurrentState = targetState; 595 mTargetState = targetState;
591 mSettleAnimator = ValueAnimator.ofFloat( 596 mSettleAnimator = ValueAnimator.ofFloat(
592 getSheetOffsetFromBottom(), getSheetHeightForState(targetState)) ; 597 getSheetOffsetFromBottom(), getSheetHeightForState(targetState)) ;
593 mSettleAnimator.setDuration(BASE_ANIMATION_DURATION_MS); 598 mSettleAnimator.setDuration(BASE_ANIMATION_DURATION_MS);
594 mSettleAnimator.setInterpolator(mInterpolator); 599 mSettleAnimator.setInterpolator(mInterpolator);
595 600
596 // When the animation is canceled or ends, reset the handle to null. 601 // When the animation is canceled or ends, reset the handle to null.
597 mSettleAnimator.addListener(new AnimatorListenerAdapter() { 602 mSettleAnimator.addListener(new AnimatorListenerAdapter() {
598 @Override 603 @Override
599 public void onAnimationEnd(Animator animator) { 604 public void onAnimationEnd(Animator animator) {
600 mSettleAnimator = null; 605 mSettleAnimator = null;
606 setInternalCurrentState(mTargetState);
601 } 607 }
602 }); 608 });
603 609
604 mSettleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListen er() { 610 mSettleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListen er() {
605 @Override 611 @Override
606 public void onAnimationUpdate(ValueAnimator animator) { 612 public void onAnimationUpdate(ValueAnimator animator) {
607 setSheetOffsetFromBottom((Float) animator.getAnimatedValue()); 613 setSheetOffsetFromBottom((Float) animator.getAnimatedValue());
608 } 614 }
609 }); 615 });
610 616
611 mSettleAnimator.start(); 617 mSettleAnimator.start();
618 setInternalCurrentState(SHEET_STATE_SCROLLING);
612 } 619 }
613 620
614 /** 621 /**
615 * Gets the distance of a fling based on the velocity and the base animation time. This formula 622 * Gets the distance of a fling based on the velocity and the base animation time. This formula
616 * assumes the deceleration curve is quadratic (t^2), hence the displacement formula should be: 623 * assumes the deceleration curve is quadratic (t^2), hence the displacement formula should be:
617 * displacement = initialVelocity * duration / 2. 624 * displacement = initialVelocity * duration / 2.
618 * @param velocity The velocity of the fling. 625 * @param velocity The velocity of the fling.
619 * @return The distance the fling would cover. 626 * @return The distance the fling would cover.
620 */ 627 */
621 private float getFlingDistance(float velocity) { 628 private float getFlingDistance(float velocity) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 if (mLastPeekToHalfRatioSent < 1f || peekHalfRatio < 1f) { 723 if (mLastPeekToHalfRatioSent < 1f || peekHalfRatio < 1f) {
717 mLastPeekToHalfRatioSent = peekHalfRatio; 724 mLastPeekToHalfRatioSent = peekHalfRatio;
718 for (BottomSheetObserver o : mObservers) { 725 for (BottomSheetObserver o : mObservers) {
719 o.onTransitionPeekToHalf(peekHalfRatio); 726 o.onTransitionPeekToHalf(peekHalfRatio);
720 } 727 }
721 } 728 }
722 } 729 }
723 730
724 /** 731 /**
725 * Moves the sheet to the provided state. 732 * Moves the sheet to the provided state.
726 * @param state The state to move the panel to. 733 * @param state The state to move the panel to.
Theresa 2017/03/17 23:36:19 nit: It may be good to mention that SCROLLING is n
mdjones 2017/03/20 16:09:17 Done.
727 * @param animate If true, the sheet will animate to the provided state, oth erwise it will 734 * @param animate If true, the sheet will animate to the provided state, oth erwise it will
728 * move there instantly. 735 * move there instantly.
729 */ 736 */
730 public void setSheetState(@SheetState int state, boolean animate) { 737 public void setSheetState(@SheetState int state, boolean animate) {
731 mCurrentState = state; 738 assert state != SHEET_STATE_SCROLLING;
739
740 mTargetState = state;
732 741
733 if (animate) { 742 if (animate) {
734 createSettleAnimation(state); 743 createSettleAnimation(state);
735 } else { 744 } else {
736 setSheetOffsetFromBottom(getSheetHeightForState(state)); 745 setSheetOffsetFromBottom(getSheetHeightForState(state));
746 setInternalCurrentState(mTargetState);
737 } 747 }
738 } 748 }
739 749
740 /** 750 /**
741 * @return The current state of the bottom sheet. If the sheet is animating, this will be the 751 * @return The current state of the bottom sheet. If the sheet is animating, this will be the
742 * state the sheet is animating to. 752 * state the sheet is animating to.
743 */ 753 */
744 public int getSheetState() { 754 public int getSheetState() {
745 return mCurrentState; 755 return mCurrentState;
746 } 756 }
747 757
748 /** 758 /**
759 * Set the current state of the bottom sheet. This is for internal use to no tify observers of
760 * state change events.
761 * @param state The current state of the sheet.
762 */
763 private void setInternalCurrentState(@SheetState int state) {
764 // TODO(mdjones): Trigger onSheetStateChanged here.
765 mCurrentState = state;
766 }
767
768 /**
749 * If the animation to settle the sheet in one of its states is running. 769 * If the animation to settle the sheet in one of its states is running.
750 * @return True if the animation is running. 770 * @return True if the animation is running.
751 */ 771 */
752 public boolean isRunningSettleAnimation() { 772 public boolean isRunningSettleAnimation() {
753 return mSettleAnimator != null; 773 return mSettleAnimator != null;
754 } 774 }
755 775
756 @VisibleForTesting 776 @VisibleForTesting
757 public BottomSheetContent getCurrentSheetContent() { 777 public BottomSheetContent getCurrentSheetContent() {
758 return mSheetContent; 778 return mSheetContent;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 @Override 846 @Override
827 public void onFadingViewVisibilityChanged(boolean visible) {} 847 public void onFadingViewVisibilityChanged(boolean visible) {}
828 848
829 private boolean canMoveSheet() { 849 private boolean canMoveSheet() {
830 boolean isInOverviewMode = mTabModelSelector != null 850 boolean isInOverviewMode = mTabModelSelector != null
831 && (mTabModelSelector.getCurrentTab() == null 851 && (mTabModelSelector.getCurrentTab() == null
832 || mTabModelSelector.getCurrentTab().getActivity().is InOverviewMode()); 852 || mTabModelSelector.getCurrentTab().getActivity().is InOverviewMode());
833 return !isToolbarAndroidViewHidden() && !isInOverviewMode; 853 return !isToolbarAndroidViewHidden() && !isInOverviewMode;
834 } 854 }
835 } 855 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698