Remove color extraction from popup arrow, add shadows.

Bug: 175329686
Bug: 187014675
Test: manual

Change-Id: I84a3f23b7a9ceef004a2b1b66e5f8a10585bd113
This commit is contained in:
Jon Miranda 2021-05-07 15:29:54 -07:00
parent d30f4ce528
commit 35c5477d5c
16 changed files with 25 additions and 208 deletions

View File

@ -15,7 +15,7 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/popupColorSecondary" />
<solid android:color="?attr/popupColorPrimary" />
<corners android:radius="8dp" />
<size android:height="16dp" />
</shape>

View File

@ -15,6 +15,6 @@
limitations under the License.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="?attr/popupColorSecondary"/>
<foreground android:drawable="?attr/popupColorSecondary"/>
<background android:drawable="?attr/popupColorPrimary"/>
<foreground android:drawable="?attr/popupColorPrimary"/>
</adaptive-icon>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/popupColorSecondary"/>
<corners android:radius="@dimen/popup_single_item_radius" />
</shape>

View File

@ -19,6 +19,7 @@
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/bg_popup_item_width"
android:layout_height="@dimen/bg_popup_item_height"
android:elevation="@dimen/deep_shortcuts_elevation"
android:background="@drawable/middle_item_primary"
android:theme="@style/PopupItem" >

View File

@ -20,6 +20,5 @@
android:layout_height="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
android:elevation="@dimen/deep_shortcuts_elevation"
android:importantForAccessibility="yes"
android:orientation="vertical" />

View File

@ -21,7 +21,6 @@
android:layout_height="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
android:elevation="@dimen/deep_shortcuts_elevation"
android:orientation="vertical">
<LinearLayout
android:id="@+id/notification_container"
@ -29,5 +28,6 @@
android:layout_height="wrap_content"
android:visibility="gone"
android:background="?attr/popupColorPrimary"
android:elevation="@dimen/deep_shortcuts_elevation"
android:orientation="vertical"/>
</com.android.launcher3.popup.PopupContainerWithArrow>

View File

@ -19,6 +19,7 @@
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/bg_popup_item_width"
android:layout_height="@dimen/bg_popup_item_height"
android:elevation="@dimen/deep_shortcuts_elevation"
android:background="@drawable/middle_item_primary"
android:theme="@style/PopupItem" >

View File

@ -21,7 +21,8 @@
android:layout_height="@dimen/system_shortcut_header_height"
android:orientation="horizontal"
android:gravity="end|center_vertical"
android:background="@drawable/single_item_secondary"
android:background="@drawable/single_item_primary"
android:elevation="@dimen/deep_shortcuts_elevation"
android:clipToPadding="true">
<Space android:layout_width="0dp"

View File

@ -17,8 +17,7 @@
*/
-->
<resources>
<color name="popup_color_neutral_light">@android:color/system_neutral1_0</color>
<color name="popup_color_primary_light">@android:color/system_neutral1_50</color>
<color name="popup_color_primary_light">@android:color/system_neutral1_0</color>
<color name="popup_color_secondary_light">@android:color/system_neutral2_100</color>
<color name="popup_color_tertiary_light">@android:color/system_neutral2_300</color>
<color name="popup_color_neutral_dark">@android:color/system_neutral1_1000</color>

View File

@ -21,7 +21,6 @@
<attr name="allAppsScrimColor" format="color" />
<attr name="allAppsNavBarScrimColor" format="color" />
<attr name="allAppsTheme" format="reference" />
<attr name="popupColorNeutral" format="color" />
<attr name="popupColorPrimary" format="color" />
<attr name="popupColorSecondary" format="color" />
<attr name="popupColorTertiary" format="color" />

View File

@ -41,7 +41,6 @@
<color name="gesture_tutorial_action_button_label_color">#FF000000</color>
<color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
<color name="popup_color_neutral_light">#FFF</color>
<color name="popup_color_primary_light">#FFF</color>
<color name="popup_color_secondary_light">#F1F3F4</color>
<color name="popup_color_tertiary_light">#E0E0E0</color> <!-- Gray 300 -->

View File

@ -202,7 +202,8 @@
<dimen name="pending_widget_elevation">2dp</dimen>
<!-- Deep shortcuts -->
<dimen name="deep_shortcuts_elevation">0dp</dimen>
<dimen name="deep_shortcuts_elevation">2dp</dimen>
<dimen name="bg_popup_padding">2dp</dimen>
<dimen name="bg_popup_item_width">216dp</dimen>
<dimen name="bg_popup_item_height">56dp</dimen>
<dimen name="pre_drag_view_scale">6dp</dimen>

View File

