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; |
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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 */ | 330 */ |
331 private boolean isToolbarAndroidViewHidden() { | 331 private boolean isToolbarAndroidViewHidden() { |
332 return mFullscreenManager == null || mFullscreenManager.getBottomControl
Offset() > 0 | 332 return mFullscreenManager == null || mFullscreenManager.getBottomControl
Offset() > 0 |
333 || mControlContainer.getVisibility() != VISIBLE; | 333 || mControlContainer.getVisibility() != VISIBLE; |
334 } | 334 } |
335 | 335 |
336 /** | 336 /** |
337 * Adds layout change listeners to the views that the bottom sheet depends o
n. Namely the | 337 * Adds layout change listeners to the views that the bottom sheet depends o
n. Namely the |
338 * heights of the root view and control container are important as they are
used in many of the | 338 * heights of the root view and control container are important as they are
used in many of the |
339 * calculations in this class. | 339 * calculations in this class. |
340 * @param activity An activity for loading native pages. | |
341 * @param root The container of the bottom sheet. | 340 * @param root The container of the bottom sheet. |
342 * @param controlContainer The container for the toolbar. | 341 * @param controlContainer The container for the toolbar. |
343 */ | 342 */ |
344 public void init(View root, View controlContainer) { | 343 public void init(View root, View controlContainer) { |
345 mControlContainer = controlContainer; | 344 mControlContainer = controlContainer; |
346 mToolbarHeight = mControlContainer.getHeight(); | 345 mToolbarHeight = mControlContainer.getHeight(); |
347 | 346 |
348 mBottomSheetContentContainer = (FrameLayout) findViewById(R.id.bottom_sh
eet_content); | 347 mBottomSheetContentContainer = (FrameLayout) findViewById(R.id.bottom_sh
eet_content); |
349 | 348 |
350 mCurrentState = SHEET_STATE_PEEK; | 349 mCurrentState = SHEET_STATE_PEEK; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 mPlaceholder = new View(getContext()); | 386 mPlaceholder = new View(getContext()); |
388 LayoutParams placeHolderParams = | 387 LayoutParams placeHolderParams = |
389 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_P
ARENT); | 388 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_P
ARENT); |
390 mPlaceholder.setBackgroundColor( | 389 mPlaceholder.setBackgroundColor( |
391 ApiCompatibilityUtils.getColor(getResources(), android.R.color.w
hite)); | 390 ApiCompatibilityUtils.getColor(getResources(), android.R.color.w
hite)); |
392 mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams); | 391 mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams); |
393 } | 392 } |
394 | 393 |
395 @Override | 394 @Override |
396 public int loadUrl(LoadUrlParams params) { | 395 public int loadUrl(LoadUrlParams params) { |
| 396 for (BottomSheetObserver o : mObservers) o.onLoadUrl(params.getUrl()); |
| 397 |
397 // Native page URLs in this context do not need to communicate with the
tab. | 398 // Native page URLs in this context do not need to communicate with the
tab. |
398 if (NativePageFactory.isNativePageUrl(params.getUrl(), isIncognito())) { | 399 if (NativePageFactory.isNativePageUrl(params.getUrl(), isIncognito())) { |
399 return TabLoadStatus.PAGE_LOAD_FAILED; | 400 return TabLoadStatus.PAGE_LOAD_FAILED; |
400 } | 401 } |
401 | 402 |
402 // In all non-native cases, minimize the sheet. | 403 // In all non-native cases, minimize the sheet. |
403 setSheetState(SHEET_STATE_PEEK, true); | 404 setSheetState(SHEET_STATE_PEEK, true); |
404 | 405 |
405 assert mTabModelSelector != null; | 406 assert mTabModelSelector != null; |
406 | 407 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 if (mControlContainer == null) return false; | 442 if (mControlContainer == null) return false; |
442 | 443 |
443 mControlContainer.getLocationInWindow(mLocationArray); | 444 mControlContainer.getLocationInWindow(mLocationArray); |
444 | 445 |
445 return e.getRawY() < mLocationArray[1] + mToolbarHeight; | 446 return e.getRawY() < mLocationArray[1] + mToolbarHeight; |
446 } | 447 } |
447 | 448 |
448 /** | 449 /** |
449 * A notification that the sheet is exiting the peek state into one that sho
ws content. | 450 * A notification that the sheet is exiting the peek state into one that sho
ws content. |
450 */ | 451 */ |
451 private void onExitPeekState() { | 452 private void onSheetOpened() { |
452 if (mSuggestionsContent == null) { | 453 if (mSuggestionsContent == null) { |
453 mSuggestionsContent = new SuggestionsBottomSheetContent( | 454 mSuggestionsContent = new SuggestionsBottomSheetContent( |
454 mTabModelSelector.getCurrentTab().getActivity(), this, mTabM
odelSelector); | 455 mTabModelSelector.getCurrentTab().getActivity(), this, mTabM
odelSelector); |
455 } | 456 } |
456 | 457 |
457 showContent(mSuggestionsContent); | 458 showContent(mSuggestionsContent); |
| 459 |
| 460 for (BottomSheetObserver o : mObservers) o.onSheetOpened(); |
458 } | 461 } |
459 | 462 |
460 /** | 463 /** |
| 464 * A notification that the sheet has returned to the peeking state. |
| 465 */ |
| 466 private void onSheetClosed() { |
| 467 for (BottomSheetObserver o : mObservers) o.onSheetClosed(); |
| 468 } |
| 469 |
| 470 /** |
461 * Show content in the bottom sheet's content area. | 471 * Show content in the bottom sheet's content area. |
462 * @param content The {@link BottomSheetContent} to show. | 472 * @param content The {@link BottomSheetContent} to show. |
463 */ | 473 */ |
464 private void showContent(BottomSheetContent content) { | 474 private void showContent(BottomSheetContent content) { |
465 // If the desired content is already showing, do nothing. | 475 // If the desired content is already showing, do nothing. |
466 if (mSheetContent == content) return; | 476 if (mSheetContent == content) return; |
467 | 477 |
468 if (mSheetContent != null) { | 478 if (mSheetContent != null) { |
469 mBottomSheetContentContainer.removeView(mSheetContent.getScrollingCo
ntentView()); | 479 mBottomSheetContentContainer.removeView(mSheetContent.getScrollingCo
ntentView()); |
470 mSheetContent = null; | 480 mSheetContent = null; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 return mContainerHeight - getTranslationY(); | 602 return mContainerHeight - getTranslationY(); |
593 } | 603 } |
594 | 604 |
595 /** | 605 /** |
596 * Sets the sheet's offset relative to the bottom of the screen. | 606 * Sets the sheet's offset relative to the bottom of the screen. |
597 * @param offset The offset that the sheet should be. | 607 * @param offset The offset that the sheet should be. |
598 */ | 608 */ |
599 private void setSheetOffsetFromBottom(float offset) { | 609 private void setSheetOffsetFromBottom(float offset) { |
600 if (MathUtils.areFloatsEqual(getSheetOffsetFromBottom(), getMinOffset()) | 610 if (MathUtils.areFloatsEqual(getSheetOffsetFromBottom(), getMinOffset()) |
601 && offset > getMinOffset()) { | 611 && offset > getMinOffset()) { |
602 onExitPeekState(); | 612 onSheetOpened(); |
| 613 } else if (MathUtils.areFloatsEqual(offset, getMinOffset()) |
| 614 && getSheetOffsetFromBottom() > getMinOffset()) { |
| 615 onSheetClosed(); |
603 } | 616 } |
604 | 617 |
605 setTranslationY(mContainerHeight - offset); | 618 setTranslationY(mContainerHeight - offset); |
606 sendUpdatePeekToHalfEvent(); | 619 sendUpdatePeekToHalfEvent(); |
607 } | 620 } |
608 | 621 |
609 /** | 622 /** |
| 623 * This is the same as {@link #setSheetOffsetFromBottom(float)} but exclusiv
ely for testing. |
| 624 * @param offset The offset to set the sheet to. |
| 625 */ |
| 626 @VisibleForTesting |
| 627 public void setSheetOffsetFromBottomForTesting(float offset) { |
| 628 setSheetOffsetFromBottom(offset); |
| 629 } |
| 630 |
| 631 /** |
610 * @return The ratio of the height of the screen that the peeking state is. | 632 * @return The ratio of the height of the screen that the peeking state is. |
611 */ | 633 */ |
612 private float getPeekRatio() { | 634 @VisibleForTesting |
| 635 public float getPeekRatio() { |
613 return mStateRatios[0]; | 636 return mStateRatios[0]; |
614 } | 637 } |
615 | 638 |
616 /** | 639 /** |
617 * @return The ratio of the height of the screen that the half expanded stat
e is. | 640 * @return The ratio of the height of the screen that the half expanded stat
e is. |
618 */ | 641 */ |
619 private float getHalfRatio() { | 642 @VisibleForTesting |
| 643 public float getHalfRatio() { |
620 return mStateRatios[1]; | 644 return mStateRatios[1]; |
621 } | 645 } |
622 | 646 |
623 /** | 647 /** |
624 * @return The ratio of the height of the screen that the fully expanded sta
te is. | 648 * @return The ratio of the height of the screen that the fully expanded sta
te is. |
625 */ | 649 */ |
626 private float getFullRatio() { | 650 @VisibleForTesting |
| 651 public float getFullRatio() { |
627 return mStateRatios[2]; | 652 return mStateRatios[2]; |
628 } | 653 } |
629 | 654 |
630 /** | 655 /** |
| 656 * @return The height of the container that the bottom sheet exists in. |
| 657 */ |
| 658 @VisibleForTesting |
| 659 public float getSheetContainerHeight() { |
| 660 return mContainerHeight; |
| 661 } |
| 662 |
| 663 /** |
631 * Sends a notification if the sheet is transitioning from the peeking to ha
lf expanded state. | 664 * Sends a notification if the sheet is transitioning from the peeking to ha
lf expanded state. |
632 * This method only sends events when the sheet is between the peeking and h
alf states. | 665 * This method only sends events when the sheet is between the peeking and h
alf states. |
633 */ | 666 */ |
634 private void sendUpdatePeekToHalfEvent() { | 667 private void sendUpdatePeekToHalfEvent() { |
635 float screenRatio = | 668 float screenRatio = |
636 mContainerHeight > 0 ? getSheetOffsetFromBottom() / mContainerHe
ight : 0; | 669 mContainerHeight > 0 ? getSheetOffsetFromBottom() / mContainerHe
ight : 0; |
637 | 670 |
638 // This ratio is relative to the peek and half positions of the sheet ra
ther than the height | 671 // This ratio is relative to the peek and half positions of the sheet ra
ther than the height |
639 // of the screen. | 672 // of the screen. |
640 float peekHalfRatio = MathUtils.clamp( | 673 float peekHalfRatio = MathUtils.clamp( |
641 (screenRatio - getPeekRatio()) / (getHalfRatio() - getPeekRatio(
)), 0, 1); | 674 (screenRatio - getPeekRatio()) / (getHalfRatio() - getPeekRatio(
)), 0, 1); |
642 | 675 |
643 // If the ratio is close enough to zero, just set it to zero. | 676 // If the ratio is close enough to zero, just set it to zero. |
644 if (MathUtils.areFloatsEqual(peekHalfRatio, 0f)) peekHalfRatio = 0f; | 677 if (MathUtils.areFloatsEqual(peekHalfRatio, 0f)) peekHalfRatio = 0f; |
645 | 678 |
646 for (BottomSheetObserver o : mObservers) { | 679 if (mLastPeekToHalfRatioSent < 1f || peekHalfRatio < 1f) { |
647 if (mLastPeekToHalfRatioSent < 1f || peekHalfRatio < 1f) { | 680 mLastPeekToHalfRatioSent = peekHalfRatio; |
648 mLastPeekToHalfRatioSent = peekHalfRatio; | 681 for (BottomSheetObserver o : mObservers) { |
649 o.onTransitionPeekToHalf(peekHalfRatio); | 682 o.onTransitionPeekToHalf(peekHalfRatio); |
650 } | 683 } |
651 } | 684 } |
652 } | 685 } |
653 | 686 |
654 /** | 687 /** |
655 * Moves the sheet to the provided state. | 688 * Moves the sheet to the provided state. |
656 * @param state The state to move the panel to. | 689 * @param state The state to move the panel to. |
657 * @param animate If true, the sheet will animate to the provided state, oth
erwise it will | 690 * @param animate If true, the sheet will animate to the provided state, oth
erwise it will |
658 * move there instantly. | 691 * move there instantly. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 @Override | 789 @Override |
757 public void onFadingViewVisibilityChanged(boolean visible) {} | 790 public void onFadingViewVisibilityChanged(boolean visible) {} |
758 | 791 |
759 private boolean canMoveSheet() { | 792 private boolean canMoveSheet() { |
760 boolean isInOverviewMode = mTabModelSelector != null | 793 boolean isInOverviewMode = mTabModelSelector != null |
761 && (mTabModelSelector.getCurrentTab() == null | 794 && (mTabModelSelector.getCurrentTab() == null |
762 || mTabModelSelector.getCurrentTab().getActivity().is
InOverviewMode()); | 795 || mTabModelSelector.getCurrentTab().getActivity().is
InOverviewMode()); |
763 return !isToolbarAndroidViewHidden() && !isInOverviewMode; | 796 return !isToolbarAndroidViewHidden() && !isInOverviewMode; |
764 } | 797 } |
765 } | 798 } |
OLD | NEW |