Folder polish - update color extraction, fix contrast issues.

- Also fixes open/close animation when items were not getting clipped
  due to folder not being measured yet.

Bug: 190210234
Bug: 190164147
Test: manual
Change-Id: I230c33d7e4e1871d8d702737c56c79ce46504b8f
Merged-In: I230c33d7e4e1871d8d702737c56c79ce46504b8f
This commit is contained in:
Jon Miranda 2021-06-11 11:21:51 -07:00 committed by Jonathan Miranda
parent d541300f0e
commit 5688010306
5 changed files with 27 additions and 131 deletions

View File

@ -16,7 +16,7 @@
** limitations under the License.
*/
-->
<resources>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<color name="popup_color_primary_light">@android:color/system_accent2_50</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>
@ -36,7 +36,8 @@
<color name="text_color_tertiary_dark">@android:color/system_neutral2_400</color>
<color name="wallpaper_popup_scrim">@android:color/system_neutral1_900</color>
<color name="folder_background_light" android:lstar="98">@android:color/system_neutral1_50</color>
<color name="folder_background_dark" android:lstar="30">@android:color/system_neutral2_800</color>
<color name="folder_dot_color">@android:color/system_accent2_50</color>
</resources>

View File

@ -59,6 +59,9 @@
<color name="folder_hint_text_color_light">#FFF</color>
<color name="folder_hint_text_color_dark">#FF000000</color>
<color name="folder_background_light">#FFFFFF</color>
<color name="folder_background_dark">#FF3C4043</color>
<color name="folder_dot_color">?attr/colorPrimary</color>
<color name="text_color_primary_dark">#FFFFFFFF</color>

View File

@ -48,9 +48,9 @@
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
<item name="folderDotColor">@color/folder_dot_color</item>
<item name="folderFillColor">?android:attr/colorBackgroundFloating</item>
<item name="folderFillColor">@color/folder_background_light</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
<item name="folderTextColor">?android:attr/textColorPrimary</item>
<item name="folderTextColor">@color/workspace_text_color_dark</item>
<item name="isFolderDarkText">true</item>
<item name="folderHintColor">@color/folder_hint_text_color_dark</item>
<item name="loadingIconColor">#CCFFFFFF</item>
@ -71,10 +71,10 @@
</style>
<style name="LauncherTheme.DarkMainColor" parent="@style/LauncherTheme">
<item name="folderFillColor">?android:attr/colorBackgroundFloating</item>
<item name="folderTextColor">?attr/workspaceTextColor</item>
<item name="isFolderDarkText">?attr/isWorkspaceDarkText</item>
<item name="folderHintColor">@color/folder_hint_text_color_dark</item>
<item name="folderFillColor">@color/folder_background_dark</item>
<item name="folderTextColor">@color/workspace_text_color_light</item>
<item name="isFolderDarkText">false</item>
<item name="folderHintColor">@color/folder_hint_text_color_light</item>
<item name="disabledIconAlpha">.254</item>
</style>
@ -87,9 +87,9 @@
<item name="isWorkspaceDarkText">true</item>
<item name="workspaceStatusBarScrim">@null</item>
<item name="folderDotColor">@color/folder_dot_color</item>
<item name="folderFillColor">?android:attr/colorBackgroundFloating</item>
<item name="folderFillColor">@color/folder_background_light</item>
<item name="folderIconBorderColor">#FF80868B</item>
<item name="folderTextColor">?attr/workspaceTextColor</item>
<item name="folderTextColor">@color/workspace_text_color_dark</item>
<item name="isFolderDarkText">true</item>
<item name="folderHintColor">@color/folder_hint_text_color_dark</item>
</style>
@ -109,9 +109,9 @@
<item name="popupColorTertiary">@color/popup_color_tertiary_dark</item>
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="folderDotColor">@color/folder_dot_color</item>
<item name="folderFillColor">?android:attr/colorBackgroundFloating</item>
<item name="folderFillColor">@color/folder_background_dark</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
<item name="folderTextColor">?android:attr/textColorPrimary</item>
<item name="folderTextColor">@color/workspace_text_color_light</item>
<item name="isFolderDarkText">false</item>
<item name="folderHintColor">@color/folder_hint_text_color_light</item>
<item name="isMainColorDark">true</item>
@ -123,8 +123,8 @@
</style>
<style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
<item name="folderFillColor">?android:attr/colorBackgroundFloating</item>
<item name="folderTextColor">@android:color/white</item>
<item name="folderFillColor">@color/folder_background_dark</item>
<item name="folderTextColor">@color/workspace_text_color_light</item>
<item name="isFolderDarkText">false</item>
<item name="folderHintColor">@color/folder_hint_text_color_light</item>
<item name="disabledIconAlpha">.54</item>
@ -132,16 +132,16 @@
<style name="LauncherTheme.Dark.DarkText" parent="@style/LauncherTheme.Dark">
<item name="android:colorControlHighlight">#19212121</item>
<item name="folderFillColor">?android:attr/colorBackgroundFloating</item>
<item name="folderTextColor">?attr/workspaceTextColor</item>
<item name="isFolderDarkText">?attr/isWorkspaceDarkText</item>
<item name="folderHintColor">@color/folder_hint_text_color_dark</item>
<item name="folderFillColor">@color/folder_background_light</item>
<item name="workspaceTextColor">@color/workspace_text_color_dark</item>
<item name="workspaceShadowColor">@android:color/transparent</item>
<item name="workspaceAmbientShadowColor">@android:color/transparent</item>
<item name="workspaceKeyShadowColor">@android:color/transparent</item>
<item name="isWorkspaceDarkText">true</item>
<item name="workspaceStatusBarScrim">@null</item>
<item name="folderTextColor">@color/workspace_text_color_dark</item>
<item name="isFolderDarkText">true</item>
<item name="folderHintColor">@color/folder_hint_text_color_dark</item>
</style>
<!-- A derivative project can extend these themes to customize the application theme without

View File

@ -30,17 +30,13 @@ import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
@ -50,7 +46,6 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.FocusFinder;
import android.view.KeyEvent;
@ -69,7 +64,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Alarm;
@ -104,12 +98,10 @@ import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.views.ClipPathView;
import com.android.launcher3.widget.LocalColorExtractor;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.util.ArrayList;
@ -169,11 +161,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
private static final Rect sTempRect = new Rect();
private static final int MIN_FOLDERS_FOR_HARDWARE_OPTIMIZATION = 10;
// Index used to get background color when using local wallpaper color extraction,
private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral1_900;
private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral2_500;
private static final int LIGHT_COLOR_L_STAR = 98;
private final Alarm mReorderAlarm = new Alarm();
private final Alarm mOnExitAlarm = new Alarm();
private final Alarm mOnScrollHintAlarm = new Alarm();
@ -241,17 +228,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
@Nullable private FolderWindowInsetsAnimationCallback mFolderWindowInsetsAnimationCallback;
// Wallpaper local color extraction
@Nullable private LocalColorExtractor mColorExtractor;
@Nullable private LocalColorExtractor.Listener mColorListener;
// For simplicity, we start the color change only after the open animation has started.
private Runnable mColorChangeRunnable;
private Animator mColorChangeAnimator;
// The background color animator used in the folder open animation. We keep a reference to this,
// so that we can cancel it when starting mColorChangeAnimator.
private ObjectAnimator mOpenAnimationColorChangeAnimator;
private GradientDrawable mBackground;
/**
@ -315,64 +291,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
setWindowInsetsAnimationCallback(mFolderWindowInsetsAnimationCallback);
}
if (Utilities.ATLEAST_S) {
boolean isFolderDarkText = Themes.getAttrBoolean(getContext(), R.attr.isFolderDarkText);
mColorExtractor = LocalColorExtractor.newInstance(getContext());
mColorListener = (RectF rect, SparseIntArray extractedColors) -> {
mColorChangeRunnable = () -> {
mColorChangeRunnable = null;
int duration = FOLDER_COLOR_ANIMATION_DURATION;
// Cancel the open animation color change animator.
ObjectAnimator existingAnim = mOpenAnimationColorChangeAnimator;
if (existingAnim != null && existingAnim.isRunning()) {
duration = (int) Math.max(FOLDER_COLOR_ANIMATION_DURATION,
existingAnim.getDuration() * (1f - existingAnim.getDuration()));
existingAnim.cancel();
mOpenAnimationColorChangeAnimator = null;
}
// Start a new animator to the extracted color. Clamp down on the alpha
// to prevent folder from being transparent for too long.
GradientDrawable bg = (GradientDrawable) getBackground();
int currentColor = ColorUtils.setAlphaComponent(bg.getColor().getDefaultColor(),
255);
int newColor = getExtractedColor(extractedColors, isFolderDarkText);
mColorChangeAnimator = ObjectAnimator.ofArgb(bg, "color", currentColor,
newColor).setDuration(duration);
mColorChangeAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mColorChangeAnimator = null;
}
});
mColorChangeAnimator.start();
};
// If the folder open animation has started, we can start the color change now.
// Otherwise we wait for it to start.
if (mOpenAnimationColorChangeAnimator != null
&& mOpenAnimationColorChangeAnimator.isStarted()) {
post(mColorChangeRunnable);
}
};
}
}
/**
* Returns an index used to query the color of interest from the list of extracted colors.
* @param hasDarkText True when dark index is wanted, False when light index is wanted.
*/
@TargetApi(Build.VERSION_CODES.S)
private int getExtractedColor(SparseIntArray colors, boolean hasDarkText) {
int color = colors.get(hasDarkText
? LIGHT_COLOR_EXTRACTION_INDEX
: DARK_COLOR_EXTRACTION_INDEX);
if (hasDarkText) {
color = ColorStateList.valueOf(color).withLStar(LIGHT_COLOR_L_STAR).getDefaultColor();
}
return color;
}
public boolean onLongClick(View v) {
@ -753,15 +671,11 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
cancelRunningAnimations();
FolderAnimationManager fam = new FolderAnimationManager(this, true /* isOpening */);
AnimatorSet anim = fam.getAnimator();
mOpenAnimationColorChangeAnimator = fam.getBgColorAnimator();
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mFolderIcon.setIconVisible(false);
mFolderIcon.drawLeaveBehindIfExists();
if (mColorChangeRunnable != null) {
mColorChangeRunnable.run();
}
}
@Override
public void onAnimationEnd(Animator animation) {
@ -857,9 +771,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
mCurrentAnimator.cancel();
}
if (mColorChangeAnimator != null && mColorChangeAnimator.isRunning()) {
mColorChangeAnimator.cancel();
}
}
private void animateClosed() {
@ -945,19 +856,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
clearDragInfo();
mState = STATE_SMALL;
mContent.setCurrentPage(0);
mOpenAnimationColorChangeAnimator = null;
mColorChangeRunnable = null;
if (mColorChangeAnimator != null) {
mColorChangeAnimator.cancel();
mColorChangeAnimator = null;
}
if (mColorExtractor != null) {
mColorExtractor.removeLocations();
mColorExtractor.setListener(null);
}
GradientDrawable bg = (GradientDrawable) getBackground();
bg.setColor(Themes.getAttrColor(getContext(), R.attr.folderFillColor));
}
@Override
@ -1227,12 +1125,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
lp.y = top;
mBackground.setBounds(0, 0, width, height);
if (mColorExtractor != null) {
mColorExtractor.removeLocations();
mColorExtractor.setListener(mColorListener);
mLauncherDelegate.addRectForColorExtraction(lp, mColorExtractor);
}
}
protected int getContentAreaHeight() {

View File

@ -239,13 +239,13 @@ public class FolderAnimationManager {
mFolder, startRect, endRect, finalRadius, !mIsOpening));
// Create reveal animator for the folder content (capture the top 4 icons 2x2)
int width = mContent.getPaddingLeft() + mDeviceProfile.folderCellLayoutBorderSpacingPx
int width = mDeviceProfile.folderCellLayoutBorderSpacingPx
+ mDeviceProfile.folderCellWidthPx * 2;
int height = mContent.getPaddingTop() + mDeviceProfile.folderCellLayoutBorderSpacingPx
int height = mDeviceProfile.folderCellLayoutBorderSpacingPx
+ mDeviceProfile.folderCellHeightPx * 2;
int page = mIsOpening ? mContent.getCurrentPage() : mContent.getDestinationPage();
int left = mContent.getPaddingLeft() + page * mContent.getWidth();
Rect contentStart = new Rect(left, 0, left + width, height);
int left = mContent.getPaddingLeft() + page * lp.width;
Rect contentStart = new Rect(0, 0, width, height);
Rect contentEnd = new Rect(endRect.left + left, endRect.top, endRect.right + left,
endRect.bottom);
play(a, getShape().createRevealAnimator(