Chaniging all-apps scrim

> Converting the scrim to View, to better avoid overdraw
> Overview and Spring loaded state have different scrim alpha
> When going from overview to all-apps, there is a color scrim drawn over the overview panel.
  The slef color is merged with this color to prevent overdraw, and the remaining screen is drawn
  with a cut-out round rect path

Bug: 79111591
Change-Id: I26801fde13dd6adb4b06110bbe8087e35cc31847
This commit is contained in:
Sunny Goyal
2018-05-04 13:19:29 -07:00
parent 729020d186
commit 927447e71d
18 changed files with 390 additions and 240 deletions

View File

@@ -1,154 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.uioverrides;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v4.graphics.ColorUtils;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.graphics.ViewScrim;
import com.android.launcher3.util.Themes;
/**
* Scrim used for all-apps and shelf in Overview
* In transposed layout, it behaves as a simple color scrim.
* In portrait layout, it draws a rounded rect such that
* From normal state to overview state, the shelf just fades in and does not move
* From overview state to all-apps state the self moves up and fades in to cover the screen
*/
public class AllAppsScrim extends ViewScrim<AllAppsContainerView> {
private static final int THRESHOLD_ALPHA_DARK = 102;
private static final int THRESHOLD_ALPHA_LIGHT = 46;
private final Launcher mLauncher;
private final int mEndColor;
private int mProgressColor;
// In transposed layout, we simply draw a flat color.
private boolean mDrawingFlatColor;
private final Paint mVerticalPaint;
private float mVerticalProgress;
private final int mEndAlpha;
private final int mThresholdAlpha;
private final float mRadius;
private final float mTopPadding;
// Max vertical progress after which the scrim stops moving.
private float mMoveThreshold;
// Minimum visible size of the scrim.
private int mMinSize;
private float mDrawFactor = 0;
public AllAppsScrim(AllAppsContainerView view) {
super(view);
mLauncher = Launcher.getLauncher(view.getContext());
mEndColor = Themes.getAttrColor(mLauncher, R.attr.allAppsScrimColor);
mProgressColor = mEndColor;
mEndAlpha = Color.alpha(mEndColor);
mThresholdAlpha = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark)
? THRESHOLD_ALPHA_DARK : THRESHOLD_ALPHA_LIGHT;
mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
mTopPadding = mLauncher.getResources().getDimension(R.dimen.shelf_surface_top_padding);
mVerticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mVerticalPaint.setColor(ColorUtils.setAlphaComponent(mEndColor, 255));
// Just assume the easiest UI for now, until we have the proper layout information.
mDrawingFlatColor = true;
}
@Override
protected void onProgressChanged() {
mProgressColor = ColorUtils.setAlphaComponent(mEndColor,
Math.round(DEACCEL_2.getInterpolation(mProgress) * Color.alpha(mEndColor)));
}
@Override
public void draw(Canvas canvas, int width, int height) {
if (mDrawingFlatColor) {
if (mProgress > 0) {
canvas.drawColor(mProgressColor);
}
return;
}
if (mVerticalPaint.getAlpha() == 0) {
return;
} else if (mDrawFactor <= 0) {
canvas.drawPaint(mVerticalPaint);
} else {
float top = (height - mMinSize) * mDrawFactor - mTopPadding;
canvas.drawRoundRect(0, top - mRadius, width, height + mRadius,
mRadius, mRadius, mVerticalPaint);
}
}
public void reInitUi() {
DeviceProfile dp = mLauncher.getDeviceProfile();
mDrawingFlatColor = dp.isVerticalBarLayout();
if (!mDrawingFlatColor) {
float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
onVerticalProgress(mVerticalProgress);
}
invalidate();
}
public void onVerticalProgress(float progress) {
mVerticalProgress = progress;
if (mDrawingFlatColor) {
return;
}
float drawFactor;
int alpha;
if (mVerticalProgress >= mMoveThreshold) {
drawFactor = 1;
alpha = mVerticalProgress >= 1 ? 0 : Math.round(mThresholdAlpha
* ACCEL_2.getInterpolation((1 - mVerticalProgress) / (1 - mMoveThreshold)));
} else if (mVerticalProgress <= 0) {
drawFactor = 0;
alpha = mEndAlpha;
} else {
drawFactor = mVerticalProgress / mMoveThreshold;
alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * drawFactor);
}
alpha = Utilities.boundToRange(alpha, 0, 255);
if (alpha != mVerticalPaint.getAlpha() || drawFactor != mDrawFactor) {
mVerticalPaint.setAlpha(alpha);
mDrawFactor = drawFactor;
invalidate();
}
}
}

View File

@@ -31,7 +31,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
*/
public class AllAppsState extends LauncherState {
private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY | FLAG_ALL_APPS_SCRIM;
private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY;
private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
@Override

View File

@@ -24,9 +24,8 @@ import com.android.quickstep.views.RecentsView;
*/
public class FastOverviewState extends OverviewState {
private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_DISABLE_RESTORE
| FLAG_DISABLE_INTERACTION | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON
| FLAG_DISABLE_ACCESSIBILITY;
private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
| FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
public FastOverviewState(int id) {
super(id, QuickScrubController.QUICK_SCRUB_START_DURATION, STATE_FLAGS);

View File

@@ -34,7 +34,7 @@ import com.android.quickstep.views.RecentsView;
*/
public class OverviewState extends LauncherState {
private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
| FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
public OverviewState(int id) {
@@ -100,6 +100,11 @@ public class OverviewState extends LauncherState {
}
}
@Override
public float getWorkspaceScrimAlpha(Launcher launcher) {
return 0.5f;
}
@Override
public float getVerticalProgress(Launcher launcher) {
if ((getVisibleElements(launcher) & ALL_APPS_HEADER_EXTRA) == 0) {

View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep.views;
import static android.support.v4.graphics.ColorUtils.compositeColors;
import static android.support.v4.graphics.ColorUtils.setAlphaComponent;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.Op;
import android.util.AttributeSet;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.OverviewState;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;
/**
* Scrim used for all-apps and shelf in Overview
* In transposed layout, it behaves as a simple color scrim.
* In portrait layout, it draws a rounded rect such that
* From normal state to overview state, the shelf just fades in and does not move
* From overview state to all-apps state the shelf moves up and fades in to cover the screen
*/
public class ShelfScrimView extends ScrimView {
private static final int THRESHOLD_ALPHA_DARK = 102;
private static final int THRESHOLD_ALPHA_LIGHT = 46;
private final Launcher mLauncher;
// In transposed layout, we simply draw a flat color.
private boolean mDrawingFlatColor;
// For shelf mode
private final int mEndAlpha;
private final int mThresholdAlpha;
private final float mRadius;
private final float mTopPadding;
private final float mMaxScrimAlpha;
private final Paint mPaint;
// Max vertical progress after which the scrim stops moving.
private float mMoveThreshold;
// Minimum visible size of the scrim.
private int mMinSize;
private float mScrimMoveFactor = 0;
private int mShelfColor;
private int mRemainingScreenColor;
private final Path mTempPath = new Path();
private final Path mRemainingScreenPath = new Path();
private boolean mRemainingScreenPathValid = false;
public ShelfScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
mLauncher = Launcher.getLauncher(context);
mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);
mEndAlpha = Color.alpha(mEndScrim);
mThresholdAlpha = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark)
? THRESHOLD_ALPHA_DARK : THRESHOLD_ALPHA_LIGHT;
mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
mTopPadding = mLauncher.getResources().getDimension(R.dimen.shelf_surface_top_padding);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// Just assume the easiest UI for now, until we have the proper layout information.
mDrawingFlatColor = true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mRemainingScreenPathValid = false;
}
@Override
public void reInitUi() {
DeviceProfile dp = mLauncher.getDeviceProfile();
mDrawingFlatColor = dp.isVerticalBarLayout();
if (!mDrawingFlatColor) {
float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
mRemainingScreenPathValid = false;
updateColors();
}
invalidate();
}
@Override
public void updateColors() {
super.updateColors();
if (mDrawingFlatColor) {
return;
}
if (mProgress >= mMoveThreshold) {
mScrimMoveFactor = 1;
if (mProgress >= 1) {
mShelfColor = 0;
} else {
int alpha = Math.round(mThresholdAlpha * ACCEL_2.getInterpolation(
(1 - mProgress) / (1 - mMoveThreshold)));
mShelfColor = setAlphaComponent(mEndScrim, alpha);
}
mRemainingScreenColor = 0;
} else if (mProgress <= 0) {
mScrimMoveFactor = 0;
mShelfColor = mCurrentFlatColor;
mRemainingScreenColor = 0;
} else {
mScrimMoveFactor = mProgress / mMoveThreshold;
mRemainingScreenColor = setAlphaComponent(mScrimColor,
Math.round((1 - mScrimMoveFactor) * mMaxScrimAlpha * 255));
// Merge the remainingScreenColor and shelfColor in one to avoid overdraw.
int alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * mScrimMoveFactor);
mShelfColor = compositeColors(setAlphaComponent(mEndScrim, alpha),
mRemainingScreenColor);
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mDrawingFlatColor) {
if (mCurrentFlatColor != 0) {
canvas.drawColor(mCurrentFlatColor);
}
return;
}
if (mShelfColor == 0) {
return;
} else if (mScrimMoveFactor <= 0) {
canvas.drawColor(mShelfColor);
return;
}
float minTop = getHeight() - mMinSize;
float top = minTop * mScrimMoveFactor - mTopPadding - mRadius;
// Draw the scrim over the remaining screen if needed.
if (mRemainingScreenColor != 0) {
if (!mRemainingScreenPathValid) {
mTempPath.reset();
// Using a arbitrary '+10' in the bottom to avoid any left-overs at the
// corners due to rounding issues.
mTempPath.addRoundRect(0, minTop, getWidth(), getHeight() + mRadius + 10,
mRadius, mRadius, Direction.CW);
mRemainingScreenPath.reset();
mRemainingScreenPath.addRect(0, 0, getWidth(), getHeight(), Direction.CW);
mRemainingScreenPath.op(mTempPath, Op.DIFFERENCE);
}
float offset = minTop - top;
canvas.translate(0, -offset);
mPaint.setColor(mRemainingScreenColor);
canvas.drawPath(mRemainingScreenPath, mPaint);
canvas.translate(0, offset);
}
mPaint.setColor(mShelfColor);
canvas.drawRoundRect(0, top, getWidth(), getHeight() + mRadius,
mRadius, mRadius, mPaint);
}
}