summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorSetup Wizard Team <android-setup-team-eng@google.com>2019-03-14 09:55:53 +0800
committerpastychang <pastychang@google.com>2019-03-14 10:40:06 +0800
commit82e3d14f503c6e75c53a0ce218afaffbfe47e31e (patch)
treedf4354c7df1a47c0b9515f502223b4bcf1bd2b90 /main/src
parent1d8468829fcf4c6f94a7453a9b1c978e89f98eb0 (diff)
downloadsetupdesign-82e3d14f503c6e75c53a0ce218afaffbfe47e31e.tar.gz
Import updated Android Setupdesign Library 238357199
Test: mm PiperOrigin-RevId: 238357199 Change-Id: Ic3f1ca113eb1ab8aacc5cfcad5e3ec389f542788
Diffstat (limited to 'main/src')
-rw-r--r--main/src/com/google/android/setupdesign/GlifLayout.java23
-rw-r--r--main/src/com/google/android/setupdesign/SetupWizardLayout.java10
-rw-r--r--main/src/com/google/android/setupdesign/items/Dividable.java34
-rw-r--r--main/src/com/google/android/setupdesign/items/Item.java35
-rw-r--r--main/src/com/google/android/setupdesign/items/ItemViewHolder.java4
-rw-r--r--main/src/com/google/android/setupdesign/items/ProgressBarItem.java46
-rw-r--r--main/src/com/google/android/setupdesign/template/HeaderMixin.java210
-rw-r--r--main/src/com/google/android/setupdesign/template/IconMixin.java181
-rw-r--r--main/src/com/google/android/setupdesign/util/DescriptionStyler.java84
-rw-r--r--main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java42
-rw-r--r--main/src/com/google/android/setupdesign/util/SystemBarHelper.java180
11 files changed, 709 insertions, 140 deletions
diff --git a/main/src/com/google/android/setupdesign/GlifLayout.java b/main/src/com/google/android/setupdesign/GlifLayout.java
index ee36285..bb71976 100644
--- a/main/src/com/google/android/setupdesign/GlifLayout.java
+++ b/main/src/com/google/android/setupdesign/GlifLayout.java
@@ -35,12 +35,13 @@ import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import com.google.android.setupcompat.PartnerCustomizationLayout;
-import com.google.android.setupcompat.template.HeaderMixin;
-import com.google.android.setupcompat.template.IconMixin;
import com.google.android.setupcompat.template.StatusBarMixin;
+import com.google.android.setupdesign.template.HeaderMixin;
+import com.google.android.setupdesign.template.IconMixin;
import com.google.android.setupdesign.template.ProgressBarMixin;
import com.google.android.setupdesign.template.RequireScrollMixin;
import com.google.android.setupdesign.template.ScrollViewScrollHandlingDelegate;
+import com.google.android.setupdesign.util.DescriptionStyler;
/**
* Layout for the GLIF theme used in Setup Wizard for N.
@@ -99,8 +100,11 @@ public class GlifLayout extends PartnerCustomizationLayout {
// All the constructors delegate to this init method. The 3-argument constructor is not
// available in LinearLayout before v11, so call super with the exact same arguments.
private void init(AttributeSet attrs, int defStyleAttr) {
- registerMixin(HeaderMixin.class, new HeaderMixin(this, attrs, defStyleAttr));
- registerMixin(IconMixin.class, new IconMixin(this, attrs, defStyleAttr));
+ registerMixin(
+ HeaderMixin.class,
+ new HeaderMixin(this, attrs, defStyleAttr, shouldApplyPartnerResource()));
+ registerMixin(
+ IconMixin.class, new IconMixin(this, attrs, defStyleAttr, shouldApplyPartnerResource()));
registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this));
final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this);
registerMixin(RequireScrollMixin.class, requireScrollMixin);
@@ -131,7 +135,18 @@ public class GlifLayout extends PartnerCustomizationLayout {
if (stickyHeader != 0) {
inflateStickyHeader(stickyHeader);
}
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ TextView description = this.findManagedViewById(R.id.sud_layout_description);
+ if (description != null) {
+ if (shouldApplyPartnerResource()) {
+ DescriptionStyler.applyPartnerCustomizationStyle(description);
+ }
+ }
}
@Override
diff --git a/main/src/com/google/android/setupdesign/SetupWizardLayout.java b/main/src/com/google/android/setupdesign/SetupWizardLayout.java
index 35752cd..bec06b1 100644
--- a/main/src/com/google/android/setupdesign/SetupWizardLayout.java
+++ b/main/src/com/google/android/setupdesign/SetupWizardLayout.java
@@ -39,7 +39,8 @@ import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import com.google.android.setupcompat.internal.TemplateLayout;
-import com.google.android.setupcompat.template.HeaderMixin;
+import com.google.android.setupcompat.template.SystemNavBarMixin;
+import com.google.android.setupdesign.template.HeaderMixin;
import com.google.android.setupdesign.template.NavigationBarMixin;
import com.google.android.setupdesign.template.ProgressBarMixin;
import com.google.android.setupdesign.template.RequireScrollMixin;
@@ -79,7 +80,12 @@ public class SetupWizardLayout extends TemplateLayout {
// All the constructors delegate to this init method. The 3-argument constructor is not
// available in LinearLayout before v11, so call super with the exact same arguments.
private void init(AttributeSet attrs, int defStyleAttr) {
- registerMixin(HeaderMixin.class, new HeaderMixin(this, attrs, defStyleAttr));
+ registerMixin(
+ SystemNavBarMixin.class,
+ new SystemNavBarMixin(this, /* window= */ null, /* applyPartnerResources= */ false));
+ registerMixin(
+ HeaderMixin.class,
+ new HeaderMixin(this, attrs, defStyleAttr, /* applyPartnerResource= */ false));
registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this));
registerMixin(NavigationBarMixin.class, new NavigationBarMixin(this));
final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this);
diff --git a/main/src/com/google/android/setupdesign/items/Dividable.java b/main/src/com/google/android/setupdesign/items/Dividable.java
new file mode 100644
index 0000000..7ed1332
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/items/Dividable.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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.items;
+
+/**
+ * Same as {@link com.google.android.setupdesign.DividerItemDecoration.DividedViewHolder} but not
+ * limited for use to {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}
+ */
+public interface Dividable {
+ /**
+ * Returns whether divider is allowed above this item. A divider will be shown only if both items
+ * immediately above and below it allows this divider.
+ */
+ boolean isDividerAllowedAbove();
+
+ /**
+ * Returns whether divider is allowed below this item. A divider will be shown only if both items
+ * immediately above and below it allows this divider.
+ */
+ boolean isDividerAllowedBelow();
+}
diff --git a/main/src/com/google/android/setupdesign/items/Item.java b/main/src/com/google/android/setupdesign/items/Item.java
index 4217b4e..7aa6297 100644
--- a/main/src/com/google/android/setupdesign/items/Item.java
+++ b/main/src/com/google/android/setupdesign/items/Item.java
@@ -18,10 +18,15 @@ package com.google.android.setupdesign.items;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
+import androidx.annotation.ColorInt;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.View;
+import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.android.setupdesign.R;
@@ -37,6 +42,8 @@ public class Item extends AbstractItem {
private CharSequence summary;
private CharSequence title;
private boolean visible = true;
+ @ColorInt private int iconTint = Color.TRANSPARENT;
+ private int iconGravity = Gravity.CENTER;
public Item() {
super();
@@ -52,6 +59,8 @@ public class Item extends AbstractItem {
summary = a.getText(R.styleable.SudItem_android_summary);
layoutRes = a.getResourceId(R.styleable.SudItem_android_layout, getDefaultLayoutResource());
visible = a.getBoolean(R.styleable.SudItem_android_visible, true);
+ iconTint = a.getColor(R.styleable.SudItem_sudIconTint, Color.TRANSPARENT);
+ iconGravity = a.getInt(R.styleable.SudItem_sudIconGravity, Gravity.CENTER);
a.recycle();
}
@@ -83,6 +92,23 @@ public class Item extends AbstractItem {
return icon;
}
+ public void setIconTint(@ColorInt int iconTint) {
+ this.iconTint = iconTint;
+ }
+
+ @ColorInt
+ public int getIconTint() {
+ return iconTint;
+ }
+
+ public void setIconGravity(int iconGravity) {
+ this.iconGravity = iconGravity;
+ }
+
+ public int getIconGravity() {
+ return iconGravity;
+ }
+
public void setLayoutResource(int layoutResource) {
layoutRes = layoutResource;
notifyItemChanged();
@@ -155,6 +181,15 @@ public class Item extends AbstractItem {
iconView.setImageDrawable(null);
onMergeIconStateAndLevels(iconView, icon);
iconView.setImageDrawable(icon);
+ if (iconTint != Color.TRANSPARENT) {
+ iconView.setColorFilter(iconTint);
+ } else {
+ iconView.clearColorFilter();
+ }
+ LayoutParams layoutParams = iconContainer.getLayoutParams();
+ if (layoutParams instanceof LinearLayout.LayoutParams) {
+ ((LinearLayout.LayoutParams) layoutParams).gravity = iconGravity;
+ }
iconContainer.setVisibility(View.VISIBLE);
} else {
iconContainer.setVisibility(View.GONE);
diff --git a/main/src/com/google/android/setupdesign/items/ItemViewHolder.java b/main/src/com/google/android/setupdesign/items/ItemViewHolder.java
index b293cfe..f79b2b6 100644
--- a/main/src/com/google/android/setupdesign/items/ItemViewHolder.java
+++ b/main/src/com/google/android/setupdesign/items/ItemViewHolder.java
@@ -32,12 +32,12 @@ class ItemViewHolder extends RecyclerView.ViewHolder
@Override
public boolean isDividerAllowedAbove() {
- return isEnabled;
+ return item instanceof Dividable ? ((Dividable) item).isDividerAllowedAbove() : isEnabled;
}
@Override
public boolean isDividerAllowedBelow() {
- return isEnabled;
+ return item instanceof Dividable ? ((Dividable) item).isDividerAllowedBelow() : isEnabled;
}
public void setEnabled(boolean isEnabled) {
diff --git a/main/src/com/google/android/setupdesign/items/ProgressBarItem.java b/main/src/com/google/android/setupdesign/items/ProgressBarItem.java
new file mode 100644
index 0000000..444a0d0
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/items/ProgressBarItem.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.items;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import com.google.android.setupdesign.R;
+
+public class ProgressBarItem extends Item {
+
+ public ProgressBarItem() {
+ super();
+ }
+
+ public ProgressBarItem(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ // This item is not clickable.
+ return false;
+ }
+
+ @Override
+ protected int getDefaultLayoutResource() {
+ return R.layout.sud_items_progress_bar;
+ }
+
+ @Override
+ public void onBindView(View view) {}
+}
diff --git a/main/src/com/google/android/setupdesign/template/HeaderMixin.java b/main/src/com/google/android/setupdesign/template/HeaderMixin.java
new file mode 100644
index 0000000..ea2063e
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/template/HeaderMixin.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2017 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.template;
+
+import static android.content.res.ColorStateList.valueOf;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.Typeface;
+import androidx.annotation.AttrRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.ViewParent;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.google.android.setupcompat.R;
+import com.google.android.setupcompat.internal.TemplateLayout;
+import com.google.android.setupcompat.partnerconfig.PartnerConfig;
+import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+import com.google.android.setupcompat.template.Mixin;
+
+/**
+ * A {@link com.google.android.setupcompat.template.Mixin} for setting and getting the header text.
+ */
+public class HeaderMixin implements Mixin {
+
+ private final TemplateLayout templateLayout;
+
+ /**
+ * @param layout The layout this Mixin belongs to.
+ * @param attrs XML attributes given to the layout.
+ * @param defStyleAttr The default style attribute as given to the constructor of the layout.
+ * @param applyPartnerResource Whether to apply partner resources or not.
+ */
+ public HeaderMixin(
+ @NonNull TemplateLayout layout,
+ @Nullable AttributeSet attrs,
+ @AttrRes int defStyleAttr,
+ boolean applyPartnerResource) {
+ templateLayout = layout;
+ final Context context = layout.getContext();
+
+ final TypedArray a =
+ layout
+ .getContext()
+ .obtainStyledAttributes(attrs, R.styleable.SucHeaderMixin, defStyleAttr, 0);
+
+ // Set the header text
+ final CharSequence headerText = a.getText(R.styleable.SucHeaderMixin_sucHeaderText);
+ if (headerText != null) {
+ setText(headerText);
+ }
+ // Set the header text color
+ final ColorStateList headerTextColor =
+ a.getColorStateList(R.styleable.SucHeaderMixin_sucHeaderTextColor);
+ if (headerTextColor != null) {
+ setTextColor(headerTextColor);
+ }
+
+ a.recycle();
+
+ TextView header = layout.findManagedViewById(R.id.suc_layout_title);
+ if (header != null && applyPartnerResource) {
+ applyPartnerCustomizationStyle(context, header);
+ }
+ }
+
+ public void applyPartnerCustomizationStyle(Context context, TextView header) {
+
+ int textColor =
+ PartnerConfigHelper.get(context).getColor(context, PartnerConfig.CONFIG_HEADER_TEXT_COLOR);
+ if (textColor != 0) {
+ setTextColor(valueOf(textColor));
+ }
+
+ float textSize =
+ PartnerConfigHelper.get(context)
+ .getDimension(context, PartnerConfig.CONFIG_HEADER_TEXT_SIZE);
+ if (textSize != 0) {
+ setTextSize(textSize);
+ }
+
+ String fontFamily =
+ PartnerConfigHelper.get(context)
+ .getString(context, PartnerConfig.CONFIG_HEADER_FONT_FAMILY);
+ if (fontFamily != null) {
+ setFontFamily(Typeface.create(fontFamily, Typeface.NORMAL));
+ }
+
+ String gravity =
+ PartnerConfigHelper.get(context).getString(context, PartnerConfig.CONFIG_LAYOUT_GRAVITY);
+ if (gravity != null) {
+ switch (gravity.toLowerCase()) {
+ case "center":
+ setGravity(header, Gravity.CENTER);
+ break;
+ case "start":
+ setGravity(header, Gravity.START);
+ break;
+ default: // fall out
+ }
+ }
+
+ int color =
+ PartnerConfigHelper.get(context)
+ .getColor(context, PartnerConfig.CONFIG_HEADER_AREA_BACKGROUND_COLOR);
+ setBackgroundColor(color);
+ }
+
+ /** @return The TextView displaying the header. */
+ public TextView getTextView() {
+ return (TextView) templateLayout.findManagedViewById(R.id.suc_layout_title);
+ }
+
+ /**
+ * Sets the header text. This can also be set via the XML attribute {@code app:sucHeaderText}.
+ *
+ * @param title The resource ID of the text to be set as header.
+ */
+ public void setText(int title) {
+ final TextView titleView = getTextView();
+ if (titleView != null) {
+ titleView.setText(title);
+ }
+ }
+
+ /**
+ * Sets the header text. This can also be set via the XML attribute {@code app:sucHeaderText}.
+ *
+ * @param title The text to be set as header.
+ */
+ public void setText(CharSequence title) {
+ final TextView titleView = getTextView();
+ if (titleView != null) {
+ titleView.setText(title);
+ }
+ }
+
+ /** @return The current header text. */
+ public CharSequence getText() {
+ final TextView titleView = getTextView();
+ return titleView != null ? titleView.getText() : null;
+ }
+
+ private void setTextSize(float sizePx) {
+ final TextView titleView = getTextView();
+ if (titleView != null) {
+ titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, sizePx);
+ }
+ }
+
+ /**
+ * Sets the color of the header text. This can also be set via XML using {@code
+ * app:sucHeaderTextColor}.
+ *
+ * @param color The text color of the header.
+ */
+ public void setTextColor(ColorStateList color) {
+ final TextView titleView = getTextView();
+ if (titleView != null) {
+ titleView.setTextColor(color);
+ }
+ }
+
+ /** Sets the background color of the header's parent LinearLayout */
+ public void setBackgroundColor(int color) {
+ final TextView titleView = getTextView();
+ if (titleView != null) {
+ ViewParent parent = titleView.getParent();
+ if (parent instanceof LinearLayout) {
+ ((LinearLayout) parent).setBackgroundColor(color);
+ }
+ }
+ }
+
+ private void setFontFamily(Typeface fontFamily) {
+ final TextView titleView = getTextView();
+ if (titleView != null) {
+ titleView.setTypeface(fontFamily);
+ }
+ }
+
+ /** Returns the current text color of the header. */
+ public ColorStateList getTextColor() {
+ final TextView titleView = getTextView();
+ return titleView != null ? titleView.getTextColors() : null;
+ }
+
+ private void setGravity(TextView header, int gravity) {
+ header.setGravity(gravity);
+ }
+}
diff --git a/main/src/com/google/android/setupdesign/template/IconMixin.java b/main/src/com/google/android/setupdesign/template/IconMixin.java
new file mode 100644
index 0000000..d68daa4
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/template/IconMixin.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2017 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.template;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import com.google.android.setupcompat.internal.TemplateLayout;
+import com.google.android.setupcompat.template.Mixin;
+import com.google.android.setupdesign.R;
+import com.google.android.setupdesign.util.PartnerStyleHelper;
+
+/**
+ * A {@link com.google.android.setupcompat.template.Mixin} for setting an icon on the template
+ * layout.
+ */
+public class IconMixin implements Mixin {
+
+ private final TemplateLayout templateLayout;
+
+ private final int originalHeight;
+ private final ImageView.ScaleType originalScaleType;
+
+ /**
+ * @param layout The template layout that this Mixin is a part of.
+ * @param attrs XML attributes given to the layout.
+ * @param defStyleAttr The default style attribute as given to the constructor of the layout.
+ * @param shouldApplyPartnerResource Whether to apply partner resources or not.
+ */
+ public IconMixin(
+ TemplateLayout layout,
+ AttributeSet attrs,
+ int defStyleAttr,
+ boolean shouldApplyPartnerResource) {
+ templateLayout = layout;
+ final Context context = layout.getContext();
+
+ ImageView iconView = getView();
+ if (iconView != null) {
+ LayoutParams layoutParams = iconView.getLayoutParams();
+ originalHeight = layoutParams.height;
+ originalScaleType = iconView.getScaleType();
+ } else {
+ originalHeight = 0;
+ originalScaleType = null;
+ }
+
+ final TypedArray a =
+ context.obtainStyledAttributes(attrs, R.styleable.SudIconMixin, defStyleAttr, 0);
+
+ final @DrawableRes int icon = a.getResourceId(R.styleable.SudIconMixin_android_icon, 0);
+ if (icon != 0) {
+ setIcon(icon);
+ }
+
+ final boolean upscaleIcon = a.getBoolean(R.styleable.SudIconMixin_sudUpscaleIcon, false);
+ setUpscaleIcon(upscaleIcon);
+
+ final @ColorInt int iconTint =
+ a.getColor(R.styleable.SudIconMixin_sudIconTint, Color.TRANSPARENT);
+ if (iconTint != Color.TRANSPARENT) {
+ setIconTint(iconTint);
+ }
+
+ a.recycle();
+
+ ImageView iconImage = layout.findManagedViewById(R.id.sud_layout_icon);
+ if (iconImage != null && shouldApplyPartnerResource) {
+ applyPartnerCustomizationStyle(context, iconImage);
+ }
+ }
+
+ public void applyPartnerCustomizationStyle(Context context, ImageView iconImage) {
+ int gravity = PartnerStyleHelper.getLayoutGravity(context);
+ if (gravity != 0) {
+ setGravity(iconImage, gravity);
+ }
+ }
+
+ /**
+ * Sets the icon on this layout. The icon can also be set in XML using {@code android:icon}.
+ *
+ * @param icon A drawable icon.
+ */
+ public void setIcon(Drawable icon) {
+ final ImageView iconView = getView();
+ if (iconView != null) {
+ iconView.setImageDrawable(icon);
+ iconView.setVisibility(icon != null ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ /**
+ * Sets the icon on this layout. The icon can also be set in XML using {@code android:icon}.
+ *
+ * @param icon A drawable icon resource.
+ */
+ public void setIcon(@DrawableRes int icon) {
+ final ImageView iconView = getView();
+ if (iconView != null) {
+ // Note: setImageResource on the ImageView is overridden in AppCompatImageView for
+ // support lib users, which enables vector drawable compat to work on versions pre-L.
+ iconView.setImageResource(icon);
+ iconView.setVisibility(icon != 0 ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ /** @return The icon previously set in {@link #setIcon(Drawable)} or {@code android:icon} */
+ public Drawable getIcon() {
+ final ImageView iconView = getView();
+ return iconView != null ? iconView.getDrawable() : null;
+ }
+
+ /** Forces the icon view to be as big as desired in the style. */
+ public void setUpscaleIcon(boolean shouldUpscaleIcon) {
+ final ImageView iconView = getView();
+ if (iconView != null) {
+ LayoutParams layoutParams = iconView.getLayoutParams();
+ layoutParams.height = shouldUpscaleIcon ? iconView.getMaxHeight() : originalHeight;
+ iconView.setLayoutParams(layoutParams);
+ iconView.setScaleType(shouldUpscaleIcon ? ImageView.ScaleType.FIT_CENTER : originalScaleType);
+ }
+ }
+
+ /** Tints the icon on this layout to the given color. */
+ public void setIconTint(@ColorInt int tint) {
+ final ImageView iconView = getView();
+ if (iconView != null) {
+ iconView.setColorFilter(tint);
+ }
+ }
+
+ /** Sets the content description of the icon view */
+ public void setContentDescription(CharSequence description) {
+ final ImageView iconView = getView();
+ if (iconView != null) {
+ iconView.setContentDescription(description);
+ }
+ }
+
+ /** @return The content description of the icon view */
+ public CharSequence getContentDescription() {
+ final ImageView iconView = getView();
+ return iconView != null ? iconView.getContentDescription() : null;
+ }
+
+ /** @return The ImageView responsible for displaying the icon. */
+ protected ImageView getView() {
+ return (ImageView) templateLayout.findManagedViewById(R.id.sud_layout_icon);
+ }
+
+ private void setGravity(ImageView icon, int gravity) {
+ if (icon.getLayoutParams() instanceof LinearLayout.LayoutParams) {
+ LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) icon.getLayoutParams();
+ layoutParams.gravity = gravity;
+ icon.setLayoutParams(layoutParams);
+ }
+ }
+}
diff --git a/main/src/com/google/android/setupdesign/util/DescriptionStyler.java b/main/src/com/google/android/setupdesign/util/DescriptionStyler.java
new file mode 100644
index 0000000..d4e7ded
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/util/DescriptionStyler.java
@@ -0,0 +1,84 @@
+package com.google.android.setupdesign.util;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import androidx.annotation.VisibleForTesting;
+import android.util.TypedValue;
+import android.widget.TextView;
+import com.google.android.setupcompat.partnerconfig.PartnerConfig;
+import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+
+/** Applies the given style properties for the style of the given type. */
+public class DescriptionStyler {
+
+ public static void applyPartnerCustomizationStyle(TextView description) {
+
+ final Context context = description.getContext();
+
+ int descriptionTextColor =
+ PartnerConfigHelper.get(context)
+ .getColor(context, PartnerConfig.CONFIG_DESCRIPTION_TEXT_COLOR);
+ if (descriptionTextColor != 0) {
+ setTextColor(description, descriptionTextColor);
+ }
+
+ int descriptionLinkTextColor =
+ PartnerConfigHelper.get(context)
+ .getColor(context, PartnerConfig.CONFIG_DESCRIPTION_LINK_TEXT_COLOR);
+ if (descriptionLinkTextColor != 0) {
+ setLinkTextColor(description, descriptionLinkTextColor);
+ }
+
+ float descriptionTextSize =
+ PartnerConfigHelper.get(context)
+ .getDimension(context, PartnerConfig.CONFIG_DESCRIPTION_TEXT_SIZE, 0);
+ if (descriptionTextSize != 0) {
+ setTextSize(description, descriptionTextSize);
+ }
+
+ String fontFamilyName =
+ PartnerConfigHelper.get(context)
+ .getString(context, PartnerConfig.CONFIG_DESCRIPTION_FONT_FAMILY);
+ Typeface font = Typeface.create(fontFamilyName, Typeface.NORMAL);
+ if (font != null) {
+ setFontFamily(description, font);
+ }
+
+ setGravity(description, PartnerStyleHelper.getLayoutGravity(context));
+ }
+
+ @VisibleForTesting
+ static void setTextSize(TextView description, float size) {
+ if (description != null) {
+ description.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
+ }
+ }
+
+ @VisibleForTesting
+ static void setFontFamily(TextView description, Typeface fontFamily) {
+ if (description != null) {
+ description.setTypeface(fontFamily);
+ }
+ }
+
+ @VisibleForTesting
+ static void setTextColor(TextView description, int color) {
+ if (description != null) {
+ description.setTextColor(color);
+ }
+ }
+
+ @VisibleForTesting
+ static void setLinkTextColor(TextView description, int color) {
+ if (description != null) {
+ description.setLinkTextColor(color);
+ }
+ }
+
+ @VisibleForTesting
+ static void setGravity(TextView description, int gravity) {
+ if (description != null) {
+ description.setGravity(gravity);
+ }
+ }
+}
diff --git a/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java b/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java
new file mode 100644
index 0000000..735b705
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.util;
+
+import android.content.Context;
+import android.view.Gravity;
+import com.google.android.setupcompat.partnerconfig.PartnerConfig;
+import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+
+/** The helper reads styles from the partner configurations. */
+public class PartnerStyleHelper {
+
+ public static int getLayoutGravity(Context context) {
+ String gravity =
+ PartnerConfigHelper.get(context).getString(context, PartnerConfig.CONFIG_LAYOUT_GRAVITY);
+ if (gravity != null) {
+ switch (gravity.toLowerCase()) {
+ case "center":
+ return Gravity.CENTER;
+ case "start":
+ return Gravity.START;
+ default:
+ return 0;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/main/src/com/google/android/setupdesign/util/SystemBarHelper.java b/main/src/com/google/android/setupdesign/util/SystemBarHelper.java
index e784fb0..467c4dc 100644
--- a/main/src/com/google/android/setupdesign/util/SystemBarHelper.java
+++ b/main/src/com/google/android/setupdesign/util/SystemBarHelper.java
@@ -16,7 +16,6 @@
package com.google.android.setupdesign.util;
-import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Dialog;
import android.content.Context;
@@ -25,12 +24,12 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
import androidx.annotation.RequiresPermission;
-import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
+import com.google.android.setupcompat.util.SystemBarBaseHelper;
/**
* A helper class to manage the system navigation bar and status bar. This will add various
@@ -46,37 +45,25 @@ public class SystemBarHelper {
private static final String TAG = "SystemBarHelper";
- @SuppressLint("InlinedApi")
- private static final int DEFAULT_IMMERSIVE_FLAGS =
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
-
- @SuppressLint("InlinedApi")
- private static final int DIALOG_IMMERSIVE_FLAGS =
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
-
/** Needs to be equal to View.STATUS_BAR_DISABLE_BACK */
private static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
/**
- * The maximum number of retries when peeking the decor view. When polling for the decor view,
- * waiting it to be installed, set a maximum number of retries.
- */
- private static final int PEEK_DECOR_VIEW_RETRIES = 3;
-
- /**
* Hide the navigation bar for a dialog.
*
* <p>This will only take effect in versions Lollipop or above. Otherwise this is a no-op.
+ *
+ * @deprecated If the layout is instance of TemplateLayout, please use
+ * SystemNavBarMixin.hideSystemBars.
*/
+ @Deprecated
public static void hideSystemBars(final Dialog dialog) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
final Window window = dialog.getWindow();
temporarilyDisableDialogFocus(window);
- addVisibilityFlag(window, DIALOG_IMMERSIVE_FLAGS);
- addImmersiveFlagsToDecorView(window, DIALOG_IMMERSIVE_FLAGS);
+ SystemBarBaseHelper.addVisibilityFlag(window, SystemBarBaseHelper.DIALOG_IMMERSIVE_FLAGS);
+ SystemBarBaseHelper.addImmersiveFlagsToDecorView(
+ window, SystemBarBaseHelper.DIALOG_IMMERSIVE_FLAGS);
// Also set the navigation bar and status bar to transparent color. Note that this
// doesn't work if android.R.boolean.config_enableTranslucentDecor is false.
@@ -93,11 +80,16 @@ public class SystemBarHelper {
* Wizard style.
*
* <p>This will only take effect in versions Lollipop or above. Otherwise this is a no-op.
+ *
+ * @deprecated If the layout instance of TemplateLayout, please use
+ * SystemNavBarMixin.hideSystemBars.
*/
+ @Deprecated
public static void hideSystemBars(final Window window) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
- addVisibilityFlag(window, DEFAULT_IMMERSIVE_FLAGS);
- addImmersiveFlagsToDecorView(window, DEFAULT_IMMERSIVE_FLAGS);
+ SystemBarBaseHelper.addVisibilityFlag(window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS);
+ SystemBarBaseHelper.addImmersiveFlagsToDecorView(
+ window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS);
// Also set the navigation bar and status bar to transparent color. Note that this
// doesn't work if android.R.boolean.config_enableTranslucentDecor is false.
@@ -110,20 +102,16 @@ public class SystemBarHelper {
* Revert the actions of hideSystemBars. Note that this will remove the system UI visibility flags
* regardless of whether it is originally present. You should also manually reset the navigation
* bar and status bar colors, as this method doesn't know what value to revert it to.
+ *
+ * @deprecated If the layout is instance of TemplateLayout, please use
+ * SystemNavBarMixin.showSystemBars.
*/
- public static void showSystemBars(final Dialog dialog, final Context context) {
- showSystemBars(dialog.getWindow(), context);
- }
-
- /**
- * Revert the actions of hideSystemBars. Note that this will remove the system UI visibility flags
- * regardless of whether it is originally present. You should also manually reset the navigation
- * bar and status bar colors, as this method doesn't know what value to revert it to.
- */
+ @Deprecated
public static void showSystemBars(final Window window, final Context context) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
- removeVisibilityFlag(window, DEFAULT_IMMERSIVE_FLAGS);
- removeImmersiveFlagsFromDecorView(window, DEFAULT_IMMERSIVE_FLAGS);
+ SystemBarBaseHelper.removeVisibilityFlag(window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS);
+ SystemBarBaseHelper.removeImmersiveFlagsFromDecorView(
+ window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS);
if (context != null) {
//noinspection AndroidLintInlinedApi
@@ -139,44 +127,46 @@ public class SystemBarHelper {
}
}
- /** Convenience method to add a visibility flag in addition to the existing ones. */
+ /**
+ * Convenience method to add a visibility flag in addition to the existing ones.
+ *
+ * @deprecated Use SystemBarBaseHelper.addVisibilityFlag(final View view, final int flag).
+ */
+ @Deprecated
public static void addVisibilityFlag(final View view, final int flag) {
- if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
- final int vis = view.getSystemUiVisibility();
- view.setSystemUiVisibility(vis | flag);
- }
+ SystemBarBaseHelper.addVisibilityFlag(view, flag);
}
- /** Convenience method to add a visibility flag in addition to the existing ones. */
+ /**
+ * Convenience method to add a visibility flag in addition to the existing ones.
+ *
+ * @deprecated Use SystemBarBaseHelper.addVisibilityFlag(final Window window, final int flag).
+ */
+ @Deprecated
public static void addVisibilityFlag(final Window window, final int flag) {
- if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
- WindowManager.LayoutParams attrs = window.getAttributes();
- attrs.systemUiVisibility |= flag;
- window.setAttributes(attrs);
- }
+ SystemBarBaseHelper.addVisibilityFlag(window, flag);
}
/**
* Convenience method to remove a visibility flag from the view, leaving other flags that are not
* specified intact.
+ *
+ * @deprecated Use SystemBarBaseHelper.removeVisibilityFlag(final View view, final int flag).
*/
+ @Deprecated
public static void removeVisibilityFlag(final View view, final int flag) {
- if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
- final int vis = view.getSystemUiVisibility();
- view.setSystemUiVisibility(vis & ~flag);
- }
+ SystemBarBaseHelper.removeVisibilityFlag(view, flag);
}
/**
* Convenience method to remove a visibility flag from the window, leaving other flags that are
* not specified intact.
+ *
+ * @deprecated Use SystemBarBaseHelper.removeVisibilityFlag(final Window window, final int flag).
*/
+ @Deprecated
public static void removeVisibilityFlag(final Window window, final int flag) {
- if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
- WindowManager.LayoutParams attrs = window.getAttributes();
- attrs.systemUiVisibility &= ~flag;
- window.setAttributes(attrs);
- }
+ SystemBarBaseHelper.removeVisibilityFlag(window, flag);
}
/**
@@ -193,11 +183,11 @@ public class SystemBarHelper {
public static void setBackButtonVisible(final Window window, final boolean visible) {
if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
if (visible) {
- removeVisibilityFlag(window, STATUS_BAR_DISABLE_BACK);
- removeImmersiveFlagsFromDecorView(window, STATUS_BAR_DISABLE_BACK);
+ SystemBarBaseHelper.removeVisibilityFlag(window, STATUS_BAR_DISABLE_BACK);
+ SystemBarBaseHelper.removeImmersiveFlagsFromDecorView(window, STATUS_BAR_DISABLE_BACK);
} else {
- addVisibilityFlag(window, STATUS_BAR_DISABLE_BACK);
- addImmersiveFlagsToDecorView(window, STATUS_BAR_DISABLE_BACK);
+ SystemBarBaseHelper.addVisibilityFlag(window, STATUS_BAR_DISABLE_BACK);
+ SystemBarBaseHelper.addImmersiveFlagsToDecorView(window, STATUS_BAR_DISABLE_BACK);
}
}
}
@@ -222,80 +212,6 @@ public class SystemBarHelper {
}
/**
- * Add the specified immersive flags to the decor view of the window, because {@link
- * View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} only takes effect when it is added to a view instead of
- * the window.
- */
- @TargetApi(VERSION_CODES.HONEYCOMB)
- private static void addImmersiveFlagsToDecorView(final Window window, final int vis) {
- getDecorView(
- window,
- new OnDecorViewInstalledListener() {
- @Override
- public void onDecorViewInstalled(View decorView) {
- addVisibilityFlag(decorView, vis);
- }
- });
- }
-
- @TargetApi(VERSION_CODES.HONEYCOMB)
- private static void removeImmersiveFlagsFromDecorView(final Window window, final int vis) {
- getDecorView(
- window,
- new OnDecorViewInstalledListener() {
- @Override
- public void onDecorViewInstalled(View decorView) {
- removeVisibilityFlag(decorView, vis);
- }
- });
- }
-
- private static void getDecorView(Window window, OnDecorViewInstalledListener callback) {
- new DecorViewFinder().getDecorView(window, callback, PEEK_DECOR_VIEW_RETRIES);
- }
-
- private static class DecorViewFinder {
-
- private final Handler handler = new Handler();
- private Window window;
- private int retries;
- private OnDecorViewInstalledListener callback;
-
- private final Runnable checkDecorViewRunnable =
- new Runnable() {
- @Override
- public void run() {
- // Use peekDecorView instead of getDecorView so that clients can still set window
- // features after calling this method.
- final View decorView = window.peekDecorView();
- if (decorView != null) {
- callback.onDecorViewInstalled(decorView);
- } else {
- retries--;
- if (retries >= 0) {
- // If the decor view is not installed yet, try again in the next loop.
- handler.post(checkDecorViewRunnable);
- } else {
- Log.w(TAG, "Cannot get decor view of window: " + window);
- }
- }
- }
- };
-
- public void getDecorView(Window window, OnDecorViewInstalledListener callback, int retries) {
- this.window = window;
- this.retries = retries;
- this.callback = callback;
- checkDecorViewRunnable.run();
- }
- }
-
- private interface OnDecorViewInstalledListener {
-
- void onDecorViewInstalled(View decorView);
- }
-
- /**
* Apply a hack to temporarily set the window to not focusable, so that the navigation bar will
* not show up during the transition.
*/