Add a scrim to taskbar for bubbles expanded state
When bubbles are expanded a scrim is shown on top of everything. Taskbar is layered above bubbles but we still need the scrim to show on top of it. This CL adds the ability to show a scrim on taskbar. The scrim is a view in the taskbar drag layer and is placed between the taskbar and the nav buttons so that it can block touches / scrim the taskbar but still allow the nav buttons to be visible and touchable. Add interpolators for alpha matching what bubbles is using. Test: manual 1 - expand bubbles while taskbar is visible => observe scrim - open manage menu => observe darker scrim 2 - check that taps on scrim collapse manage menu or stack 3 - check there isn't a scrim while taskbar is stashed and bubbles / manage menu are open 4 - check that three button nav works while bubbles are expanded Bug: 197139718 Change-Id: I94c4ecd07f81b2bad55c38525d60f493d3c1f9d8
This commit is contained in:
parent
273aa1c7af
commit
5fdf2d08fc
|
@ -30,6 +30,11 @@
|
|||
android:layout_gravity="bottom"
|
||||
android:clipChildren="false" />
|
||||
|
||||
<com.android.launcher3.taskbar.TaskbarScrimView
|
||||
android:id="@+id/taskbar_scrim"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/navbuttons_view"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -124,6 +124,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
|||
mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
|
||||
R.layout.taskbar, null, false);
|
||||
TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
|
||||
TaskbarScrimView taskbarScrimView = mDragLayer.findViewById(R.id.taskbar_scrim);
|
||||
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
|
||||
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
|
||||
|
||||
|
@ -144,6 +145,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
|||
R.color.popup_color_primary_light),
|
||||
new TaskbarDragLayerController(this, mDragLayer),
|
||||
new TaskbarViewController(this, taskbarView),
|
||||
new TaskbarScrimViewController(this, taskbarScrimView),
|
||||
new TaskbarUnfoldAnimationController(unfoldTransitionProgressProvider,
|
||||
mWindowManager),
|
||||
new TaskbarKeyguardController(this),
|
||||
|
@ -322,6 +324,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
|||
mControllers.navbarButtonsViewController.isRecentsDisabled());
|
||||
mControllers.taskbarKeyguardController.updateStateForSysuiFlags(systemUiStateFlags);
|
||||
mControllers.taskbarStashController.updateStateForSysuiFlags(systemUiStateFlags);
|
||||
mControllers.taskbarScrimViewController.updateStateForSysuiFlags(systemUiStateFlags);
|
||||
}
|
||||
|
||||
public void onRotationProposal(int rotation, boolean isValid) {
|
||||
|
|
|
@ -30,6 +30,7 @@ public class TaskbarControllers {
|
|||
public final NavbarButtonsViewController navbarButtonsViewController;
|
||||
public final RotationButtonController rotationButtonController;
|
||||
public final TaskbarDragLayerController taskbarDragLayerController;
|
||||
public final TaskbarScrimViewController taskbarScrimViewController;
|
||||
public final TaskbarViewController taskbarViewController;
|
||||
public final TaskbarUnfoldAnimationController taskbarUnfoldAnimationController;
|
||||
public final TaskbarKeyguardController taskbarKeyguardController;
|
||||
|
@ -47,6 +48,7 @@ public class TaskbarControllers {
|
|||
RotationButtonController rotationButtonController,
|
||||
TaskbarDragLayerController taskbarDragLayerController,
|
||||
TaskbarViewController taskbarViewController,
|
||||
TaskbarScrimViewController taskbarScrimViewController,
|
||||
TaskbarUnfoldAnimationController taskbarUnfoldAnimationController,
|
||||
TaskbarKeyguardController taskbarKeyguardController,
|
||||
StashedHandleViewController stashedHandleViewController,
|
||||
|
@ -59,6 +61,7 @@ public class TaskbarControllers {
|
|||
this.rotationButtonController = rotationButtonController;
|
||||
this.taskbarDragLayerController = taskbarDragLayerController;
|
||||
this.taskbarViewController = taskbarViewController;
|
||||
this.taskbarScrimViewController = taskbarScrimViewController;
|
||||
this.taskbarUnfoldAnimationController = taskbarUnfoldAnimationController;
|
||||
this.taskbarKeyguardController = taskbarKeyguardController;
|
||||
this.stashedHandleViewController = stashedHandleViewController;
|
||||
|
@ -78,6 +81,7 @@ public class TaskbarControllers {
|
|||
}
|
||||
taskbarDragLayerController.init(this);
|
||||
taskbarViewController.init(this);
|
||||
taskbarScrimViewController.init(this);
|
||||
taskbarUnfoldAnimationController.init(this);
|
||||
taskbarKeyguardController.init(navbarButtonsViewController);
|
||||
stashedHandleViewController.init(this);
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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.taskbar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* View that handles scrimming the taskbar and the inverted corners it draws. The scrim is used
|
||||
* when bubbles is expanded.
|
||||
*/
|
||||
public class TaskbarScrimView extends View {
|
||||
private final Paint mTaskbarScrimPaint;
|
||||
private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath;
|
||||
|
||||
private boolean mShowScrim;
|
||||
private float mLeftCornerRadius, mRightCornerRadius;
|
||||
private float mBackgroundHeight;
|
||||
|
||||
public TaskbarScrimView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TaskbarScrimView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
mTaskbarScrimPaint = new Paint();
|
||||
mTaskbarScrimPaint.setColor(getResources().getColor(android.R.color.system_neutral1_1000));
|
||||
mTaskbarScrimPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
|
||||
mTaskbarScrimPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
mInvertedLeftCornerPath = new Path();
|
||||
mInvertedRightCornerPath = new Path();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
if (mShowScrim) {
|
||||
canvas.save();
|
||||
canvas.translate(0, canvas.getHeight() - mBackgroundHeight);
|
||||
|
||||
// Scrim the taskbar itself.
|
||||
canvas.drawRect(0, 0, canvas.getWidth(), mBackgroundHeight, mTaskbarScrimPaint);
|
||||
|
||||
// Scrim the inverted rounded corners above the taskbar.
|
||||
canvas.translate(0, -mLeftCornerRadius);
|
||||
canvas.drawPath(mInvertedLeftCornerPath, mTaskbarScrimPaint);
|
||||
canvas.translate(0, mLeftCornerRadius);
|
||||
canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius);
|
||||
canvas.drawPath(mInvertedRightCornerPath, mTaskbarScrimPaint);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the height of the taskbar background.
|
||||
* @param height the height of the background.
|
||||
*/
|
||||
protected void setBackgroundHeight(float height) {
|
||||
mBackgroundHeight = height;
|
||||
if (mShowScrim) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the alpha of the taskbar scrim.
|
||||
* @param alpha the alpha of the scrim.
|
||||
*/
|
||||
protected void setScrimAlpha(float alpha) {
|
||||
mShowScrim = alpha > 0f;
|
||||
mTaskbarScrimPaint.setAlpha((int) (alpha * 255));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the radius of the left and right corners above the taskbar.
|
||||
* @param leftCornerRadius the radius of the left corner.
|
||||
* @param rightCornerRadius the radius of the right corner.
|
||||
*/
|
||||
protected void setCornerSizes(float leftCornerRadius, float rightCornerRadius) {
|
||||
mLeftCornerRadius = leftCornerRadius;
|
||||
mRightCornerRadius = rightCornerRadius;
|
||||
|
||||
Path square = new Path();
|
||||
square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW);
|
||||
Path circle = new Path();
|
||||
circle.addCircle(mLeftCornerRadius, 0, mLeftCornerRadius, Path.Direction.CW);
|
||||
mInvertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE);
|
||||
square.reset();
|
||||
square.addRect(0, 0, mRightCornerRadius, mRightCornerRadius, Path.Direction.CW);
|
||||
circle.reset();
|
||||
circle.addCircle(0, 0, mRightCornerRadius, Path.Direction.CW);
|
||||
mInvertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE);
|
||||
|
||||
if (mShowScrim) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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.taskbar;
|
||||
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
|
||||
/**
|
||||
* Handles properties/data collection, and passes the results to {@link TaskbarScrimView} to render.
|
||||
*/
|
||||
public class TaskbarScrimViewController {
|
||||
|
||||
private static final float SCRIM_ALPHA = 0.6f;
|
||||
|
||||
private static final Interpolator SCRIM_ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
|
||||
private static final Interpolator SCRIM_ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
|
||||
|
||||
private final TaskbarActivityContext mActivity;
|
||||
private final TaskbarScrimView mScrimView;
|
||||
|
||||
// Alpha property for the scrim.
|
||||
private final AnimatedFloat mScrimAlpha = new AnimatedFloat(this::updateScrimAlpha);
|
||||
|
||||
// Initialized in init.
|
||||
private TaskbarControllers mControllers;
|
||||
|
||||
public TaskbarScrimViewController(TaskbarActivityContext activity, TaskbarScrimView scrimView) {
|
||||
mActivity = activity;
|
||||
mScrimView = scrimView;
|
||||
mScrimView.setCornerSizes(mActivity.getLeftCornerRadius(),
|
||||
mActivity.getRightCornerRadius());
|
||||
mScrimView.setBackgroundHeight(mActivity.getDeviceProfile().taskbarSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the controller
|
||||
*/
|
||||
public void init(TaskbarControllers controllers) {
|
||||
mControllers = controllers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the scrim state based on the flags.
|
||||
*/
|
||||
public void updateStateForSysuiFlags(int stateFlags) {
|
||||
final boolean bubblesExpanded = (stateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
|
||||
final boolean manageMenuExpanded =
|
||||
(stateFlags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
|
||||
final boolean showScrim = !mControllers.navbarButtonsViewController.isImeVisible()
|
||||
&& bubblesExpanded && mControllers.taskbarStashController.isInAppAndNotStashed();
|
||||
final float scrimAlpha = manageMenuExpanded
|
||||
// When manage menu shows there's the first scrim and second scrim so figure out
|
||||
// what the total transparency would be.
|
||||
? (SCRIM_ALPHA + (SCRIM_ALPHA * (1 - SCRIM_ALPHA)))
|
||||
: showScrim ? SCRIM_ALPHA : 0;
|
||||
showScrim(showScrim, scrimAlpha);
|
||||
}
|
||||
|
||||
private void showScrim(boolean showScrim, float alpha) {
|
||||
mScrimView.setOnClickListener(showScrim ? (view) -> onClick() : null);
|
||||
mScrimView.setClickable(showScrim);
|
||||
ObjectAnimator anim = mScrimAlpha.animateToValue(showScrim ? alpha : 0);
|
||||
anim.setInterpolator(showScrim ? SCRIM_ALPHA_IN : SCRIM_ALPHA_OUT);
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private void updateScrimAlpha() {
|
||||
mScrimView.setScrimAlpha(mScrimAlpha.value);
|
||||
}
|
||||
|
||||
private void onClick() {
|
||||
SystemUiProxy.INSTANCE.get(mActivity).onBackPressed();
|
||||
}
|
||||
}
|
|
@ -198,6 +198,14 @@ public class TaskbarStashController {
|
|||
return (flags & flagMask) != 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the taskbar is currently visible and in an app.
|
||||
*/
|
||||
public boolean isInAppAndNotStashed() {
|
||||
return !mIsStashed && (mState & FLAG_IN_APP) != 0;
|
||||
}
|
||||
|
||||
public int getContentHeight() {
|
||||
return isStashed() ? mStashedHeight : mUnstashedHeight;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue