diff options
author | Setup Wizard Team <android-setup-team-eng@google.com> | 2021-06-03 09:38:33 +0800 |
---|---|---|
committer | Nicole Huang <nicolehuang@google.com> | 2021-06-03 04:42:40 +0000 |
commit | fdbcc61ac6271d776cc4c32b221391b8be630620 (patch) | |
tree | 4879f3e3e5d507d77545f77a294e5c42c8b4f8fb /main/src | |
parent | 96c1ad461a5c78d14fa0fe92aa82861814e68934 (diff) | |
download | setupdesign-fdbcc61ac6271d776cc4c32b221391b8be630620.tar.gz |
Import updated Android Setupdesign Library 377192531
Copied from google3/third_party/java_src/android_libs/setupdesign
Test: mm
Bug: 189741363
Included changes:
- 377192531 [ColorExtraction] Adjusts error color for color extraction.
- 377006422 [DynamicColor] Adds testcase for DynamicColorPalette.
- 376739070 Extract IconUniformityAppImageView to setup compat library
- 376633744 [GlifLoadingLayout] Fixes using make measure spec causes ...
PiperOrigin-RevId: 377192531
Change-Id: I3da964364738db3637f8d2e884c77bb5413bd44d
Diffstat (limited to 'main/src')
4 files changed, 304 insertions, 1 deletions
diff --git a/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java b/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java index d681d9f..2541c66 100644 --- a/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java +++ b/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java @@ -58,7 +58,6 @@ public final class DynamicColorPalette { case ColorType.ACCENT: colorRes = R.color.sud_dynamic_color_accent_glif_v3; break; - // TODO: Add testcase for getColor attributes. case ColorType.PRIMARY_TEXT: colorRes = R.color.sud_system_primary_text; break; diff --git a/main/src/com/google/android/setupdesign/view/IconUniformityAppImageView.java b/main/src/com/google/android/setupdesign/view/IconUniformityAppImageView.java new file mode 100644 index 0000000..9f0e21d --- /dev/null +++ b/main/src/com/google/android/setupdesign/view/IconUniformityAppImageView.java @@ -0,0 +1,164 @@ +/* + * 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.google.android.setupdesign.view; + +import android.annotation.TargetApi; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Matrix.ScaleToFit; +import android.graphics.Outline; +import android.graphics.RectF; +import android.graphics.drawable.GradientDrawable; +import android.os.Build; +import androidx.annotation.ColorRes; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import com.google.android.setupdesign.R; +import com.google.android.setupdesign.widget.CardBackgroundDrawable; + +/** An ImageView that displays an app icon according to the icon uniformity spec. */ +public class IconUniformityAppImageView extends ImageView + implements IconUniformityAppImageViewBindable { + // Scaling factor for inset on each side of legacy icon. + private static final Float LEGACY_SIZE_SCALE_FACTOR = 0.75f; + + private static final Float LEGACY_SIZE_SCALE_MARGIN_FACTOR = (1f - LEGACY_SIZE_SCALE_FACTOR) / 2f; + + // Apps & games radius is 20% of icon height. + private static final Float APPS_ICON_RADIUS_MULTIPLIER = 0.20f; + + @ColorRes private int backdropColorResId = 0; + + private static final boolean ON_L_PLUS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + + private CardBackgroundDrawable cardBackgroundDrawable; + /** Drawable used as background after the actual image data is visible. */ + private final GradientDrawable backdropDrawable = new GradientDrawable(); + + public IconUniformityAppImageView(Context context) { + super(context); + } + + public IconUniformityAppImageView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public IconUniformityAppImageView( + Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @TargetApi(23) + public IconUniformityAppImageView( + Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + backdropColorResId = R.color.sud_uniformity_backdrop_color; + backdropDrawable.setColor(ContextCompat.getColor(getContext(), backdropColorResId)); + } + + @Override + public void bindView(IconUniformityAppImageViewData viewData) { + if (Build.VERSION.SDK_INT <= 17) { + // clipPath is not supported on hardware accelerated canvas so won't take effect unless we + // manually set to software. + setLayerType(LAYER_TYPE_SOFTWARE, /* paint= */ null); + } + + setLegacyTransformationMatrix( + viewData.icon.getMinimumWidth(), + viewData.icon.getMinimumHeight(), + getLayoutParams().width, + getLayoutParams().height); + + float radius = getLayoutParams().height * APPS_ICON_RADIUS_MULTIPLIER; + + if (ON_L_PLUS) { + setBackgroundColor(ContextCompat.getColor(getContext(), backdropColorResId)); + backdropDrawable.setCornerRadius(radius); + setElevation(getContext().getResources().getDimension(R.dimen.sud_icon_uniformity_elevation)); + setClipToOutline(true); + setOutlineProvider( + new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect( + /* left= */ 0, + /* top= */ 0, + /* right= */ getLayoutParams().width, + /* bottom= */ getLayoutParams().height, + /* radius= */ radius); + } + }); + } else { + cardBackgroundDrawable = + new CardBackgroundDrawable( + ContextCompat.getColor(getContext(), backdropColorResId), + /* radius= */ radius, + /* inset= */ 0f); + cardBackgroundDrawable.setBounds( + /* left= */ 0, + /* top= */ 0, + /* right= */ getLayoutParams().width, + /* bottom= */ getLayoutParams().height); + } + + setImageDrawable(viewData.icon); + } + + @Override + public void onRecycle() { + setImageDrawable(null); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (!ON_L_PLUS && cardBackgroundDrawable != null) { + cardBackgroundDrawable.draw(canvas); + } + super.onDraw(canvas); + } + + private void setLegacyTransformationMatrix( + float drawableWidth, float drawableHeight, float imageViewWidth, float imageViewHeight) { + Matrix scaleMatrix = new Matrix(); + float verticalMargin = imageViewHeight * LEGACY_SIZE_SCALE_MARGIN_FACTOR; + float horizontalMargin = imageViewWidth * LEGACY_SIZE_SCALE_MARGIN_FACTOR; + RectF scrRectF = new RectF(0f, 0f, drawableWidth, drawableHeight); + RectF destRectF = + new RectF( + horizontalMargin, + verticalMargin, + imageViewWidth - horizontalMargin, + imageViewHeight - verticalMargin); + + scaleMatrix.setRectToRect(scrRectF, destRectF, ScaleToFit.FILL); + + setScaleType(ScaleType.MATRIX); + setImageMatrix(scaleMatrix); + } +} diff --git a/main/src/com/google/android/setupdesign/view/IconUniformityAppImageViewBindable.java b/main/src/com/google/android/setupdesign/view/IconUniformityAppImageViewBindable.java new file mode 100644 index 0000000..1eab81b --- /dev/null +++ b/main/src/com/google/android/setupdesign/view/IconUniformityAppImageViewBindable.java @@ -0,0 +1,36 @@ +/* + * 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.google.android.setupdesign.view; + +import android.graphics.drawable.Drawable; + +/** ViewBindable for [IconUniformityAppImageView] */ +public interface IconUniformityAppImageViewBindable { + + /** Data for [IconUniformityAppImageView] */ + class IconUniformityAppImageViewData { + public Drawable icon; + + public IconUniformityAppImageViewData(Drawable icon) { + this.icon = icon; + } + } + + void bindView(IconUniformityAppImageViewData viewData); + + void onRecycle(); +} diff --git a/main/src/com/google/android/setupdesign/widget/CardBackgroundDrawable.java b/main/src/com/google/android/setupdesign/widget/CardBackgroundDrawable.java new file mode 100644 index 0000000..b354921 --- /dev/null +++ b/main/src/com/google/android/setupdesign/widget/CardBackgroundDrawable.java @@ -0,0 +1,104 @@ +/* + * 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.google.android.setupdesign.widget; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Path.Direction; +import android.graphics.Path.FillType; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import androidx.annotation.ColorInt; +import androidx.annotation.Nullable; + +/** A rounded rectangle drawable. */ +public class CardBackgroundDrawable extends Drawable { + private final float inset; + + private final Paint paint; + private final RectF cardBounds = new RectF(); + private final Path clipPath = new Path(); + + private float cornerRadius; + private boolean dirty = false; + + /** + * @param color Background color of the card to be rendered + * @param radius Corner rounding radius + * @param inset Inset from the edge of the canvas to the card + */ + public CardBackgroundDrawable(@ColorInt int color, float radius, float inset) { + cornerRadius = radius; + paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); + paint.setColor(color); + this.inset = inset; + } + + @Override + public void onBoundsChange(Rect bounds) { + super.onBoundsChange(bounds); + dirty = true; + } + + @Override + public void setColorFilter(@Nullable ColorFilter cf) { + paint.setColorFilter(cf); + } + + @Override + public int getOpacity() { + return PixelFormat.OPAQUE; + } + + public void setCornerRadius(float radius) { + if (cornerRadius == radius) { + return; + } + + cornerRadius = radius; + dirty = true; + invalidateSelf(); + } + + @Override + public void draw(Canvas canvas) { + if (dirty) { + buildComponents(getBounds()); + dirty = false; + } + + if (cornerRadius > 0) { + canvas.clipPath(clipPath); + } + } + + @Override + public void setAlpha(int alpha) {} + + private void buildComponents(Rect bounds) { + cardBounds.set(bounds); + cardBounds.inset(inset, inset); + + clipPath.reset(); + clipPath.setFillType(FillType.EVEN_ODD); + clipPath.addRoundRect(cardBounds, cornerRadius, cornerRadius, Direction.CW); + } +} |