From 0abb36f6920733f813e22ad984bb7d48f0924698 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 23 Jun 2015 10:53:59 -0700 Subject: [PATCH] Fixing overscroll effect when the navigation bar is opaque The navigation bar is opaque on mobile devices in landscape mode. Launcher should ignore the right insets and draw the edge effect appropriately. Also draw the black bar under the navigation bar, just in case we assume it to be opaque, but it was not actually opaque. Bug: 18526657 Change-Id: I1d49dcb82b8a5ee25009bc738cd9b8c0c5c88263 --- .../launcher3/InvariantDeviceProfile.java | 9 ++++++- .../android/launcher3/LauncherRootView.java | 25 +++++++++++++++++++ src/com/android/launcher3/PagedView.java | 12 ++++++--- src/com/android/launcher3/Workspace.java | 1 + 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index ae204c40c3..20a77b5af6 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -17,6 +17,7 @@ package com.android.launcher3; import android.annotation.TargetApi; +import android.app.ActivityManager; import android.content.Context; import android.graphics.Point; import android.os.Build; @@ -84,6 +85,9 @@ public class InvariantDeviceProfile { DeviceProfile landscapeProfile; DeviceProfile portraitProfile; + // On Marshmallow the status bar is no longer opaque, when drawn on the right. + public boolean isRightInsetOpaque; + InvariantDeviceProfile() { } @@ -116,7 +120,7 @@ public class InvariantDeviceProfile { defaultLayoutId = dlId; } - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) + @TargetApi(Build.VERSION_CODES.M) InvariantDeviceProfile(Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); @@ -167,6 +171,9 @@ public class InvariantDeviceProfile { largeSide, smallSide, true /* isLandscape */); portraitProfile = new DeviceProfile(context, this, smallestSize, largestSize, smallSide, largeSide, false /* isLandscape */); + + isRightInsetOpaque = !Utilities.ATLEAST_MARSHMALLOW || + context.getSystemService(ActivityManager.class).isLowRamDevice(); } ArrayList getPredefinedDeviceProfiles() { diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index e8c11c48bd..1c6ca87134 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -1,17 +1,42 @@ package com.android.launcher3; import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; public class LauncherRootView extends InsettableFrameLayout { + + private final Paint mOpaquePaint; + private boolean mDrawRightInsetBar; + public LauncherRootView(Context context, AttributeSet attrs) { super(context, attrs); + + mOpaquePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mOpaquePaint.setColor(Color.BLACK); + mOpaquePaint.setStyle(Paint.Style.FILL); } @Override protected boolean fitSystemWindows(Rect insets) { setInsets(insets); + mDrawRightInsetBar = mInsets.right > 0 && LauncherAppState + .getInstance().getInvariantDeviceProfile().isRightInsetOpaque; + return true; // I'll take it from here } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + + // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque. + if (mDrawRightInsetBar) { + int width = getWidth(); + canvas.drawRect(width - mInsets.right, 0, width, getHeight(), mOpaquePaint); + } + } } \ No newline at end of file diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 05f0a05534..2579ea363c 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -202,6 +202,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected final Rect mInsets = new Rect(); protected final boolean mIsRtl; + // When set to true, full screen content and overscroll effect is shited inside by right inset. + protected boolean mIgnoreRightInset; + // Edge effect private final LauncherEdgeEffect mEdgeGlowLeft = new LauncherEdgeEffect(); private final LauncherEdgeEffect mEdgeGlowRight = new LauncherEdgeEffect(); @@ -819,7 +822,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc childWidthMode = MeasureSpec.EXACTLY; childHeightMode = MeasureSpec.EXACTLY; - childWidth = getViewportWidth() - mInsets.left - mInsets.right; + childWidth = getViewportWidth() - mInsets.left + - (mIgnoreRightInset ? mInsets.right : 0); childHeight = getViewportHeight(); } if (referenceChildWidth == 0) { @@ -1177,8 +1181,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc canvas.rotate(90); getEdgeVerticalPostion(sTmpIntPoint); - canvas.translate(sTmpIntPoint[0] - display.top, -display.width()); - mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], display.width()); + + int width = mIgnoreRightInset ? (display.width() - mInsets.right) : display.width(); + canvas.translate(sTmpIntPoint[0] - display.top, -width); + mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], width); if (mEdgeGlowRight.draw(canvas)) { postInvalidateOnAnimation(); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 0fdc742b60..362e8046dc 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -454,6 +454,7 @@ public class Workspace extends PagedView setWallpaperDimension(); setEdgeGlowColor(getResources().getColor(R.color.workspace_edge_effect_color)); + mIgnoreRightInset = app.getInvariantDeviceProfile().isRightInsetOpaque; } private void setupLayoutTransition() {