Snap for 6077728 from 0564078669999e2e240c9a5ca55e7cd5c28a7e04 to rvc-release
Change-Id: I1a36f12fccd20a593b456bbd69a465e57204c58b
diff --git a/main/res/layout/sud_glif_header.xml b/main/res/layout/sud_glif_header.xml
index 478438c..f5a1113 100644
--- a/main/res/layout/sud_glif_header.xml
+++ b/main/res/layout/sud_glif_header.xml
@@ -16,6 +16,7 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/sud_layout_header"
style="@style/SudGlifHeaderContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/main/src/com/google/android/setupdesign/GlifLayout.java b/main/src/com/google/android/setupdesign/GlifLayout.java
index 67be5d5..de4f8c1 100644
--- a/main/src/com/google/android/setupdesign/GlifLayout.java
+++ b/main/src/com/google/android/setupdesign/GlifLayout.java
@@ -112,11 +112,8 @@
a.getBoolean(R.styleable.SudGlifLayout_sudUsePartnerHeavyTheme, false);
applyPartnerHeavyThemeResource = shouldApplyPartnerResource() && usePartnerHeavyTheme;
- registerMixin(
- HeaderMixin.class,
- new HeaderMixin(this, attrs, defStyleAttr));
- registerMixin(
- IconMixin.class, new IconMixin(this, attrs, defStyleAttr));
+ registerMixin(HeaderMixin.class, new HeaderMixin(this, attrs, defStyleAttr));
+ registerMixin(IconMixin.class, new IconMixin(this, attrs, defStyleAttr));
registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this));
final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this);
registerMixin(RequireScrollMixin.class, requireScrollMixin);
@@ -154,15 +151,19 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ getMixin(IconMixin.class).tryApplyPartnerCustomizationStyle();
+ getMixin(HeaderMixin.class).tryApplyPartnerCustomizationStyle();
+ tryApplyPartnerCustomizationStyleToShortDescription();
+ }
- TextView description = this.findManagedViewById(R.id.sud_layout_description);
- if (description != null) {
- if (applyPartnerHeavyThemeResource) {
+ private void tryApplyPartnerCustomizationStyleToShortDescription() {
+ if (applyPartnerHeavyThemeResource) {
+ TextView description =
+ this.findManagedViewById(com.google.android.setupdesign.R.id.sud_layout_description);
+ if (description != null) {
DescriptionStyler.applyPartnerCustomizationStyle(description);
}
}
- getMixin(IconMixin.class).applyPartnerCustomizationStyle();
- getMixin(HeaderMixin.class).applyPartnerCustomizationStyle();
}
@Override
diff --git a/main/src/com/google/android/setupdesign/util/LinkAccessibilityHelper.java b/main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java
similarity index 99%
rename from main/src/com/google/android/setupdesign/util/LinkAccessibilityHelper.java
rename to main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java
index fd0d17f..ed9daf3 100644
--- a/main/src/com/google/android/setupdesign/util/LinkAccessibilityHelper.java
+++ b/main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.android.setupdesign.util;
+package com.google.android.setupdesign.accessibility;
import android.graphics.Rect;
import android.os.Build;
diff --git a/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java b/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java
index 28b41c9..42438d6 100644
--- a/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java
+++ b/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
import androidx.core.view.AccessibilityDelegateCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
@@ -64,6 +65,22 @@
? AccessibilityActionCompat.ACTION_COLLAPSE
: AccessibilityActionCompat.ACTION_EXPAND);
}
+
+ @Override
+ public boolean performAccessibilityAction(View view, int action, Bundle args) {
+ boolean result;
+ switch (action) {
+ case AccessibilityNodeInfoCompat.ACTION_COLLAPSE:
+ case AccessibilityNodeInfoCompat.ACTION_EXPAND:
+ setExpanded(!isExpanded());
+ result = true;
+ break;
+ default:
+ result = super.performAccessibilityAction(view, action, args);
+ break;
+ }
+ return result;
+ }
};
public ExpandableSwitchItem() {
diff --git a/main/src/com/google/android/setupdesign/items/Item.java b/main/src/com/google/android/setupdesign/items/Item.java
index 6f0cea3..e5d173f 100644
--- a/main/src/com/google/android/setupdesign/items/Item.java
+++ b/main/src/com/google/android/setupdesign/items/Item.java
@@ -21,6 +21,7 @@
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import androidx.annotation.ColorInt;
+import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -37,10 +38,10 @@
public class Item extends AbstractItem {
private boolean enabled = true;
- private Drawable icon;
+ @Nullable private Drawable icon;
private int layoutRes;
- private CharSequence summary;
- private CharSequence title;
+ @Nullable private CharSequence summary;
+ @Nullable private CharSequence title;
private boolean visible = true;
@ColorInt private int iconTint = Color.TRANSPARENT;
private int iconGravity = Gravity.CENTER_VERTICAL;
@@ -83,11 +84,12 @@
return enabled;
}
- public void setIcon(Drawable icon) {
+ public void setIcon(@Nullable Drawable icon) {
this.icon = icon;
notifyItemChanged();
}
+ @Nullable
public Drawable getIcon() {
return icon;
}
@@ -119,20 +121,22 @@
return layoutRes;
}
- public void setSummary(CharSequence summary) {
+ public void setSummary(@Nullable CharSequence summary) {
this.summary = summary;
notifyItemChanged();
}
+ @Nullable
public CharSequence getSummary() {
return summary;
}
- public void setTitle(CharSequence title) {
+ public void setTitle(@Nullable CharSequence title) {
this.title = title;
notifyItemChanged();
}
+ @Nullable
public CharSequence getTitle() {
return title;
}
diff --git a/main/src/com/google/android/setupdesign/template/HeaderMixin.java b/main/src/com/google/android/setupdesign/template/HeaderMixin.java
index 51b726b..ef14d29 100644
--- a/main/src/com/google/android/setupdesign/template/HeaderMixin.java
+++ b/main/src/com/google/android/setupdesign/template/HeaderMixin.java
@@ -16,28 +16,20 @@
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.setupdesign.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;
-import com.google.android.setupdesign.GlifLayout;
-import java.util.Locale;
+import com.google.android.setupdesign.R;
+import com.google.android.setupdesign.util.HeaderAreaStyler;
+import com.google.android.setupdesign.util.PartnerStyleHelper;
/**
* A {@link com.google.android.setupcompat.template.Mixin} for setting and getting the header text.
@@ -75,64 +67,22 @@
a.recycle();
}
- /** See {@link #applyPartnerCustomizationStyle(Context, TextView)}. */
- public void applyPartnerCustomizationStyle() {
- final Context context = templateLayout.getContext();
- TextView header = templateLayout.findManagedViewById(R.id.suc_layout_title);
- applyPartnerCustomizationStyle(context, header);
- }
-
/**
- * Use the given {@code header} to apply heavy theme. If {@link
- * com.google.android.setupdesign.GlifLayout#shouldApplyPartnerHeavyThemeResource()} is true,
- * {@code header} can be customized style from partner configuration.
- *
- * @param context The context of client activity.
- * @param header The icon image to use for apply heavy theme.
+ * Tries to apply the partner customizations to the header text and background if the layout of
+ * this {@link HeaderMixin} is set to apply partner heavy theme resource.
*/
- private void applyPartnerCustomizationStyle(Context context, @Nullable TextView header) {
- if (header != null
- && (templateLayout instanceof GlifLayout)
- && ((GlifLayout) templateLayout).shouldApplyPartnerHeavyThemeResource()) {
- int textColor =
- PartnerConfigHelper.get(context)
- .getColor(context, PartnerConfig.CONFIG_HEADER_TEXT_COLOR);
- if (textColor != 0) {
- setTextColor(valueOf(textColor));
- }
+ public void tryApplyPartnerCustomizationStyle() {
+ if (!PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout)) {
+ return;
+ }
- 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(Locale.ROOT)) {
- 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);
+ TextView header = templateLayout.findManagedViewById(R.id.suc_layout_title);
+ if (header != null) {
+ HeaderAreaStyler.applyPartnerCustomizationHeaderStyle(header);
+ }
+ LinearLayout headerLayout = templateLayout.findManagedViewById(R.id.sud_layout_header);
+ if (headerLayout != null) {
+ HeaderAreaStyler.applyPartnerCustomizationHeaderAreaStyle(headerLayout);
}
}
@@ -171,13 +121,6 @@
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}.
@@ -202,20 +145,9 @@
}
}
- 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
index cfc498d..f74f87a 100644
--- a/main/src/com/google/android/setupdesign/template/IconMixin.java
+++ b/main/src/com/google/android/setupdesign/template/IconMixin.java
@@ -24,16 +24,14 @@
import android.os.Build.VERSION_CODES;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
-import androidx.annotation.Nullable;
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.GlifLayout;
import com.google.android.setupdesign.R;
+import com.google.android.setupdesign.util.HeaderAreaStyler;
import com.google.android.setupdesign.util.PartnerStyleHelper;
/**
@@ -86,29 +84,18 @@
a.recycle();
}
- /** See {@link #applyPartnerCustomizationStyle(Context, ImageView)}. */
- public void applyPartnerCustomizationStyle() {
- final Context context = templateLayout.getContext();
- final ImageView iconImage = templateLayout.findManagedViewById(R.id.sud_layout_icon);
- applyPartnerCustomizationStyle(context, iconImage);
- }
-
/**
- * Use the given {@code iconImage} to apply heavy theme. If {@link
- * com.google.android.setupdesign.GlifLayout#shouldApplyPartnerHeavyThemeResource()} is true,
- * {@code iconImage} can be customized style from partner configuration.
- *
- * @param context The context of client activity.
- * @param iconImage The icon image to use for apply heavy theme.
+ * Tries to apply the partner customization to the header icon if the layout of this {@link
+ * IconMixin} is set to apply partner heavy theme resource.
*/
- private void applyPartnerCustomizationStyle(Context context, @Nullable ImageView iconImage) {
- if (iconImage != null
- && (templateLayout instanceof GlifLayout)
- && ((GlifLayout) templateLayout).shouldApplyPartnerHeavyThemeResource()) {
- int gravity = PartnerStyleHelper.getLayoutGravity(context);
- if (gravity != 0) {
- setGravity(iconImage, gravity);
- }
+ public void tryApplyPartnerCustomizationStyle() {
+ if (!PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout)) {
+ return;
+ }
+
+ ImageView iconImage = templateLayout.findManagedViewById(R.id.sud_layout_icon);
+ if (iconImage != null) {
+ HeaderAreaStyler.applyPartnerCustomizationIconStyle(iconImage);
}
}
@@ -189,12 +176,4 @@
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/ContentStyler.java b/main/src/com/google/android/setupdesign/util/ContentStyler.java
new file mode 100644
index 0000000..0ab49b8
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/util/ContentStyler.java
@@ -0,0 +1,64 @@
+/*
+ * 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 android.widget.TextView;
+import com.google.android.setupcompat.partnerconfig.PartnerConfig;
+import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+import com.google.android.setupdesign.util.TextViewPartnerStyler.TextPartnerConfigs;
+import java.util.Locale;
+
+/**
+ * Applies the partner style of content to the given TextView {@code contentText}. The user needs to
+ * check if the {@code contentText} should apply partner heavy theme before calling this method.
+ */
+public final class ContentStyler {
+ public static void applyPartnerCustomizationStyle(TextView contentText) {
+
+ TextViewPartnerStyler.applyPartnerCustomizationStyle(
+ contentText,
+ new TextPartnerConfigs(
+ PartnerConfig.CONFIG_CONTENT_TEXT_COLOR,
+ PartnerConfig.CONFIG_CONTENT_LINK_TEXT_COLOR,
+ PartnerConfig.CONFIG_CONTENT_TEXT_SIZE,
+ PartnerConfig.CONFIG_CONTENT_FONT_FAMILY,
+ ContentStyler.getPartnerContentTextGravity(contentText.getContext())));
+ }
+
+ public static int getPartnerContentTextGravity(Context context) {
+ String gravity =
+ PartnerConfigHelper.get(context)
+ .getString(context, PartnerConfig.CONFIG_CONTENT_LAYOUT_GRAVITY);
+ if (gravity == null) {
+ return 0;
+ }
+ switch (gravity.toLowerCase(Locale.ROOT)) {
+ case "center":
+ return Gravity.CENTER;
+ case "start":
+ return Gravity.START;
+ case "end":
+ return Gravity.END;
+ default:
+ return 0;
+ }
+ }
+
+ private ContentStyler() {}
+}
diff --git a/main/src/com/google/android/setupdesign/util/DescriptionStyler.java b/main/src/com/google/android/setupdesign/util/DescriptionStyler.java
index d4e7ded..0a05f9d 100644
--- a/main/src/com/google/android/setupdesign/util/DescriptionStyler.java
+++ b/main/src/com/google/android/setupdesign/util/DescriptionStyler.java
@@ -1,84 +1,43 @@
+/*
+ * 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.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;
+import com.google.android.setupdesign.util.TextViewPartnerStyler.TextPartnerConfigs;
-/** Applies the given style properties for the style of the given type. */
-public class DescriptionStyler {
+/**
+ * Applies the partner style of description to the given TextView {@code description}. The user
+ * needs to check if the {@code description} should apply partner heavy theme before calling this
+ * method.
+ */
+public final 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));
+ TextViewPartnerStyler.applyPartnerCustomizationStyle(
+ description,
+ new TextPartnerConfigs(
+ PartnerConfig.CONFIG_DESCRIPTION_TEXT_COLOR,
+ PartnerConfig.CONFIG_DESCRIPTION_LINK_TEXT_COLOR,
+ PartnerConfig.CONFIG_DESCRIPTION_TEXT_SIZE,
+ PartnerConfig.CONFIG_DESCRIPTION_FONT_FAMILY,
+ PartnerStyleHelper.getLayoutGravity(description.getContext())));
}
- @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);
- }
- }
+ private DescriptionStyler() {}
}
diff --git a/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java b/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java
new file mode 100644
index 0000000..cd5135d
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java
@@ -0,0 +1,86 @@
+/*
+ * 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 androidx.annotation.Nullable;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.google.android.setupcompat.partnerconfig.PartnerConfig;
+import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+import com.google.android.setupdesign.util.TextViewPartnerStyler.TextPartnerConfigs;
+
+/**
+ * Helper class to apply the partner customization for the header area widgets. The user needs to
+ * check if the header area widgets should apply partner heavy theme before calling these methods.
+ */
+public final class HeaderAreaStyler {
+
+ /** Applies the partner style of header text to the given textView {@code header}. */
+ public static void applyPartnerCustomizationHeaderStyle(@Nullable TextView header) {
+
+ if (header == null) {
+ return;
+ }
+ TextViewPartnerStyler.applyPartnerCustomizationStyle(
+ header,
+ new TextPartnerConfigs(
+ PartnerConfig.CONFIG_HEADER_TEXT_COLOR,
+ null,
+ PartnerConfig.CONFIG_HEADER_TEXT_SIZE,
+ PartnerConfig.CONFIG_HEADER_FONT_FAMILY,
+ PartnerStyleHelper.getLayoutGravity(header.getContext())));
+ }
+
+ /** Applies the partner style of header background to the given layout {@code headerArea}. */
+ public static void applyPartnerCustomizationHeaderAreaStyle(ViewGroup headerArea) {
+
+ if (headerArea == null) {
+ return;
+ }
+ Context context = headerArea.getContext();
+ int color =
+ PartnerConfigHelper.get(context)
+ .getColor(context, PartnerConfig.CONFIG_HEADER_AREA_BACKGROUND_COLOR);
+ headerArea.setBackgroundColor(color);
+ }
+
+ /** Applies the partner style of header icon to the given {@code iconImage}. */
+ public static void applyPartnerCustomizationIconStyle(@Nullable ImageView iconImage) {
+
+ if (iconImage == null) {
+ return;
+ }
+
+ int gravity = PartnerStyleHelper.getLayoutGravity(iconImage.getContext());
+ if (gravity != 0) {
+ setGravity(iconImage, gravity);
+ }
+ }
+
+ private static 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);
+ }
+ }
+
+ private HeaderAreaStyler() {}
+}
diff --git a/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java b/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java
index c4e0162..d1d4a26 100644
--- a/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java
+++ b/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java
@@ -18,26 +18,44 @@
import android.content.Context;
import android.view.Gravity;
+import android.widget.FrameLayout;
import com.google.android.setupcompat.partnerconfig.PartnerConfig;
import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+import com.google.android.setupdesign.GlifLayout;
import java.util.Locale;
/** The helper reads styles from the partner configurations. */
-public class PartnerStyleHelper {
+public final class PartnerStyleHelper {
+ /**
+ * Returns the partner configuration of layout gravity, usually apply to wigets in header area.
+ */
public static int getLayoutGravity(Context context) {
String gravity =
PartnerConfigHelper.get(context).getString(context, PartnerConfig.CONFIG_LAYOUT_GRAVITY);
- if (gravity != null) {
- switch (gravity.toLowerCase(Locale.ROOT)) {
- case "center":
- return Gravity.CENTER;
- case "start":
- return Gravity.START;
- default:
- return 0;
- }
+ if (gravity == null) {
+ return 0;
}
- return 0;
+ switch (gravity.toLowerCase(Locale.ROOT)) {
+ case "center":
+ return Gravity.CENTER;
+ case "start":
+ return Gravity.START;
+ default:
+ return 0;
+ }
}
+
+ /** Returns the given layout if apply partner heavy theme. */
+ public static boolean isPartnerHeavyThemeLayout(FrameLayout layout) {
+ if (!(layout instanceof GlifLayout)) {
+ return false;
+ }
+ if (!((GlifLayout) layout).shouldApplyPartnerHeavyThemeResource()) {
+ return false;
+ }
+ return true;
+ }
+
+ private PartnerStyleHelper() {}
}
diff --git a/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java b/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java
new file mode 100644
index 0000000..552102e
--- /dev/null
+++ b/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java
@@ -0,0 +1,123 @@
+/*
+ * 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.graphics.Typeface;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.util.TypedValue;
+import android.widget.TextView;
+import com.google.android.setupcompat.partnerconfig.PartnerConfig;
+import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
+
+/** Helper class to apply partner configurations to a textView. */
+final class TextViewPartnerStyler {
+
+ /** Applies given partner configurations {@code textPartnerConfigs} to the {@code textView}. */
+ public static void applyPartnerCustomizationStyle(
+ @NonNull TextView textView, @NonNull TextPartnerConfigs textPartnerConfigs) {
+
+ if (textView == null || textPartnerConfigs == null) {
+ return;
+ }
+
+ Context context = textView.getContext();
+ if (textPartnerConfigs.getTextColorConfig() != null) {
+ int textColor =
+ PartnerConfigHelper.get(context)
+ .getColor(context, textPartnerConfigs.getTextColorConfig());
+ if (textColor != 0) {
+ textView.setTextColor(textColor);
+ }
+ }
+
+ if (textPartnerConfigs.getTextLinkedColorConfig() != null) {
+ int linkTextColor =
+ PartnerConfigHelper.get(context)
+ .getColor(context, textPartnerConfigs.getTextLinkedColorConfig());
+ if (linkTextColor != 0) {
+ textView.setLinkTextColor(linkTextColor);
+ }
+ }
+
+ if (textPartnerConfigs.getTextSizeConfig() != null) {
+ float textSize =
+ PartnerConfigHelper.get(context)
+ .getDimension(context, textPartnerConfigs.getTextSizeConfig(), 0);
+ if (textSize > 0) {
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
+ }
+ }
+
+ if (textPartnerConfigs.getTextFontFamilyConfig() != null) {
+ String fontFamilyName =
+ PartnerConfigHelper.get(context)
+ .getString(context, textPartnerConfigs.getTextFontFamilyConfig());
+ Typeface font = Typeface.create(fontFamilyName, Typeface.NORMAL);
+ if (font != null) {
+ textView.setTypeface(font);
+ }
+ }
+
+ textView.setGravity(textPartnerConfigs.getTextGravity());
+ }
+
+ /** Keeps the partner conflagrations for a textView. */
+ public static class TextPartnerConfigs {
+ private final PartnerConfig textColorConfig;
+ private final PartnerConfig textLinkedColorConfig;
+ private final PartnerConfig textSizeConfig;
+ private final PartnerConfig textFontFamilyConfig;
+ private final int textGravity;
+
+ public TextPartnerConfigs(
+ @Nullable PartnerConfig textColorConfig,
+ @Nullable PartnerConfig textLinkedColorConfig,
+ @Nullable PartnerConfig textSizeConfig,
+ @Nullable PartnerConfig textFontFamilyConfig,
+ int textGravity) {
+ this.textColorConfig = textColorConfig;
+ this.textLinkedColorConfig = textLinkedColorConfig;
+ this.textSizeConfig = textSizeConfig;
+ this.textFontFamilyConfig = textFontFamilyConfig;
+ this.textGravity = textGravity;
+ }
+
+ public PartnerConfig getTextColorConfig() {
+ return textColorConfig;
+ }
+
+ public PartnerConfig getTextLinkedColorConfig() {
+ return textLinkedColorConfig;
+ }
+
+ public PartnerConfig getTextSizeConfig() {
+ return textSizeConfig;
+ }
+
+ public PartnerConfig getTextFontFamilyConfig() {
+ return textFontFamilyConfig;
+ }
+
+ public int getTextGravity() {
+ return textGravity;
+ }
+ }
+
+ private TextViewPartnerStyler() {}
+}
diff --git a/main/src/com/google/android/setupdesign/view/HeaderRecyclerView.java b/main/src/com/google/android/setupdesign/view/HeaderRecyclerView.java
index 0e40875..b3161fd 100644
--- a/main/src/com/google/android/setupdesign/view/HeaderRecyclerView.java
+++ b/main/src/com/google/android/setupdesign/view/HeaderRecyclerView.java
@@ -21,6 +21,7 @@
import android.os.Build;
import androidx.recyclerview.widget.RecyclerView;
import android.util.AttributeSet;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -238,6 +239,107 @@
}
}
+ private boolean handleDpadDown() {
+ View focusedView = findFocus();
+ if (focusedView == null) {
+ return false;
+ }
+
+ int[] focusdLocationInWindow = new int[2];
+ int[] myLocationInWindow = new int[2];
+
+ focusedView.getLocationInWindow(focusdLocationInWindow);
+ getLocationInWindow(myLocationInWindow);
+
+ int offset =
+ (focusdLocationInWindow[1] + focusedView.getMeasuredHeight())
+ - (myLocationInWindow[1] + getMeasuredHeight());
+
+ /*
+ (focusdLocationInWindow[1] + focusedView.getMeasuredHeight())
+ is the bottom position of focused view
+
+ (myLocationInWindow[1] + getMeasuredHeight())
+ is the bottom position of recycler view
+
+ If the bottom of focused view is out of recycler view, means we need to scroll down to show
+ more detail
+
+ We scroll 70% of recycler view to make sure user can have 30% of previous information, to make
+ sure user can keep reading easily.
+ */
+ if (offset > 0) {
+ // We expect only scroll 70% of recycler view
+ int scrollLength = (int) (getMeasuredHeight() * 0.7f);
+ smoothScrollBy(0, Math.min(scrollLength, offset));
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean handleDpadUp() {
+ View focusedView = findFocus();
+ if (focusedView == null) {
+ return false;
+ }
+
+ int[] focusedLocationInWindow = new int[2];
+ int[] myLocationInWindow = new int[2];
+
+ focusedView.getLocationInWindow(focusedLocationInWindow);
+ getLocationInWindow(myLocationInWindow);
+
+ int offset = (focusedLocationInWindow[1] - myLocationInWindow[1]);
+
+ /*
+ focusedLocationInWindow[1] is top of focused view
+ myLocationInWindow[1] is top of recycler view
+
+ If top of focused view is higher than recycler view we need scroll up to show more information
+ we try to scroll up 70% of recycler view ot scroll up to the top of focused view
+ */
+ if (offset < 0) {
+ // We expect only scroll 70% of recycler view
+ int scrollLength = (int) (getMeasuredHeight() * -0.7f);
+
+ smoothScrollBy(0, Math.max(scrollLength, offset));
+ return true;
+ }
+ return false;
+ }
+
+ private boolean shouldHandleActionUp = false;
+
+ private boolean handleKeyEvent(KeyEvent keyEvent) {
+ if (shouldHandleActionUp && keyEvent.getAction() == KeyEvent.ACTION_UP) {
+ shouldHandleActionUp = false;
+ return true;
+ } else if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+ boolean eventHandled = false;
+ switch (keyEvent.getKeyCode()) {
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ eventHandled = handleDpadDown();
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ eventHandled = handleDpadUp();
+ break;
+ default: // fall out
+ }
+ shouldHandleActionUp = eventHandled;
+ return eventHandled;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (handleKeyEvent(event)) {
+ return true;
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
/** Gets the header view of this RecyclerView, or {@code null} if there are no headers. */
public View getHeader() {
return header;
diff --git a/main/src/com/google/android/setupdesign/view/RichTextView.java b/main/src/com/google/android/setupdesign/view/RichTextView.java
index c264947..338b856 100644
--- a/main/src/com/google/android/setupdesign/view/RichTextView.java
+++ b/main/src/com/google/android/setupdesign/view/RichTextView.java
@@ -32,10 +32,10 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
+import com.google.android.setupdesign.accessibility.LinkAccessibilityHelper;
import com.google.android.setupdesign.span.LinkSpan;
import com.google.android.setupdesign.span.LinkSpan.OnLinkClickListener;
import com.google.android.setupdesign.span.SpanHelper;
-import com.google.android.setupdesign.util.LinkAccessibilityHelper;
import com.google.android.setupdesign.view.TouchableMovementMethod.TouchableLinkMovementMethod;
/**