Skip to content

Commit

Permalink
[M3][Color] Updated color harmonization demo
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 446199668
(cherry picked from commit dc65df3)
  • Loading branch information
Material Design Team authored and dsn5ft committed May 4, 2022
1 parent b402cb3 commit 1dbd3dd
Show file tree
Hide file tree
Showing 10 changed files with 598 additions and 146 deletions.
Expand Up @@ -17,7 +17,7 @@
package io.material.catalog.color;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
Expand All @@ -32,7 +32,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for {@link ColorHarmonizationFragment} */
/** Tests for {@link ColorHarmonizationDemoFragment} */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class ColorHarmonizationDemoFragmentTest {
Expand All @@ -57,11 +57,34 @@ public void setUpAndLaunchFragment() {
}

@Test
public void checkColorHexValueTextIsShown() {
onView(withId(R.id.cat_color_enabled_switch)).perform(click());
public void checkButtonsAreShown() {
onView(withId(R.id.red_button_dark)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.red_button_light)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.yellow_button_dark)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.yellow_button_light)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.green_button_dark)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.green_button_light)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.blue_button_dark)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.blue_button_light)).perform(scrollTo()).check(matches(isDisplayed()));
}

onView(withId(R.id.material_button_color_hex_value)).check(matches(isDisplayed()));
onView(withId(R.id.material_unelevated_button_color_hex_value)).check(matches(isDisplayed()));
onView(withId(R.id.material_text_input_color_hex_value)).check(matches(isDisplayed()));
@Test
public void checkColorPalettesAreShown() {
onView(withId(R.id.cat_colors_error)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_harmonized_error))
.perform(scrollTo())
.check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_yellow)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_harmonized_yellow))
.perform(scrollTo())
.check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_green)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_harmonized_green))
.perform(scrollTo())
.check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_blue)).perform(scrollTo()).check(matches(isDisplayed()));
onView(withId(R.id.cat_colors_harmonized_blue))
.perform(scrollTo())
.check(matches(isDisplayed()));
}
}
2 changes: 1 addition & 1 deletion catalog/java/io/material/catalog/color/ColorGrid.java
Expand Up @@ -35,7 +35,7 @@ final class ColorGrid {
@NonNull private final MaterialColorSpec materialColorSpecAccentContainer;
@NonNull private final MaterialColorSpec materialColorSpecOnAccentContainer;

static ColorGrid createFromColorGridData(Context context, ColorGridData colorGridData) {
static ColorGrid createFromColorGridData(ColorGridData colorGridData) {
ColorRoles colorRoles = colorGridData.getColorRoles();
ColorRoleNames colorRoleNames = colorGridData.getColorRoleNames();
MaterialColorSpec[] materialColorSpecs =
Expand Down
Expand Up @@ -18,88 +18,137 @@

import io.material.catalog.R;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.LayoutRes;
import android.widget.LinearLayout;
import androidx.annotation.IdRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.color.DynamicColors;
import com.google.android.material.color.HarmonizedColors;
import com.google.android.material.color.HarmonizedColorsOptions;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputLayout;
import io.material.catalog.feature.DemoFragment;
import java.util.ArrayList;
import java.util.List;

/** A fragment that displays the Color Harmonization demo for the Catalog app. */
public class ColorHarmonizationDemoFragment extends DemoFragment {

private static final int GREEN_RESOURCE_ID = R.color.green40;
private static final int RED_RESOURCE_ID = R.color.red40;
private static final int BLUE_RESOURCE_ID = R.color.blue90;
private static final HarmonizableButtonData[] HARMONIZABLE_BUTTON_DATA_LIST =
new HarmonizableButtonData[] {
new HarmonizableButtonData(
R.id.red_button_dark, R.color.error_reference, /* isLightButton= */ false),
new HarmonizableButtonData(
R.id.red_button_light, R.color.error_reference, /* isLightButton= */ true),
new HarmonizableButtonData(
R.id.yellow_button_dark, R.color.yellow_reference, /* isLightButton= */ false),
new HarmonizableButtonData(
R.id.yellow_button_light, R.color.yellow_reference, /* isLightButton= */ true),
new HarmonizableButtonData(
R.id.green_button_dark, R.color.green_reference, /* isLightButton= */ false),
new HarmonizableButtonData(
R.id.green_button_light, R.color.green_reference, /* isLightButton= */ true),
new HarmonizableButtonData(
R.id.blue_button_dark, R.color.blue_reference, /* isLightButton= */ false),
new HarmonizableButtonData(
R.id.blue_button_light, R.color.blue_reference, /* isLightButton= */ true),
};
// TODO(b/231143697): Refactor this class to a DemoActivity and showcase harmonization using
// error color attributes.
private static final ColorHarmonizationGridRowData[] HARMONIZATION_GRID_ROW_DATA_LIST =
new ColorHarmonizationGridRowData[] {
new ColorHarmonizationGridRowData(
R.id.cat_colors_error,
R.id.cat_colors_harmonized_error,
R.color.error_reference,
R.array.cat_error_strings),
new ColorHarmonizationGridRowData(
R.id.cat_colors_yellow,
R.id.cat_colors_harmonized_yellow,
R.color.yellow_reference,
R.array.cat_yellow_strings),
new ColorHarmonizationGridRowData(
R.id.cat_colors_green,
R.id.cat_colors_harmonized_green,
R.color.green_reference,
R.array.cat_green_strings),
new ColorHarmonizationGridRowData(
R.id.cat_colors_blue,
R.id.cat_colors_harmonized_blue,
R.color.blue_reference,
R.array.cat_blue_strings)
};

private Context dynamicColorsContext;
private Context harmonizedContext;
private View demoView;

private final List<HarmonizableButton> harmonizableButtonList = new ArrayList<>();

@Nullable
@Override
public View onCreateDemoView(
@Nullable LayoutInflater layoutInflater,
@Nullable ViewGroup viewGroup,
@Nullable Bundle bundle) {
View view = layoutInflater.inflate(getColorsContent(), viewGroup, false /* attachToRoot */);
MaterialButton elevatedButton = view.findViewById(R.id.material_button);
MaterialButton unelevatedButton = view.findViewById(R.id.material_unelevated_button);
TextInputLayout textInputLayout = view.findViewById(R.id.material_text_input_layout);
TextView buttonColorHexValueText = view.findViewById(R.id.material_button_color_hex_value);
TextView unelevatedButtonColorHexValueText =
view.findViewById(R.id.material_unelevated_button_color_hex_value);
TextView textInputColorHexValueText =
view.findViewById(R.id.material_text_input_color_hex_value);

elevatedButton.setBackgroundColor(getResources().getColor(GREEN_RESOURCE_ID));
unelevatedButton.setBackgroundColor(getResources().getColor(RED_RESOURCE_ID));
textInputLayout.setBoxBackgroundColor(getResources().getColor(BLUE_RESOURCE_ID));

SwitchMaterial enabledSwitch = view.findViewById(R.id.cat_color_enabled_switch);
enabledSwitch.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
buttonColorHexValueText.setVisibility(View.VISIBLE);
unelevatedButtonColorHexValueText.setVisibility(View.VISIBLE);
textInputColorHexValueText.setVisibility(View.VISIBLE);
demoView =
layoutInflater.inflate(
R.layout.cat_colors_harmonization_fragment, viewGroup, false /* attachToRoot */);

int maybeHarmonizedGreen = maybeHarmonizeWithPrimary(GREEN_RESOURCE_ID, isChecked);
int maybeHarmonizedRed = maybeHarmonizeWithPrimary(RED_RESOURCE_ID, isChecked);
int maybeHarmonizedBlue = maybeHarmonizeWithPrimary(BLUE_RESOURCE_ID, isChecked);

elevatedButton.setBackgroundColor(maybeHarmonizedGreen);
unelevatedButton.setBackgroundColor(maybeHarmonizedRed);
textInputLayout.setBoxBackgroundColor(maybeHarmonizedBlue);

// The %06X gives us zero-padded hex (always 6 chars long).
buttonColorHexValueText.setText(
getColorHexValueText(R.string.cat_color_hex_value_text, maybeHarmonizedGreen));
unelevatedButtonColorHexValueText.setText(
getColorHexValueText(R.string.cat_color_hex_value_text, maybeHarmonizedRed));
textInputColorHexValueText.setText(
getColorHexValueText(R.string.cat_color_hex_value_text, maybeHarmonizedBlue));
});

return view;
}
dynamicColorsContext = DynamicColors.wrapContextIfAvailable(requireContext());
HarmonizedColorsOptions options =
new HarmonizedColorsOptions.Builder()
.setColorResourceIds(
new int[] {
R.color.error_reference,
R.color.yellow_reference,
R.color.blue_reference,
R.color.green_reference,
})
.build();
harmonizedContext = HarmonizedColors.wrapContextIfAvailable(dynamicColorsContext, options);

private int maybeHarmonizeWithPrimary(@ColorRes int colorResId, boolean harmonize) {
return harmonize
? MaterialColors.harmonizeWithPrimary(getContext(), getResources().getColor(colorResId))
: getResources().getColor(colorResId);
for (ColorHarmonizationGridRowData colorHarmonizationGridRowData :
HARMONIZATION_GRID_ROW_DATA_LIST) {
createColorGridAndPopulateLayout(
dynamicColorsContext,
colorHarmonizationGridRowData,
colorHarmonizationGridRowData.getLeftLayoutId());
createColorGridAndPopulateLayout(
harmonizedContext,
colorHarmonizationGridRowData,
colorHarmonizationGridRowData.getRightLayoutId());
}
// Setup buttons text color based on current theme.
for (HarmonizableButtonData harmonizableButtonData : HARMONIZABLE_BUTTON_DATA_LIST) {
harmonizableButtonList.add(HarmonizableButton.create(demoView, harmonizableButtonData));
}
updateButtons(/* harmonize= */ false);
SwitchMaterial enabledSwitch = demoView.findViewById(R.id.cat_color_enabled_switch);
enabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> updateButtons(isChecked));
return demoView;
}

private CharSequence getColorHexValueText(@StringRes int stringResId, @ColorInt int color) {
return getResources().getString(stringResId, String.format("#%06X", (0xFFFFFF & color)));
private void createColorGridAndPopulateLayout(
Context context,
ColorHarmonizationGridRowData colorHarmonizationGridRowData,
@IdRes int layoutId) {
ColorGrid colorGrid =
ColorGrid.createFromColorGridData(
ColorGridData.createFromColorResId(
context,
colorHarmonizationGridRowData.getColorResId(),
colorHarmonizationGridRowData.getColorNameIds()));
LinearLayout layout = demoView.findViewById(layoutId);
layout.addView(colorGrid.renderView(context, layout));
}

@LayoutRes
protected int getColorsContent() {
return R.layout.cat_colors_harmonization_fragment;
private void updateButtons(boolean harmonize) {
for (HarmonizableButton button : harmonizableButtonList) {
button.updateColors(harmonize);
}
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2022 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 io.material.catalog.color;

import androidx.annotation.ArrayRes;
import androidx.annotation.ColorRes;
import androidx.annotation.IdRes;

/** A class that provides data for a row in the Color Harmonization demo grid. */
final class ColorHarmonizationGridRowData {

@IdRes private final int leftLayoutId;
@IdRes private final int rightLayoutId;
@ColorRes private final int colorResId;
@ArrayRes private final int colorNameIds;

ColorHarmonizationGridRowData(
@IdRes int leftLayoutId,
@IdRes int rightLayoutId,
@ColorRes int colorResId,
@ArrayRes int colorNameIds) {
this.leftLayoutId = leftLayoutId;
this.rightLayoutId = rightLayoutId;
this.colorResId = colorResId;
this.colorNameIds = colorNameIds;
}

@IdRes
int getLeftLayoutId() {
return leftLayoutId;
}

@IdRes
int getRightLayoutId() {
return rightLayoutId;
}

@ColorRes
int getColorResId() {
return colorResId;
}

@ArrayRes
int getColorNameIds() {
return colorNameIds;
}
}
15 changes: 3 additions & 12 deletions catalog/java/io/material/catalog/color/ColorRow.java
Expand Up @@ -18,7 +18,6 @@

import io.material.catalog.R;

import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
Expand Down Expand Up @@ -75,16 +74,8 @@ private void bindColorRoleItem(
TextView colorRole = view.findViewById(textViewId);

colorRole.setText(colorRoleTextResID);
colorRole.setTextColor(getTextColor(colorAttrResId));
colorRole.setBackgroundColor(MaterialColors.getColor(view, colorAttrResId));
}

private int getTextColor(@AttrRes int colorAttrResId) {
if (!MaterialColors.isColorLight(MaterialColors.getColor(catColorsSchemeRow, colorAttrResId))) {
// Use white text color if the color is considered dark.
return Color.WHITE;
} else {
return Color.BLACK;
}
colorRole.setTextColor(
ColorDemoUtils.getTextColor(MaterialColors.getColor(catColorsSchemeRow, colorAttrResId)));
colorRole.setBackgroundColor(MaterialColors.getColor(catColorsSchemeRow, colorAttrResId));
}
}

0 comments on commit 1dbd3dd

Please sign in to comment.