Chromium Code Reviews| 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.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 15 matching lines...) Expand all Loading... | |
| 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.chrome.browser.widget.FadingBackgroundView; |
| 36 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContentControll er.ContentType; | |
| 36 import org.chromium.content_public.browser.LoadUrlParams; | 37 import org.chromium.content_public.browser.LoadUrlParams; |
| 37 | 38 |
| 38 import java.lang.annotation.Retention; | 39 import java.lang.annotation.Retention; |
| 39 import java.lang.annotation.RetentionPolicy; | 40 import java.lang.annotation.RetentionPolicy; |
| 40 | 41 |
| 41 /** | 42 /** |
| 42 * This class defines the bottom sheet that has multiple states and a persistent ly showing toolbar. | 43 * This class defines the bottom sheet that has multiple states and a persistent ly showing toolbar. |
| 43 * Namely, the states are: | 44 * Namely, the states are: |
| 44 * - PEEK: Only the toolbar is visible at the bottom of the screen. | 45 * - PEEK: Only the toolbar is visible at the bottom of the screen. |
| 45 * - HALF: The sheet is expanded to consume around half of the screen. | 46 * - HALF: The sheet is expanded to consume around half of the screen. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 | 145 |
| 145 /** | 146 /** |
| 146 * The default toolbar view. This is shown when the current bottom sheet con tent doesn't have | 147 * The default toolbar view. This is shown when the current bottom sheet con tent doesn't have |
| 147 * its own toolbar and when the bottom sheet is closed. | 148 * its own toolbar and when the bottom sheet is closed. |
| 148 */ | 149 */ |
| 149 private View mDefaultToolbarView; | 150 private View mDefaultToolbarView; |
| 150 | 151 |
| 151 /** The last non-default toolbar view that was attached to mToolbarHolder. * / | 152 /** The last non-default toolbar view that was attached to mToolbarHolder. * / |
| 152 private View mLastToolbarView; | 153 private View mLastToolbarView; |
| 153 | 154 |
| 155 /** Whether the sheet is currently open. */ | |
| 156 private boolean mIsSheetOpen; | |
| 157 | |
| 154 /** | 158 /** |
| 155 * An interface defining content that can be displayed inside of the bottom sheet for Chrome | 159 * An interface defining content that can be displayed inside of the bottom sheet for Chrome |
| 156 * Home. | 160 * Home. |
| 157 */ | 161 */ |
| 158 public interface BottomSheetContent { | 162 public interface BottomSheetContent { |
| 159 /** | 163 /** |
| 160 * Gets the {@link View} that holds the content to be displayed in the C hrome Home bottom | 164 * Gets the {@link View} that holds the content to be displayed in the C hrome Home bottom |
| 161 * sheet. | 165 * sheet. |
| 162 * @return The content view. | 166 * @return The content view. |
| 163 */ | 167 */ |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 175 | 179 |
| 176 /** | 180 /** |
| 177 * @return The vertical scroll offset of the content view. | 181 * @return The vertical scroll offset of the content view. |
| 178 */ | 182 */ |
| 179 int getVerticalScrollOffset(); | 183 int getVerticalScrollOffset(); |
| 180 | 184 |
| 181 /** | 185 /** |
| 182 * Called to destroy the BottomSheetContent when it is no longer in use. | 186 * Called to destroy the BottomSheetContent when it is no longer in use. |
| 183 */ | 187 */ |
| 184 void destroy(); | 188 void destroy(); |
| 189 | |
| 190 /** | |
| 191 * @return The {@link BottomSheetContentController.ContentType} for this content. | |
| 192 */ | |
| 193 @ContentType | |
| 194 int getType(); | |
| 185 } | 195 } |
| 186 | 196 |
| 187 /** | 197 /** |
| 188 * This class is responsible for detecting swipe and scroll events on the bo ttom sheet or | 198 * This class is responsible for detecting swipe and scroll events on the bo ttom sheet or |
| 189 * ignoring them when appropriate. | 199 * ignoring them when appropriate. |
| 190 */ | 200 */ |
| 191 private class BottomSheetSwipeDetector extends GestureDetector.SimpleOnGestu reListener { | 201 private class BottomSheetSwipeDetector extends GestureDetector.SimpleOnGestu reListener { |
| 192 @Override | 202 @Override |
| 193 public boolean onDown(MotionEvent e) { | 203 public boolean onDown(MotionEvent e) { |
| 194 return true; | 204 return true; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 * @param context An Android context. | 274 * @param context An Android context. |
| 265 * @param atts The XML attributes. | 275 * @param atts The XML attributes. |
| 266 */ | 276 */ |
| 267 public BottomSheet(Context context, AttributeSet atts) { | 277 public BottomSheet(Context context, AttributeSet atts) { |
| 268 super(context, atts); | 278 super(context, atts); |
| 269 | 279 |
| 270 mVelocityTracker = VelocityTracker.obtain(); | 280 mVelocityTracker = VelocityTracker.obtain(); |
| 271 | 281 |
| 272 mGestureDetector = new GestureDetector(context, new BottomSheetSwipeDete ctor()); | 282 mGestureDetector = new GestureDetector(context, new BottomSheetSwipeDete ctor()); |
| 273 mGestureDetector.setIsLongpressEnabled(false); | 283 mGestureDetector.setIsLongpressEnabled(false); |
| 284 | |
| 285 BottomSheetMetrics metrics = new BottomSheetMetrics(); | |
| 286 addObserver(metrics); | |
|
gone
2017/03/20 21:04:52
maybe just make it addObserver(new BottomSheetMetr
Theresa
2017/03/20 21:22:52
Done.
| |
| 274 } | 287 } |
| 275 | 288 |
| 276 @Override | 289 @Override |
| 277 public boolean onInterceptTouchEvent(MotionEvent e) { | 290 public boolean onInterceptTouchEvent(MotionEvent e) { |
| 278 if (!canMoveSheet()) return false; | 291 if (!canMoveSheet()) return false; |
| 279 | 292 |
| 280 // The incoming motion event may have been adjusted by the view sending it down. Create a | 293 // The incoming motion event may have been adjusted by the view sending it down. Create a |
| 281 // motion event with the raw (x, y) coordinates of the original so the g esture detector | 294 // motion event with the raw (x, y) coordinates of the original so the g esture detector |
| 282 // functions properly. | 295 // functions properly. |
| 283 mGestureDetector.onTouchEvent(createRawMotionEvent(e)); | 296 mGestureDetector.onTouchEvent(createRawMotionEvent(e)); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 mLastToolbarView = null; | 511 mLastToolbarView = null; |
| 499 } | 512 } |
| 500 | 513 |
| 501 if (mSheetContent.getToolbarView() != null) { | 514 if (mSheetContent.getToolbarView() != null) { |
| 502 mLastToolbarView = mSheetContent.getToolbarView(); | 515 mLastToolbarView = mSheetContent.getToolbarView(); |
| 503 mToolbarHolder.addView(mSheetContent.getToolbarView()); | 516 mToolbarHolder.addView(mSheetContent.getToolbarView()); |
| 504 mDefaultToolbarView.setVisibility(View.GONE); | 517 mDefaultToolbarView.setVisibility(View.GONE); |
| 505 } else { | 518 } else { |
| 506 mDefaultToolbarView.setVisibility(View.VISIBLE); | 519 mDefaultToolbarView.setVisibility(View.VISIBLE); |
| 507 } | 520 } |
| 521 | |
| 522 for (BottomSheetObserver o : mObservers) { | |
| 523 o.onSheetContentChanged(mSheetContent); | |
| 524 } | |
| 508 } | 525 } |
| 509 | 526 |
| 510 /** | 527 /** |
| 511 * Determines if a touch event is inside the toolbar. This assumes the toolb ar is the full | 528 * Determines if a touch event is inside the toolbar. This assumes the toolb ar is the full |
| 512 * width of the screen and that the toolbar is at the top of the bottom shee t. | 529 * width of the screen and that the toolbar is at the top of the bottom shee t. |
| 513 * @param e The motion event to test. | 530 * @param e The motion event to test. |
| 514 * @return True if the event occured in the toolbar region. | 531 * @return True if the event occured in the toolbar region. |
| 515 */ | 532 */ |
| 516 private boolean isTouchEventInToolbar(MotionEvent e) { | 533 private boolean isTouchEventInToolbar(MotionEvent e) { |
| 517 if (mControlContainer == null) return false; | 534 if (mControlContainer == null) return false; |
| 518 | 535 |
| 519 mControlContainer.getLocationInWindow(mLocationArray); | 536 mControlContainer.getLocationInWindow(mLocationArray); |
| 520 | 537 |
| 521 return e.getRawY() < mLocationArray[1] + mToolbarHeight; | 538 return e.getRawY() < mLocationArray[1] + mToolbarHeight; |
| 522 } | 539 } |
| 523 | 540 |
| 524 /** | 541 /** |
| 525 * A notification that the sheet is exiting the peek state into one that sho ws content. | 542 * A notification that the sheet is exiting the peek state into one that sho ws content. |
| 526 */ | 543 */ |
| 527 private void onSheetOpened() { | 544 private void onSheetOpened() { |
| 545 if (mIsSheetOpen) return; | |
| 546 | |
| 547 mIsSheetOpen = true; | |
| 528 for (BottomSheetObserver o : mObservers) o.onSheetOpened(); | 548 for (BottomSheetObserver o : mObservers) o.onSheetOpened(); |
| 529 } | 549 } |
| 530 | 550 |
| 531 /** | 551 /** |
| 532 * A notification that the sheet has returned to the peeking state. | 552 * A notification that the sheet has returned to the peeking state. |
| 533 */ | 553 */ |
| 534 private void onSheetClosed() { | 554 private void onSheetClosed() { |
| 555 if (!mIsSheetOpen) return; | |
| 556 | |
| 557 mIsSheetOpen = false; | |
| 535 for (BottomSheetObserver o : mObservers) o.onSheetClosed(); | 558 for (BottomSheetObserver o : mObservers) o.onSheetClosed(); |
| 536 } | 559 } |
| 537 | 560 |
| 538 /** | 561 /** |
| 539 * Creates an unadjusted version of a MotionEvent. | 562 * Creates an unadjusted version of a MotionEvent. |
| 540 * @param e The original event. | 563 * @param e The original event. |
| 541 * @return The unadjusted version of the event. | 564 * @return The unadjusted version of the event. |
| 542 */ | 565 */ |
| 543 private MotionEvent createRawMotionEvent(MotionEvent e) { | 566 private MotionEvent createRawMotionEvent(MotionEvent e) { |
| 544 MotionEvent rawEvent = MotionEvent.obtain(e); | 567 MotionEvent rawEvent = MotionEvent.obtain(e); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 } | 744 } |
| 722 } | 745 } |
| 723 | 746 |
| 724 /** | 747 /** |
| 725 * Moves the sheet to the provided state. | 748 * Moves the sheet to the provided state. |
| 726 * @param state The state to move the panel to. | 749 * @param state The state to move the panel to. |
| 727 * @param animate If true, the sheet will animate to the provided state, oth erwise it will | 750 * @param animate If true, the sheet will animate to the provided state, oth erwise it will |
| 728 * move there instantly. | 751 * move there instantly. |
| 729 */ | 752 */ |
| 730 public void setSheetState(@SheetState int state, boolean animate) { | 753 public void setSheetState(@SheetState int state, boolean animate) { |
| 754 boolean stateChanged = state != mCurrentState; | |
| 731 mCurrentState = state; | 755 mCurrentState = state; |
| 732 | 756 |
| 733 if (animate) { | 757 if (animate) { |
| 734 createSettleAnimation(state); | 758 createSettleAnimation(state); |
| 735 } else { | 759 } else { |
| 736 setSheetOffsetFromBottom(getSheetHeightForState(state)); | 760 setSheetOffsetFromBottom(getSheetHeightForState(state)); |
| 737 } | 761 } |
| 762 | |
| 763 if (!stateChanged) return; | |
| 764 | |
| 765 for (BottomSheetObserver o : mObservers) { | |
| 766 o.onSheetStateChanged(mCurrentState); | |
| 767 } | |
| 738 } | 768 } |
| 739 | 769 |
| 740 /** | 770 /** |
| 741 * @return The current state of the bottom sheet. If the sheet is animating, this will be the | 771 * @return The current state of the bottom sheet. If the sheet is animating, this will be the |
| 742 * state the sheet is animating to. | 772 * state the sheet is animating to. |
| 743 */ | 773 */ |
| 744 public int getSheetState() { | 774 public int getSheetState() { |
| 745 return mCurrentState; | 775 return mCurrentState; |
| 746 } | 776 } |
| 747 | 777 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 @Override | 856 @Override |
| 827 public void onFadingViewVisibilityChanged(boolean visible) {} | 857 public void onFadingViewVisibilityChanged(boolean visible) {} |
| 828 | 858 |
| 829 private boolean canMoveSheet() { | 859 private boolean canMoveSheet() { |
| 830 boolean isInOverviewMode = mTabModelSelector != null | 860 boolean isInOverviewMode = mTabModelSelector != null |
| 831 && (mTabModelSelector.getCurrentTab() == null | 861 && (mTabModelSelector.getCurrentTab() == null |
| 832 || mTabModelSelector.getCurrentTab().getActivity().is InOverviewMode()); | 862 || mTabModelSelector.getCurrentTab().getActivity().is InOverviewMode()); |
| 833 return !isToolbarAndroidViewHidden() && !isInOverviewMode; | 863 return !isToolbarAndroidViewHidden() && !isInOverviewMode; |
| 834 } | 864 } |
| 835 } | 865 } |
| OLD | NEW |