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

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

Issue 2838313003: Revert of 🏠 Polish bottom sheet content transitions (Closed)
Patch Set: Created 3 years, 7 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 | « chrome/android/java/res/layout/bottom_control_container.xml ('k') | 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.AnimatorSet;
10 import android.animation.ObjectAnimator; 9 import android.animation.ObjectAnimator;
11 import android.animation.ValueAnimator; 10 import android.animation.ValueAnimator;
12 import android.content.Context; 11 import android.content.Context;
13 import android.content.SharedPreferences; 12 import android.content.SharedPreferences;
14 import android.graphics.Color; 13 import android.graphics.Color;
15 import android.graphics.Region; 14 import android.graphics.Region;
16 import android.os.Build; 15 import android.os.Build;
17 import android.support.annotation.IntDef; 16 import android.support.annotation.IntDef;
18 import android.support.annotation.Nullable; 17 import android.support.annotation.Nullable;
19 import android.util.AttributeSet; 18 import android.util.AttributeSet;
20 import android.view.GestureDetector; 19 import android.view.GestureDetector;
21 import android.view.MotionEvent; 20 import android.view.MotionEvent;
22 import android.view.VelocityTracker; 21 import android.view.VelocityTracker;
23 import android.view.View; 22 import android.view.View;
24 import android.view.ViewGroup;
25 import android.view.Window; 23 import android.view.Window;
26 import android.view.animation.DecelerateInterpolator; 24 import android.view.animation.DecelerateInterpolator;
27 import android.view.animation.Interpolator; 25 import android.view.animation.Interpolator;
28 import android.widget.FrameLayout; 26 import android.widget.FrameLayout;
29 27
30 import org.chromium.base.ApiCompatibilityUtils; 28 import org.chromium.base.ApiCompatibilityUtils;
31 import org.chromium.base.ContextUtils; 29 import org.chromium.base.ContextUtils;
32 import org.chromium.base.ObserverList; 30 import org.chromium.base.ObserverList;
33 import org.chromium.base.VisibleForTesting; 31 import org.chromium.base.VisibleForTesting;
34 import org.chromium.chrome.R; 32 import org.chromium.chrome.R;
35 import org.chromium.chrome.browser.NativePageHost; 33 import org.chromium.chrome.browser.NativePageHost;
36 import org.chromium.chrome.browser.TabLoadStatus; 34 import org.chromium.chrome.browser.TabLoadStatus;
37 import org.chromium.chrome.browser.firstrun.FirstRunStatus; 35 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
38 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; 36 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
39 import org.chromium.chrome.browser.ntp.NativePageFactory; 37 import org.chromium.chrome.browser.ntp.NativePageFactory;
40 import org.chromium.chrome.browser.ntp.NewTabPage; 38 import org.chromium.chrome.browser.ntp.NewTabPage;
41 import org.chromium.chrome.browser.tab.Tab; 39 import org.chromium.chrome.browser.tab.Tab;
42 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; 40 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
43 import org.chromium.chrome.browser.tabmodel.TabModel; 41 import org.chromium.chrome.browser.tabmodel.TabModel;
44 import org.chromium.chrome.browser.tabmodel.TabModelSelector; 42 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
45 import org.chromium.chrome.browser.toolbar.BottomToolbarPhone; 43 import org.chromium.chrome.browser.toolbar.BottomToolbarPhone;
46 import org.chromium.chrome.browser.util.MathUtils; 44 import org.chromium.chrome.browser.util.MathUtils;
47 import org.chromium.chrome.browser.widget.FadingBackgroundView; 45 import org.chromium.chrome.browser.widget.FadingBackgroundView;
48 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContentControll er.ContentType; 46 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContentControll er.ContentType;
49 import org.chromium.chrome.browser.widget.textbubble.ViewAnchoredTextBubble; 47 import org.chromium.chrome.browser.widget.textbubble.ViewAnchoredTextBubble;
50 import org.chromium.content_public.browser.LoadUrlParams; 48 import org.chromium.content_public.browser.LoadUrlParams;
51 49
52 import java.lang.annotation.Retention; 50 import java.lang.annotation.Retention;
53 import java.lang.annotation.RetentionPolicy; 51 import java.lang.annotation.RetentionPolicy;
54 import java.util.ArrayList;
55 import java.util.List;
56 52
57 /** 53 /**
58 * This class defines the bottom sheet that has multiple states and a persistent ly showing toolbar. 54 * This class defines the bottom sheet that has multiple states and a persistent ly showing toolbar.
59 * Namely, the states are: 55 * Namely, the states are:
60 * - PEEK: Only the toolbar is visible at the bottom of the screen. 56 * - PEEK: Only the toolbar is visible at the bottom of the screen.
61 * - HALF: The sheet is expanded to consume around half of the screen. 57 * - HALF: The sheet is expanded to consume around half of the screen.
62 * - FULL: The sheet is expanded to its full height. 58 * - FULL: The sheet is expanded to its full height.
63 * 59 *
64 * All the computation in this file is based off of the bottom of the screen ins tead of the top 60 * All the computation in this file is based off of the bottom of the screen ins tead of the top
65 * for simplicity. This means that the bottom of the screen is 0 on the Y axis. 61 * for simplicity. This means that the bottom of the screen is 0 on the Y axis.
(...skipping 17 matching lines...) Expand all
83 79
84 /** Shared preference key for tracking whether the help bubble has been show n. */ 80 /** Shared preference key for tracking whether the help bubble has been show n. */
85 private static final String BOTTOM_SHEET_HELP_BUBBLE_SHOWN = "bottom_sheet_h elp_bubble_shown"; 81 private static final String BOTTOM_SHEET_HELP_BUBBLE_SHOWN = "bottom_sheet_h elp_bubble_shown";
86 82
87 /** 83 /**
88 * The base duration of the settling animation of the sheet. 218 ms is a spe c for material 84 * The base duration of the settling animation of the sheet. 218 ms is a spe c for material
89 * design (this is the minimum time a user is guaranteed to pay attention to something). 85 * design (this is the minimum time a user is guaranteed to pay attention to something).
90 */ 86 */
91 private static final long BASE_ANIMATION_DURATION_MS = 218; 87 private static final long BASE_ANIMATION_DURATION_MS = 218;
92 88
93 /** The amount of time it takes to transition sheet content in or out. */
94 private static final long TRANSITION_DURATION_MS = 150;
95
96 /** 89 /**
97 * The fraction of the way to the next state the sheet must be swiped to ani mate there when 90 * The fraction of the way to the next state the sheet must be swiped to ani mate there when
98 * released. This is the value used when there are 3 active states. A smalle r value here means 91 * released. This is the value used when there are 3 active states. A smalle r value here means
99 * a smaller swipe is needed to move the sheet around. 92 * a smaller swipe is needed to move the sheet around.
100 */ 93 */
101 private static final float THRESHOLD_TO_NEXT_STATE_3 = 0.5f; 94 private static final float THRESHOLD_TO_NEXT_STATE_3 = 0.5f;
102 95
103 /** This is similar to {@link #THRESHOLD_TO_NEXT_STATE_3} but for 2 states i nstead of 3. */ 96 /** This is similar to {@link #THRESHOLD_TO_NEXT_STATE_3} but for 2 states i nstead of 3. */
104 private static final float THRESHOLD_TO_NEXT_STATE_2 = 0.3f; 97 private static final float THRESHOLD_TO_NEXT_STATE_2 = 0.3f;
105 98
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 133
141 /** Whether or not the user is scrolling the bottom sheet. */ 134 /** Whether or not the user is scrolling the bottom sheet. */
142 private boolean mIsScrolling; 135 private boolean mIsScrolling;
143 136
144 /** Track the velocity of the user's scrolls to determine up or down directi on. */ 137 /** Track the velocity of the user's scrolls to determine up or down directi on. */
145 private VelocityTracker mVelocityTracker; 138 private VelocityTracker mVelocityTracker;
146 139
147 /** The animator used to move the sheet to a fixed state when released by th e user. */ 140 /** The animator used to move the sheet to a fixed state when released by th e user. */
148 private ValueAnimator mSettleAnimator; 141 private ValueAnimator mSettleAnimator;
149 142
150 /** The animator set responsible for swapping the bottom sheet content. */ 143 /** The animator used for the toolbar fades. */
151 private AnimatorSet mContentSwapAnimatorSet; 144 private ValueAnimator mToolbarFadeAnimator;
152 145
153 /** The height of the toolbar. */ 146 /** The height of the toolbar. */
154 private float mToolbarHeight; 147 private float mToolbarHeight;
155 148
156 /** The width of the view that contains the bottom sheet. */ 149 /** The width of the view that contains the bottom sheet. */
157 private float mContainerWidth; 150 private float mContainerWidth;
158 151
159 /** The height of the view that contains the bottom sheet. */ 152 /** The height of the view that contains the bottom sheet. */
160 private float mContainerHeight; 153 private float mContainerHeight;
161 154
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 550
558 cancelAnimation(); 551 cancelAnimation();
559 setSheetState(mCurrentState, false); 552 setSheetState(mCurrentState, false);
560 } 553 }
561 }); 554 });
562 555
563 mPlaceholder = new View(getContext()); 556 mPlaceholder = new View(getContext());
564 LayoutParams placeHolderParams = 557 LayoutParams placeHolderParams =
565 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_P ARENT); 558 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_P ARENT);
566 mPlaceholder.setBackgroundColor( 559 mPlaceholder.setBackgroundColor(
567 ApiCompatibilityUtils.getColor(getResources(), R.color.default_p rimary_color)); 560 ApiCompatibilityUtils.getColor(getResources(), android.R.color.w hite));
568 mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams); 561 mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams);
569 562
570 mToolbarHolder = (FrameLayout) mControlContainer.findViewById(R.id.toolb ar_holder); 563 mToolbarHolder = (FrameLayout) mControlContainer.findViewById(R.id.toolb ar_holder);
571 mDefaultToolbarView = (BottomToolbarPhone) mControlContainer.findViewByI d(R.id.toolbar); 564 mDefaultToolbarView = (BottomToolbarPhone) mControlContainer.findViewByI d(R.id.toolbar);
572 } 565 }
573 566
574 /** 567 /**
575 * Set the color of the pull handle used by the toolbar. 568 * Set the color of the pull handle used by the toolbar.
576 */ 569 */
577 public void updateHandleTint() { 570 public void updateHandleTint() {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 * @return The sheet's distance from the bottom of the screen. 638 * @return The sheet's distance from the bottom of the screen.
646 */ 639 */
647 public float getSheetOffsetFromBottom() { 640 public float getSheetOffsetFromBottom() {
648 return mContainerHeight - getTranslationY(); 641 return mContainerHeight - getTranslationY();
649 } 642 }
650 643
651 /** 644 /**
652 * Show content in the bottom sheet's content area. 645 * Show content in the bottom sheet's content area.
653 * @param content The {@link BottomSheetContent} to show. 646 * @param content The {@link BottomSheetContent} to show.
654 */ 647 */
655 public void showContent(final BottomSheetContent content) { 648 public void showContent(BottomSheetContent content) {
656 // If the desired content is already showing, do nothing. 649 // If the desired content is already showing, do nothing.
657 if (mSheetContent == content) return; 650 if (mSheetContent == content) return;
658 651
652 View newToolbar = content.getToolbarView();
653 View oldToolbar = null;
654
655 if (mSheetContent != null) {
656 oldToolbar = mSheetContent.getToolbarView();
657 mBottomSheetContentContainer.removeView(mSheetContent.getContentView ());
658 mSheetContent = null;
659 }
660
659 mBottomSheetContentContainer.removeView(mPlaceholder); 661 mBottomSheetContentContainer.removeView(mPlaceholder);
662 mSheetContent = content;
663 mBottomSheetContentContainer.addView(mSheetContent.getContentView());
660 664
661 View newToolbar = 665 doToolbarSwap(newToolbar, oldToolbar);
662 content.getToolbarView() != null ? content.getToolbarView() : mD efaultToolbarView;
663 View oldToolbar = mSheetContent != null && mSheetContent.getToolbarView( ) != null
664 ? mSheetContent.getToolbarView()
665 : mDefaultToolbarView;
666 View oldContent = mSheetContent != null ? mSheetContent.getContentView() : null;
667 666
668 // If an animation is already running, end it. 667 for (BottomSheetObserver o : mObservers) {
669 if (mContentSwapAnimatorSet != null) mContentSwapAnimatorSet.end(); 668 o.onSheetContentChanged(mSheetContent);
669 }
670 }
670 671
671 List<Animator> animators = new ArrayList<>(); 672 /**
672 mContentSwapAnimatorSet = new AnimatorSet(); 673 * Fade between a new toolbar and the old toolbar to be shown. A null parame ter can be used to
673 mContentSwapAnimatorSet.addListener(new AnimatorListenerAdapter() { 674 * refer to the default omnibox toolbar. Normally, the new toolbar is attach ed to the toolbar
675 * container and faded in. In the case of the default toolbar, the old toolb ar is faded out.
676 * This is because the default toolbar is always attached to the view hierar chy and sits behind
677 * the attach point for the other toolbars.
678 * @param newToolbar The toolbar that will be shown.
679 * @param oldToolbar The toolbar being replaced.
680 */
681 private void doToolbarSwap(View newToolbar, View oldToolbar) {
682 if (mToolbarFadeAnimator != null) mToolbarFadeAnimator.end();
683
684 final View targetToolbar = newToolbar != null ? newToolbar : mDefaultToo lbarView;
685 final View currentToolbar = oldToolbar != null ? oldToolbar : mDefaultTo olbarView;
686
687 if (targetToolbar == currentToolbar) return;
688
689 if (targetToolbar != mDefaultToolbarView) {
690 mToolbarHolder.addView(targetToolbar);
691 targetToolbar.setAlpha(0f);
692 } else {
693 targetToolbar.setVisibility(View.VISIBLE);
694 targetToolbar.setAlpha(1f);
695 }
696
697 mToolbarFadeAnimator = ObjectAnimator.ofFloat(0, 1);
698 mToolbarFadeAnimator.setDuration(BASE_ANIMATION_DURATION_MS);
699 mToolbarFadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateL istener() {
700 @Override
701 public void onAnimationUpdate(ValueAnimator animator) {
702 if (targetToolbar == mDefaultToolbarView) {
703 currentToolbar.setAlpha(1f - animator.getAnimatedFraction()) ;
704 } else {
705 targetToolbar.setAlpha(animator.getAnimatedFraction());
706 }
707 }
708 });
709 mToolbarFadeAnimator.addListener(new AnimatorListenerAdapter() {
674 @Override 710 @Override
675 public void onAnimationEnd(Animator animation) { 711 public void onAnimationEnd(Animator animation) {
676 mSheetContent = content; 712 targetToolbar.setAlpha(1f);
677 for (BottomSheetObserver o : mObservers) { 713 currentToolbar.setAlpha(0f);
678 o.onSheetContentChanged(content); 714 if (currentToolbar != mDefaultToolbarView) {
715 mToolbarHolder.removeView(currentToolbar);
716 } else {
717 currentToolbar.setVisibility(View.GONE);
679 } 718 }
719 mToolbarFadeAnimator = null;
680 updateHandleTint(); 720 updateHandleTint();
681 mContentSwapAnimatorSet = null;
682 } 721 }
683 }); 722 });
684 723
685 // For the toolbar transition, make sure we don't detach the default too lbar view. 724 mToolbarFadeAnimator.start();
686 animators.add(getViewTransitionAnimator(
687 newToolbar, oldToolbar, mToolbarHolder, mDefaultToolbarView != o ldToolbar));
688 animators.add(getViewTransitionAnimator(
689 content.getContentView(), oldContent, mBottomSheetContentContain er, true));
690
691 mContentSwapAnimatorSet.playTogether(animators);
692 mContentSwapAnimatorSet.start();
693 } 725 }
694 726
695 /** 727 /**
696 * Creates a transition animation between two views. The old view is faded o ut completely
697 * before the new view is faded in. There is an option to detach the old vie w or not.
698 * @param newView The new view to transition to.
699 * @param oldView The old view to transition from.
700 * @param detachOldView Whether or not to detach the old view once faded out .
701 * @return An animator that runs the specified animation.
702 */
703 private Animator getViewTransitionAnimator(final View newView, final View ol dView,
704 final ViewGroup parent, final boolean detachOldView) {
705 if (newView == oldView) return null;
706
707 AnimatorSet animatorSet = new AnimatorSet();
708 List<Animator> animators = new ArrayList<>();
709
710 // Fade out the old view.
711 if (oldView != null) {
712 ValueAnimator fadeOutAnimator = ObjectAnimator.ofFloat(oldView, View .ALPHA, 0);
713 fadeOutAnimator.setDuration(TRANSITION_DURATION_MS);
714 fadeOutAnimator.addListener(new AnimatorListenerAdapter() {
715 @Override
716 public void onAnimationEnd(Animator animation) {
717 if (detachOldView && oldView.getParent() != null) {
718 parent.removeView(oldView);
719 }
720 }
721 });
722 animators.add(fadeOutAnimator);
723 }
724
725 // Fade in the new view.
726 if (parent != newView.getParent()) parent.addView(newView);
727 newView.setAlpha(0);
728 ValueAnimator fadeInAnimator = ObjectAnimator.ofFloat(newView, View.ALPH A, 1);
729 fadeInAnimator.setDuration(TRANSITION_DURATION_MS);
730 animators.add(fadeInAnimator);
731
732 animatorSet.playSequentially(animators);
733
734 return animatorSet;
735 }
736
737 /**
738 * Determines if a touch event is inside the toolbar. This assumes the toolb ar is the full 728 * Determines if a touch event is inside the toolbar. This assumes the toolb ar is the full
739 * width of the screen and that the toolbar is at the top of the bottom shee t. 729 * width of the screen and that the toolbar is at the top of the bottom shee t.
740 * @param e The motion event to test. 730 * @param e The motion event to test.
741 * @return True if the event occured in the toolbar region. 731 * @return True if the event occured in the toolbar region.
742 */ 732 */
743 private boolean isTouchEventInToolbar(MotionEvent e) { 733 private boolean isTouchEventInToolbar(MotionEvent e) {
744 if (mControlContainer == null) return false; 734 if (mControlContainer == null) return false;
745 735
746 mControlContainer.getLocationInWindow(mLocationArray); 736 mControlContainer.getLocationInWindow(mLocationArray);
747 737
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 getContext(), mControlContainer, R.string.bottom_sheet_help_bubb le_message); 1141 getContext(), mControlContainer, R.string.bottom_sheet_help_bubb le_message);
1152 int inset = getContext().getResources().getDimensionPixelSize( 1142 int inset = getContext().getResources().getDimensionPixelSize(
1153 R.dimen.bottom_sheet_help_bubble_inset); 1143 R.dimen.bottom_sheet_help_bubble_inset);
1154 helpBubble.setInsetPx(0, inset, 0, inset); 1144 helpBubble.setInsetPx(0, inset, 0, inset);
1155 helpBubble.setDismissOnTouchInteraction(true); 1145 helpBubble.setDismissOnTouchInteraction(true);
1156 helpBubble.show(); 1146 helpBubble.show();
1157 1147
1158 preferences.edit().putBoolean(BOTTOM_SHEET_HELP_BUBBLE_SHOWN, true).appl y(); 1148 preferences.edit().putBoolean(BOTTOM_SHEET_HELP_BUBBLE_SHOWN, true).appl y();
1159 } 1149 }
1160 } 1150 }
OLDNEW
« no previous file with comments | « chrome/android/java/res/layout/bottom_control_container.xml ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698