@ -34,7 +34,6 @@
<item name="allAppsScrimColor">?android:attr/colorBackgroundFloating</item>
<item name="allAppsNavBarScrimColor">#66FFFFFF</item>
<item name="allAppsTheme">@style/AllAppsTheme</item>
<item name="popupColorNeutral">@color/popup_color_neutral_light</item>
<item name="popupColorPrimary">@color/popup_color_primary_light</item>
<item name="popupColorSecondary">@color/popup_color_secondary_light</item>
<item name="popupColorTertiary">@color/popup_color_tertiary_light</item>
@ -98,7 +97,6 @@
<item name="allAppsScrimColor">?android:attr/colorBackgroundFloating</item>
<item name="allAppsNavBarScrimColor">#80000000</item>
<item name="allAppsTheme">@style/AllAppsTheme.Dark</item>
<item name="popupColorNeutral">@color/popup_color_neutral_dark</item>
<item name="popupColorPrimary">@color/popup_color_primary_dark</item>
<item name="popupColorSecondary">@color/popup_color_secondary_dark</item>
<item name="popupColorTertiary">@color/popup_color_tertiary_dark</item>

View File

@ -92,10 +92,6 @@ public class NotificationItemView {
});
}
public void updateBackgroundColor(int color) {
mMainView.updateBackgroundColor(color);
}
public void addGutter() {
if (mGutter == null) {
mGutter = mPopupContainer.inflateAndAdd(R.layout.notification_gutter, mRootView);

View File

@ -19,21 +19,15 @@ package com.android.launcher3.popup;
import static com.android.launcher3.anim.Interpolators.ACCELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.util.Pair;
@ -41,32 +35,25 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.widget.LocalColorExtractor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
/**
* A container for shortcuts to deep links and notifications associated with an app.
@ -89,9 +76,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
private static final int CLOSE_CHILD_FADE_DURATION = 140;
// +1 for system shortcut view
private static final int MAX_NUM_CHILDREN = MAX_SHORTCUTS + 1;
private final Rect mTempRect = new Rect();
protected final LayoutInflater mInflater;
@ -120,13 +104,8 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
private Runnable mOnCloseCallback = () -> { };
// The rect string of the view that the arrow is attached to, in screen reference frame.
private String mArrowColorRectString;
private int mArrowColor;
private final int[] mColors;
private final HashMap<String, View> mViewForRect = new HashMap<>();
@Nullable private LocalColorExtractor mColorExtractor;
private final float mElevation;
private final int mBackgroundColor;
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@ -134,13 +113,9 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
mOutlineRadius = Themes.getDialogCornerRadius(context);
mLauncher = BaseDraggingActivity.fromContext(context);
mIsRtl = Utilities.isRtl(getResources());
setClipToOutline(true);
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mOutlineRadius);
}
});
mBackgroundColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
mElevation = getResources().getDimension(R.dimen.deep_shortcuts_elevation);
// Initialize arrow view
final Resources resources = getResources();
@ -156,33 +131,14 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
int smallerRadius = resources.getDimensionPixelSize(R.dimen.popup_smaller_radius);
mRoundedTop = new GradientDrawable();
mRoundedTop.setColor(mBackgroundColor);
mRoundedTop.setCornerRadii(new float[] { mOutlineRadius, mOutlineRadius, mOutlineRadius,
mOutlineRadius, smallerRadius, smallerRadius, smallerRadius, smallerRadius});
mRoundedBottom = new GradientDrawable();
mRoundedBottom.setColor(mBackgroundColor);
mRoundedBottom.setCornerRadii(new float[] { smallerRadius, smallerRadius, smallerRadius,
smallerRadius, mOutlineRadius, mOutlineRadius, mOutlineRadius, mOutlineRadius});
boolean isAboveAnotherSurface = getTopOpenViewWithType(mLauncher, TYPE_FOLDER) != null
|| mLauncher.getStateManager().getState() == LauncherState.ALL_APPS;
if (isAboveAnotherSurface) {
mColors = new int[] { Themes.getAttrColor(context, R.attr.popupColorNeutral) };
} else {
int primaryColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
int secondaryColor = Themes.getAttrColor(context, R.attr.popupColorSecondary);
ArgbEvaluator argb = new ArgbEvaluator();
mColors = new int[MAX_NUM_CHILDREN];
// Interpolate between the two colors, exclusive.
float step = 1f / (MAX_NUM_CHILDREN + 1);
for (int i = 0; i < mColors.length; ++i) {
mColors[i] =
(int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor);
}
if (supportsColorExtraction()) {
setupColorExtraction();
}
}
}
public ArrowPopup(Context context, AttributeSet attrs) {
@ -240,7 +196,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
int numVisibleShortcut = 0;
View lastView = null;
int numVisibleChild = 0;
for (int i = 0; i < count; i++) {
View view = getChildAt(i);
boolean isShortcut = view instanceof DeepShortcutView;
@ -267,35 +222,11 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
numVisibleShortcut++;
}
}
int color = mColors[numVisibleChild % mColors.length];
setChildColor(view, color);
// Arrow color matches the first child or the last child.
if (!mIsAboveIcon && numVisibleChild == 0) {
mArrowColor = color;
} else if (mIsAboveIcon) {
mArrowColor = color;
}
numVisibleChild++;
}
}
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
/**
* Sets the background color of the child.
*/
protected void setChildColor(View view, int color) {
Drawable bg = view.getBackground();
if (bg instanceof GradientDrawable) {
((GradientDrawable) bg.mutate()).setColor(color);
} else if (bg instanceof ColorDrawable) {
((ColorDrawable) bg.mutate()).setColor(color);
}
}
/**
* Shows the popup at the desired location, optionally reversing the children.
* @param viewsToFlip number of views from the top to to flip in case of reverse order
@ -366,23 +297,18 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
// so we centered it instead. In that case we don't want to showDefaultOptions the arrow.
mArrow.setVisibility(INVISIBLE);
} else {
updateArrowColor();
}
mArrow.setPivotX(mArrowWidth / 2.0f);
mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
}
private void updateArrowColor() {
if (!Gravity.isVertical(mGravity)) {
mArrow.setBackground(new RoundedArrowDrawable(
mArrowWidth, mArrowHeight, mArrowPointRadius,
mOutlineRadius, getMeasuredWidth(), getMeasuredHeight(),
mArrowOffsetHorizontal, -mArrowOffsetVertical,
!mIsAboveIcon, mIsLeftAligned,
mArrowColor));
mArrow.setElevation(getElevation());
mBackgroundColor));
// TODO: Remove elevation when arrow is above as it casts a shadow on the container
mArrow.setElevation(mIsAboveIcon ? mElevation : 0);
}
mArrow.setPivotX(mArrowWidth / 2.0f);
mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
}
/**
@ -434,7 +360,7 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
}
int childMargins = (numVisibleChildren - 1) * mMargin;
int height = getMeasuredHeight() + extraVerticalSpace + childMargins;
int width = getMeasuredWidth();
int width = getMeasuredWidth() + getPaddingLeft() + getPaddingRight();
getTargetObjectLocation(mTempRect);
InsettableFrameLayout dragLayer = getPopupContainer();
@ -667,19 +593,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
getPopupContainer().removeView(this);
getPopupContainer().removeView(mArrow);
mOnCloseCallback.run();
mArrowColorRectString = null;
mViewForRect.clear();
if (mColorExtractor != null) {
mColorExtractor.removeLocations();
mColorExtractor.setListener(null);
}
}
/**
* Returns whether color extraction is supported.
*/
public boolean supportsColorExtraction() {
return Utilities.ATLEAST_S;
}
/**
@ -689,68 +602,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
mOnCloseCallback = callback;
}
private void setupColorExtraction() {
Workspace workspace = mLauncher.findViewById(R.id.workspace);
if (workspace == null) {
return;
}
mColorExtractor = LocalColorExtractor.newInstance(mLauncher);
mColorExtractor.setListener((rect, extractedColors) -> {
String rectString = rect.toShortString();
View v = mViewForRect.get(rectString);
if (v != null) {
int newColor = extractedColors.get(mColorExtractionIndex);
setChildColor(v, newColor);
if (rectString.equals(mArrowColorRectString)) {
mArrowColor = newColor;
updateArrowColor();
}
}
});
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
ArrayList<RectF> locations = new ArrayList<>();
Rect r = new Rect();
int count = getChildCount();
int numVisibleChild = 0;
for (int i = 0; i < count; i++) {
View view = getChildAt(i);
if (view.getVisibility() == VISIBLE) {
RectF rf = new RectF();
mColorExtractor.getExtractedRectForView(Launcher.getLauncher(getContext()),
workspace.getCurrentPage(), view, rf);
if (rf.isEmpty()) {
numVisibleChild++;
continue;
}
locations.add(rf);
String rectString = rf.toShortString();
mViewForRect.put(rectString, view);
// Arrow color matches the first child or the last child.
if (!mIsAboveIcon && numVisibleChild == 0) {
mArrowColorRectString = rectString;
} else if (mIsAboveIcon) {
mArrowColorRectString = rectString;
}
numVisibleChild++;
}
}
mColorExtractor.addLocation(locations);
return false;
}
});
}
protected BaseDragLayer getPopupContainer() {
return mLauncher.getDragLayer();
}

View File

@ -172,14 +172,6 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
return false;
}
@Override
protected void setChildColor(View v, int color) {
super.setChildColor(v, color);
if (v.getId() == R.id.notification_container && mNotificationItemView != null) {
mNotificationItemView.updateBackgroundColor(color);
}
}
/**
* Returns true if we can show the container.
*/