@@ -277,10 +277,15 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
277277 private boolean mAnimateInitialMove ;
278278
279279 /**
280- * ステータスバーの高さ
280+ * status bar's height
281281 */
282282 private final int mBaseStatusBarHeight ;
283283
284+ /**
285+ * status bar's height(landscape)
286+ */
287+ private int mBaseStatusBarRotatedHeight ;
288+
284289 /**
285290 * Current status bar's height
286291 */
@@ -313,6 +318,11 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
313318 */
314319 private int mTouchXOffset ;
315320
321+ /**
322+ * Offset of touch Y coordinate
323+ */
324+ private int mTouchYOffset ;
325+
316326 /**
317327 * 左・右端に寄せるアニメーション
318328 */
@@ -388,6 +398,11 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
388398 */
389399 private int mRotation ;
390400
401+ /**
402+ * Cutout safe inset rect(Same as FloatingViewManager's mSafeInsetRect)
403+ */
404+ private final Rect mSafeInsetRect ;
405+
391406 static {
392407 if (Build .VERSION .SDK_INT <= Build .VERSION_CODES .N_MR1 ) {
393408 OVERLAY_TYPE = WindowManager .LayoutParams .TYPE_PRIORITY_PHONE ;
@@ -427,10 +442,17 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
427442
428443 mMoveLimitRect = new Rect ();
429444 mPositionLimitRect = new Rect ();
445+ mSafeInsetRect = new Rect ();
430446
431447 // ステータスバーの高さを取得
432448 mBaseStatusBarHeight = getSystemUiDimensionPixelSize (resources , "status_bar_height" );
433- mStatusBarHeight = mBaseStatusBarHeight ;
449+ // Check landscape resource id
450+ final int statusBarLandscapeResId = resources .getIdentifier ("status_bar_height_landscape" , "dimen" , "android" );
451+ if (statusBarLandscapeResId > 0 ) {
452+ mBaseStatusBarRotatedHeight = getSystemUiDimensionPixelSize (resources , "status_bar_height_landscape" );
453+ } else {
454+ mBaseStatusBarRotatedHeight = mBaseStatusBarHeight ;
455+ }
434456
435457 // Init physics-based animation properties
436458 updateViewConfiguration ();
@@ -546,18 +568,69 @@ public boolean onPreDraw() {
546568 * @param isHideStatusBar If true, the status bar is hidden
547569 * @param isHideNavigationBar If true, the navigation bar is hidden
548570 * @param isPortrait If true, the device orientation is portrait
549- * @param hasTouchXOffset If true, offset is required for touched X coordinate
571+ * @param windowLeftOffset Left side offset of device display
550572 */
551- void onUpdateSystemLayout (boolean isHideStatusBar , boolean isHideNavigationBar , boolean isPortrait , boolean hasTouchXOffset ) {
573+ void onUpdateSystemLayout (boolean isHideStatusBar , boolean isHideNavigationBar , boolean isPortrait , int windowLeftOffset ) {
552574 // status bar
553- mStatusBarHeight = isHideStatusBar ? 0 : mBaseStatusBarHeight ;
554- // touch X offset(navigation bar is displayed and it is on the left side of the device)
555- mTouchXOffset = !isHideNavigationBar && hasTouchXOffset ? mBaseNavigationBarRotatedHeight : 0 ;
575+ updateStatusBarHeight (isHideStatusBar , isPortrait );
576+ // touch X offset(support Cutout)
577+ updateTouchXOffset (isHideNavigationBar , windowLeftOffset );
578+ // touch Y offset(support Cutout)
579+ mTouchYOffset = isPortrait ? mSafeInsetRect .top : 0 ;
556580 // navigation bar
557581 updateNavigationBarOffset (isHideNavigationBar , isPortrait );
558582 refreshLimitRect ();
559583 }
560584
585+ /**
586+ * Update height of StatusBar.
587+ *
588+ * @param isHideStatusBar If true, the status bar is hidden
589+ * @param isPortrait If true, the device orientation is portrait
590+ */
591+ private void updateStatusBarHeight (boolean isHideStatusBar , boolean isPortrait ) {
592+ if (isHideStatusBar ) {
593+ // 1.(No Cutout)No StatusBar(=0)
594+ // 2.(Has Cutout)StatusBar is not included in mMetrics.heightPixels (=0)
595+ mStatusBarHeight = 0 ;
596+ return ;
597+ }
598+
599+ // Has Cutout
600+ final boolean hasTopCutout = mSafeInsetRect .top != 0 ;
601+ if (hasTopCutout ) {
602+ if (isPortrait ) {
603+ mStatusBarHeight = 0 ;
604+ } else {
605+ mStatusBarHeight = mBaseStatusBarRotatedHeight ;
606+ }
607+ return ;
608+ }
609+
610+ // No cutout
611+ if (isPortrait ) {
612+ mStatusBarHeight = mBaseStatusBarHeight ;
613+ } else {
614+ mStatusBarHeight = mBaseStatusBarRotatedHeight ;
615+ }
616+ }
617+
618+ /**
619+ * Update of touch X coordinate
620+ *
621+ * @param isHideNavigationBar If true, the navigation bar is hidden
622+ * @param windowLeftOffset Left side offset of device display
623+ */
624+ private void updateTouchXOffset (boolean isHideNavigationBar , int windowLeftOffset ) {
625+ final boolean noBottomCutout = mSafeInsetRect .bottom == 0 ;
626+ if (noBottomCutout ) {
627+ // touch X offset(navigation bar is displayed and it is on the left side of the device)
628+ mTouchXOffset = !isHideNavigationBar && windowLeftOffset > 0 ? mBaseNavigationBarRotatedHeight : 0 ;
629+ } else {
630+ mTouchXOffset = windowLeftOffset ;
631+ }
632+ }
633+
561634 /**
562635 * Update offset of NavigationBar.
563636 *
@@ -1327,7 +1400,7 @@ private int getXByTouch() {
13271400 * @return FloatingViewのY座標
13281401 */
13291402 private int getYByTouch () {
1330- return (int ) (mMetrics .heightPixels + mNavigationBarVerticalOffset - (mScreenTouchY - mLocalTouchY + getHeight ()));
1403+ return (int ) (mMetrics .heightPixels + mNavigationBarVerticalOffset - (mScreenTouchY - mLocalTouchY + getHeight () - mTouchYOffset ));
13311404 }
13321405
13331406 /**
@@ -1362,6 +1435,15 @@ int getState() {
13621435 return mAnimationHandler .getState ();
13631436 }
13641437
1438+ /**
1439+ * Set the cutout's safe inset area
1440+ *
1441+ * @param safeInsetRect {@link FloatingViewManager#setSafeInsetRect(Rect)}
1442+ */
1443+ void setSafeInsetRect (Rect safeInsetRect ) {
1444+ mSafeInsetRect .set (safeInsetRect );
1445+ }
1446+
13651447 /**
13661448 * アニメーションの制御を行うハンドラです。
13671449 */
@@ -1520,7 +1602,7 @@ else if (mState == FloatingView.STATE_INTERSECTING) {
15201602 * アニメーション時間から求められる位置を計算します。
15211603 *
15221604 * @param timeRate 時間比率
1523- * @return ベースとなる係数(0.0から1.0+ α)
1605+ * @return ベースとなる係数(0.0から1.0 + α)
15241606 */
15251607 private static float calcAnimationPosition (float timeRate ) {
15261608 final float position ;
0 commit comments