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.ObjectAnimator; | 9 import android.animation.ObjectAnimator; |
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.support.v4.view.ScrollingView; | 14 import android.support.v4.view.ScrollingView; |
15 import android.util.AttributeSet; | 15 import android.util.AttributeSet; |
16 import android.view.GestureDetector; | 16 import android.view.GestureDetector; |
17 import android.view.MotionEvent; | 17 import android.view.MotionEvent; |
18 import android.view.VelocityTracker; | 18 import android.view.VelocityTracker; |
19 import android.view.View; | 19 import android.view.View; |
20 import android.view.ViewGroup; | 20 import android.view.ViewGroup; |
21 import android.view.animation.DecelerateInterpolator; | 21 import android.view.animation.DecelerateInterpolator; |
22 import android.view.animation.Interpolator; | 22 import android.view.animation.Interpolator; |
23 import android.widget.FrameLayout; | 23 import android.widget.FrameLayout; |
24 import android.widget.LinearLayout; | |
25 | 24 |
26 import org.chromium.chrome.R; | 25 import org.chromium.chrome.R; |
27 import org.chromium.chrome.browser.NativePage; | 26 import org.chromium.chrome.browser.NativePage; |
28 import org.chromium.chrome.browser.ntp.NewTabPage; | 27 import org.chromium.chrome.browser.ntp.NewTabPage; |
29 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | 28 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
30 import org.chromium.chrome.browser.util.MathUtils; | 29 import org.chromium.chrome.browser.util.MathUtils; |
31 | 30 |
32 import java.lang.annotation.Retention; | 31 import java.lang.annotation.Retention; |
33 import java.lang.annotation.RetentionPolicy; | 32 import java.lang.annotation.RetentionPolicy; |
34 | 33 |
35 /** | 34 /** |
36 * This class defines the bottom sheet that has multiple states and a persistent
ly showing toolbar. | 35 * This class defines the bottom sheet that has multiple states and a persistent
ly showing toolbar. |
37 * Namely, the states are: | 36 * Namely, the states are: |
38 * - PEEK: Only the toolbar is visible at the bottom of the screen. | 37 * - PEEK: Only the toolbar is visible at the bottom of the screen. |
39 * - HALF: The sheet is expanded to consume around half of the screen. | 38 * - HALF: The sheet is expanded to consume around half of the screen. |
40 * - FULL: The sheet is expanded to its full height. | 39 * - FULL: The sheet is expanded to its full height. |
41 * | 40 * |
42 * All the computation in this file is based off of the bottom of the screen ins
tead of the top | 41 * All the computation in this file is based off of the bottom of the screen ins
tead of the top |
43 * for simplicity. This means that the bottom of the screen is 0 on the Y axis. | 42 * for simplicity. This means that the bottom of the screen is 0 on the Y axis. |
44 */ | 43 */ |
45 public class BottomSheet extends LinearLayout { | 44 public class BottomSheet extends FrameLayout { |
46 /** The different states that the bottom sheet can have. */ | 45 /** The different states that the bottom sheet can have. */ |
47 @IntDef({SHEET_STATE_PEEK, SHEET_STATE_HALF, SHEET_STATE_FULL}) | 46 @IntDef({SHEET_STATE_PEEK, SHEET_STATE_HALF, SHEET_STATE_FULL}) |
48 @Retention(RetentionPolicy.SOURCE) | 47 @Retention(RetentionPolicy.SOURCE) |
49 public @interface SheetState {} | 48 public @interface SheetState {} |
50 public static final int SHEET_STATE_PEEK = 0; | 49 public static final int SHEET_STATE_PEEK = 0; |
51 public static final int SHEET_STATE_HALF = 1; | 50 public static final int SHEET_STATE_HALF = 1; |
52 public static final int SHEET_STATE_FULL = 2; | 51 public static final int SHEET_STATE_FULL = 2; |
53 | 52 |
54 /** | 53 /** |
55 * The base duration of the settling animation of the sheet. 218 ms is a spe
c for material | 54 * The base duration of the settling animation of the sheet. 218 ms is a spe
c for material |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 } | 203 } |
205 | 204 |
206 /** | 205 /** |
207 * Constructor for inflation from XML. | 206 * Constructor for inflation from XML. |
208 * @param context An Android context. | 207 * @param context An Android context. |
209 * @param atts The XML attributes. | 208 * @param atts The XML attributes. |
210 */ | 209 */ |
211 public BottomSheet(Context context, AttributeSet atts) { | 210 public BottomSheet(Context context, AttributeSet atts) { |
212 super(context, atts); | 211 super(context, atts); |
213 | 212 |
214 setOrientation(LinearLayout.VERTICAL); | |
215 mVelocityTracker = VelocityTracker.obtain(); | 213 mVelocityTracker = VelocityTracker.obtain(); |
216 | 214 |
217 mGestureDetector = new GestureDetector(context, new BottomSheetSwipeDete
ctor()); | 215 mGestureDetector = new GestureDetector(context, new BottomSheetSwipeDete
ctor()); |
218 mGestureDetector.setIsLongpressEnabled(false); | 216 mGestureDetector.setIsLongpressEnabled(false); |
219 } | 217 } |
220 | 218 |
221 @Override | 219 @Override |
222 public boolean onInterceptTouchEvent(MotionEvent e) { | 220 public boolean onInterceptTouchEvent(MotionEvent e) { |
223 // The incoming motion event may have been adjusted by the view sending
it down. Create a | 221 // The incoming motion event may have been adjusted by the view sending
it down. Create a |
224 // motion event with the raw (x, y) coordinates of the original so the g
esture detector | 222 // motion event with the raw (x, y) coordinates of the original so the g
esture detector |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 if (mContainerHeight <= 0) return; | 376 if (mContainerHeight <= 0) return; |
379 | 377 |
380 // Though mStateRatios is a static constant, the peeking ratio is comput
ed here because | 378 // Though mStateRatios is a static constant, the peeking ratio is comput
ed here because |
381 // the correct toolbar height and container height are not know until th
ose views are | 379 // the correct toolbar height and container height are not know until th
ose views are |
382 // inflated. | 380 // inflated. |
383 mStateRatios[0] = mToolbarHeight / mContainerHeight; | 381 mStateRatios[0] = mToolbarHeight / mContainerHeight; |
384 | 382 |
385 // Compute the height that the content section of the bottom sheet. | 383 // Compute the height that the content section of the bottom sheet. |
386 float contentHeight = | 384 float contentHeight = |
387 (mContainerHeight * mStateRatios[mStateRatios.length - 1]) - mTo
olbarHeight; | 385 (mContainerHeight * mStateRatios[mStateRatios.length - 1]) - mTo
olbarHeight; |
388 mBottomSheetContent.setLayoutParams( | 386 |
389 new LinearLayout.LayoutParams((int) mContainerWidth, (int) conte
ntHeight)); | 387 MarginLayoutParams sheetContentParams = |
| 388 (MarginLayoutParams) mBottomSheetContent.getLayoutParams(); |
| 389 sheetContentParams.width = (int) mContainerWidth; |
| 390 sheetContentParams.height = (int) contentHeight; |
| 391 sheetContentParams.topMargin = (int) mToolbarHeight; |
| 392 |
| 393 MarginLayoutParams toolbarShadowParams = |
| 394 (MarginLayoutParams) findViewById(R.id.toolbar_shadow).getLayout
Params(); |
| 395 toolbarShadowParams.topMargin = (int) mToolbarHeight; |
390 } | 396 } |
391 | 397 |
392 /** | 398 /** |
393 * Find the first ScrollingView in a view hierarchy. | 399 * Find the first ScrollingView in a view hierarchy. |
394 * TODO(mdjones): The root of native pages should be a ScrollingView so this
logic is not | 400 * TODO(mdjones): The root of native pages should be a ScrollingView so this
logic is not |
395 * necessary. | 401 * necessary. |
396 * @param view The root of the tree or subtree. | 402 * @param view The root of the tree or subtree. |
397 * @return The first scrolling view or null. | 403 * @return The first scrolling view or null. |
398 */ | 404 */ |
399 private ScrollingView findScrollingChild(@Nullable View view) { | 405 private ScrollingView findScrollingChild(@Nullable View view) { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 | 567 |
562 float inverseThreshold = 1.0f - THRESHOLD_TO_NEXT_STATE; | 568 float inverseThreshold = 1.0f - THRESHOLD_TO_NEXT_STATE; |
563 float thresholdToNextState = yVelocity < 0.0f ? THRESHOLD_TO_NEXT_STATE
: inverseThreshold; | 569 float thresholdToNextState = yVelocity < 0.0f ? THRESHOLD_TO_NEXT_STATE
: inverseThreshold; |
564 | 570 |
565 if ((sheetHeight - lowerBound) / distance > thresholdToNextState) { | 571 if ((sheetHeight - lowerBound) / distance > thresholdToNextState) { |
566 return nextState; | 572 return nextState; |
567 } | 573 } |
568 return prevState; | 574 return prevState; |
569 } | 575 } |
570 } | 576 } |
OLD | NEW |