diff --git a/catalog/java/io/material/catalog/assets/res/drawable/ic_content_copy_24px.xml b/catalog/java/io/material/catalog/assets/res/drawable/ic_content_copy_24px.xml new file mode 100644 index 00000000000..000645ca631 --- /dev/null +++ b/catalog/java/io/material/catalog/assets/res/drawable/ic_content_copy_24px.xml @@ -0,0 +1,25 @@ + + + + diff --git a/catalog/java/io/material/catalog/color/ColorAdapterItem.java b/catalog/java/io/material/catalog/color/ColorAdapterItem.java new file mode 100644 index 00000000000..61ee51ecd42 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorAdapterItem.java @@ -0,0 +1,20 @@ +/* + * Copyright 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 io.material.catalog.color; + +/** Interface for the items in {@link ColorsAdapter}. */ +public interface ColorAdapterItem {} diff --git a/catalog/java/io/material/catalog/color/ColorDynamicDemoFragment.java b/catalog/java/io/material/catalog/color/ColorDynamicDemoFragment.java new file mode 100644 index 00000000000..02e3c8ad740 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorDynamicDemoFragment.java @@ -0,0 +1,38 @@ +/* + * Copyright 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 io.material.catalog.color; + +import io.material.catalog.R; + +import androidx.annotation.ArrayRes; +import androidx.annotation.LayoutRes; + +/** A fragment that displays the Dynamic Palette demo for the Catalog app. */ +public class ColorDynamicDemoFragment extends ColorPaletteDemoFragment { + + @LayoutRes + @Override + protected int getColorsLayoutResId() { + return R.layout.cat_colors_palette_fragment; + } + + @ArrayRes + @Override + protected int getColorsArrayResId() { + return R.array.cat_dynamic_colors; + } +} diff --git a/catalog/java/io/material/catalog/color/ColorHeaderItem.java b/catalog/java/io/material/catalog/color/ColorHeaderItem.java new file mode 100644 index 00000000000..c2304562130 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorHeaderItem.java @@ -0,0 +1,63 @@ +/* + * Copyright 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 io.material.catalog.color; + +import android.content.Context; +import androidx.annotation.ColorRes; +import androidx.annotation.NonNull; +import java.util.List; + +/** A class for the headers in the color palette. */ +public class ColorHeaderItem implements ColorAdapterItem { + + private static final String COLOR_600 = "600"; + + @ColorRes private final int backgroundColor; + private final String name; + + ColorHeaderItem(Context context, List colors) { + ColorItem sample = colors.get(0); + for (ColorItem color : colors) { + if (color.getColorResName().contains(COLOR_600)) { + sample = color; + break; + } + } + MaterialColorSpec materialColor = MaterialColorSpec.create(context, sample.getColorRes()); + backgroundColor = materialColor.getResourceId(); + name = materialColor.getName(); + } + + @ColorRes + int getBackgroundColorRes() { + return backgroundColor; + } + + /** Returns the raw name of the color. */ + @NonNull + public String getName() { + return name; + } + + /** Returns the display name for the header, e.g. Blue. */ + @NonNull + public String getDisplayName() { + String name = getName(); + String headerColor = name.replace('_', ' '); + return Character.toUpperCase(headerColor.charAt(0)) + headerColor.substring(1); + } +} diff --git a/catalog/java/io/material/catalog/color/ColorItem.java b/catalog/java/io/material/catalog/color/ColorItem.java new file mode 100644 index 00000000000..7864e6cc5b3 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorItem.java @@ -0,0 +1,51 @@ +/* + * Copyright 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 io.material.catalog.color; + +import android.content.Context; +import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; +import androidx.annotation.NonNull; + +/** A class for the items in the color palette. */ +public class ColorItem implements ColorAdapterItem { + + private final MaterialColorSpec colorSpec; + + ColorItem(Context context, @ColorRes int colorRes) { + colorSpec = MaterialColorSpec.create(context, colorRes); + } + + /** Returns the resource ID of the color. */ + @NonNull + @ColorRes + public int getColorRes() { + return colorSpec.getResourceId(); + } + + /** Returns the resource name of the color, e.g. system_accent1_100. */ + @NonNull + public String getColorResName() { + return colorSpec.getResourceName(); + } + + /** Returns the int value of the color. */ + @ColorInt + int getColorValue() { + return colorSpec.getValue(); + } +} diff --git a/catalog/java/io/material/catalog/color/ColorMainDemoFragment.java b/catalog/java/io/material/catalog/color/ColorMainDemoFragment.java new file mode 100644 index 00000000000..7b000f309a4 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorMainDemoFragment.java @@ -0,0 +1,41 @@ +/* + * Copyright 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 io.material.catalog.color; + +import io.material.catalog.R; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import io.material.catalog.feature.DemoFragment; + +/** A placeholder fragment that displays the main Color demo for the Catalog app. */ +public class ColorMainDemoFragment extends DemoFragment { + + @Nullable + @Override + public View onCreateDemoView( + @NonNull LayoutInflater layoutInflater, + @Nullable ViewGroup viewGroup, + @Nullable Bundle bundle) { + return layoutInflater.inflate( + R.layout.cat_colors_fragment, viewGroup, false /* attachToRoot */); + } +} diff --git a/catalog/java/io/material/catalog/color/ColorPaletteDemoFragment.java b/catalog/java/io/material/catalog/color/ColorPaletteDemoFragment.java new file mode 100644 index 00000000000..42c4bacd651 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorPaletteDemoFragment.java @@ -0,0 +1,185 @@ +/* + * Copyright 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 io.material.catalog.color; + +import io.material.catalog.R; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.ViewHolder; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.ArrayRes; +import androidx.annotation.ColorInt; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import io.material.catalog.feature.DemoFragment; + +/** A fragment that displays the Color Palette demo for the Catalog app. */ +public abstract class ColorPaletteDemoFragment extends DemoFragment { + + private static final int GREY_10 = 0xFF202124; + + private ColorsAdapter adapter; + + @Nullable + @Override + public View onCreateDemoView( + @NonNull LayoutInflater layoutInflater, + @Nullable ViewGroup viewGroup, + @Nullable Bundle bundle) { + View view = layoutInflater.inflate(getColorsLayoutResId(), viewGroup, false /* attachToRoot */); + + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + adapter = new ColorsAdapter(getContext(), getColorsArrayResId()); + recyclerView.setAdapter(adapter); + recyclerView.addItemDecoration(new ColorSectionsItemDecoration(getContext(), adapter)); + + return view; + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) { + menuInflater.inflate(R.menu.cat_colors_menu, menu); + super.onCreateOptionsMenu(menu, menuInflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem menuItem) { + if (menuItem.getItemId() == R.id.copy_colors) { + Context context = requireContext(); + ClipboardManager clipboard = + (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Colors", generateColorsText(adapter)); + clipboard.setPrimaryClip(clip); + Toast.makeText(context, "Copied colors to clipboard.", Toast.LENGTH_LONG).show(); + return true; + } + return super.onOptionsItemSelected(menuItem); + } + + @LayoutRes + protected abstract int getColorsLayoutResId(); + + /** + * Returns an array of array resources containing a list of colors resource. Each group of colors + * will be displayed in a list. + */ + @ArrayRes + protected abstract int getColorsArrayResId(); + + /** View holder class for the header of the color palette. */ + static class ColorHeaderViewHolder extends ViewHolder { + + private final TextView header; + + ColorHeaderViewHolder(ViewGroup parent) { + super( + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.cat_colors_palette_header, parent, false)); + + header = (TextView) itemView; + } + + void bind(ColorHeaderItem headerItem) { + header.setText(headerItem.getDisplayName()); + header.setBackgroundResource(headerItem.getBackgroundColorRes()); + } + } + + /** View holder class for the items of the color palette. */ + static class ColorViewHolder extends ViewHolder { + + private final Context context; + private final TextView nameView; + private final TextView descriptionView; + + ColorViewHolder(ViewGroup parent) { + super( + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.cat_colors_palette_item, parent, false)); + + nameView = itemView.findViewById(R.id.name); + descriptionView = itemView.findViewById(R.id.description); + context = itemView.getContext(); + } + + void bind(ColorItem colorItem) { + int value = ContextCompat.getColor(context, colorItem.getColorRes()); + String colorResName = colorItem.getColorResName(); + String resQualifier = + colorResName.startsWith(MaterialColorSpec.SYSTEM_PREFIX) ? "@android:color/" : "@color/"; + + nameView.setText( + context.getResources().getString(R.string.cat_color_res, resQualifier, colorResName)); + descriptionView.setText(String.format("#%06x", value & 0xFFFFFF)); + + int textColor = getTextColor(colorItem); + nameView.setTextColor(textColor); + descriptionView.setTextColor(textColor); + + itemView.setBackgroundResource(colorItem.getColorRes()); + } + + @ColorInt + private int getTextColor(ColorItem colorItem) { + if (colorItem.getColorValue() < MaterialColorSpec.TEXT_COLOR_SWITCH_VALUE) { + // Use dark grey if color value is less than TEXT_COLOR_SWITCH_VALUE. + return GREY_10; + } else { + return Color.WHITE; + } + } + } + + private String generateColorsText(@NonNull ColorsAdapter adapter) { + StringBuilder colorsText = new StringBuilder(); + for (ColorAdapterItem item : adapter.getItems()) { + if (item instanceof ColorHeaderItem) { + if (colorsText.length() > 0) { + colorsText.append("\n"); + } + colorsText.append(((ColorHeaderItem) item).getDisplayName()).append("\n"); + } else if (item instanceof ColorItem) { + ColorItem colorItem = (ColorItem) item; + int value = ContextCompat.getColor(getContext(), colorItem.getColorRes()); + String colorResName = colorItem.getColorResName(); + String resQualifier = + colorResName.startsWith(MaterialColorSpec.SYSTEM_PREFIX) + ? "@android:color/" + : "@color/"; + colorsText.append(String.format("#%06x", value & 0xFFFFFF)).append("\n"); + colorsText.append(resQualifier).append(colorResName).append("\n"); + } + } + return colorsText.toString(); + } +} diff --git a/catalog/java/io/material/catalog/color/ColorSectionsItemDecoration.java b/catalog/java/io/material/catalog/color/ColorSectionsItemDecoration.java new file mode 100644 index 00000000000..7d479e6a4f0 --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorSectionsItemDecoration.java @@ -0,0 +1,58 @@ +/* + * Copyright 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 io.material.catalog.color; + +import io.material.catalog.R; + +import android.content.Context; +import android.graphics.Rect; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.ItemDecoration; +import androidx.recyclerview.widget.RecyclerView.State; +import android.view.View; +import androidx.annotation.NonNull; + +/** + * Allows the application to add a special drawing and layout offset to specific item views from the + * adapter's data set. + */ +public class ColorSectionsItemDecoration extends ItemDecoration { + + private final int space; + private final ColorsAdapter adapter; + + public ColorSectionsItemDecoration(@NonNull Context context, @NonNull ColorsAdapter adapter) { + this.space = context.getResources().getDimensionPixelSize(R.dimen.cat_colors_header_space); + this.adapter = adapter; + } + + @NonNull + @Override + public void getItemOffsets( + @NonNull Rect rect, + @NonNull View view, + @NonNull RecyclerView recyclerView, + @NonNull State state) { + super.getItemOffsets(rect, view, recyclerView, state); + + // Add space above each header except the first. + int position = recyclerView.getChildAdapterPosition(view); + if (position != 0 && adapter.getItemViewType(position) == ColorsAdapter.VIEW_TYPE_HEADER) { + rect.set(0, space, 0, 0); + } + } +} diff --git a/catalog/java/io/material/catalog/color/ColorsAdapter.java b/catalog/java/io/material/catalog/color/ColorsAdapter.java new file mode 100644 index 00000000000..dc44dcaaeed --- /dev/null +++ b/catalog/java/io/material/catalog/color/ColorsAdapter.java @@ -0,0 +1,110 @@ +/* + * Copyright 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 io.material.catalog.color; + +import android.content.Context; +import android.content.res.TypedArray; +import androidx.recyclerview.widget.RecyclerView.Adapter; +import androidx.recyclerview.widget.RecyclerView.ViewHolder; +import android.view.ViewGroup; +import androidx.annotation.ArrayRes; +import androidx.annotation.NonNull; +import io.material.catalog.color.ColorPaletteDemoFragment.ColorHeaderViewHolder; +import io.material.catalog.color.ColorPaletteDemoFragment.ColorViewHolder; +import java.util.ArrayList; +import java.util.List; + +/** Adapter class for the colors palette. */ +public class ColorsAdapter extends Adapter { + + // The header indicator of a color. + public static final int VIEW_TYPE_HEADER = 0; + + private static final int VIEW_TYPE_COLOR = 1; + private final List items = new ArrayList<>(); + private final Context context; + + public ColorsAdapter(@NonNull Context context, @NonNull @ArrayRes int colorItems) { + this.context = context; + TypedArray colorsArray = context.getResources().obtainTypedArray(colorItems); + + for (int i = 0; i < colorsArray.length(); i++) { + List colors = getColorsFromArrayResource(colorsArray.getResourceId(i, 0)); + items.add(new ColorHeaderItem(context, colors)); + items.addAll(colors); + } + + colorsArray.recycle(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_HEADER: + return new ColorHeaderViewHolder(parent); + case VIEW_TYPE_COLOR: + return new ColorViewHolder(parent); + default: + // The default case should never be reached. + return null; + } + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) { + switch (getItemViewType(position)) { + case VIEW_TYPE_HEADER: + ColorHeaderItem header = (ColorHeaderItem) items.get(position); + ((ColorHeaderViewHolder) viewHolder).bind(header); + break; + case VIEW_TYPE_COLOR: + ColorItem item = (ColorItem) items.get(position); + ((ColorViewHolder) viewHolder).bind(item); + break; + default: // fall out + } + } + + @Override + public int getItemViewType(int position) { + return (items.get(position) instanceof ColorHeaderItem) ? VIEW_TYPE_HEADER : VIEW_TYPE_COLOR; + } + + @Override + public int getItemCount() { + return items.size(); + } + + /** Returns the list of {@link ColorAdapterItem}s in the adapter. */ + @NonNull + public List getItems() { + return items; + } + + private List getColorsFromArrayResource(@ArrayRes int arrayRes) { + List colors = new ArrayList<>(); + TypedArray colorsArray = context.getResources().obtainTypedArray(arrayRes); + + for (int i = 0; i < colorsArray.length(); i++) { + int color = colorsArray.getResourceId(i, 0); + colors.add(new ColorItem(context, color)); + } + colorsArray.recycle(); + return colors; + } +} diff --git a/catalog/java/io/material/catalog/color/ColorsFragment.java b/catalog/java/io/material/catalog/color/ColorsFragment.java index 094a2603414..f2f7a3b8c89 100644 --- a/catalog/java/io/material/catalog/color/ColorsFragment.java +++ b/catalog/java/io/material/catalog/color/ColorsFragment.java @@ -20,6 +20,7 @@ import androidx.fragment.app.Fragment; import androidx.annotation.NonNull; +import com.google.android.material.color.DynamicColors; import dagger.Provides; import dagger.android.ContributesAndroidInjector; import dagger.multibindings.IntoSet; @@ -28,6 +29,8 @@ import io.material.catalog.feature.Demo; import io.material.catalog.feature.DemoLandingFragment; import io.material.catalog.feature.FeatureDemo; +import java.util.ArrayList; +import java.util.List; /** A landing fragment that links to color demos for the Catalog app. */ public class ColorsFragment extends DemoLandingFragment { @@ -48,11 +51,34 @@ public Demo getMainDemo() { return new Demo() { @Override public Fragment createFragment() { - return new ColorHarmonizationDemoFragment(); + return new ColorMainDemoFragment(); } }; } + @NonNull + @Override + public List getAdditionalDemos() { + List additionalDemos = new ArrayList<>(); + if (DynamicColors.isDynamicColorAvailable()) { + additionalDemos.add( + new Demo(R.string.cat_color_dynamic_palette) { + @Override + public Fragment createFragment() { + return new ColorDynamicDemoFragment(); + } + }); + } + additionalDemos.add( + new Demo(R.string.cat_color_harmonization) { + @Override + public Fragment createFragment() { + return new ColorHarmonizationDemoFragment(); + } + }); + return additionalDemos; + } + /** The Dagger module for {@link ColorsFragment} dependencies. */ @dagger.Module public abstract static class Module { diff --git a/catalog/java/io/material/catalog/color/MaterialColorSpec.java b/catalog/java/io/material/catalog/color/MaterialColorSpec.java new file mode 100644 index 00000000000..055e8933cc1 --- /dev/null +++ b/catalog/java/io/material/catalog/color/MaterialColorSpec.java @@ -0,0 +1,83 @@ +/* + * Copyright 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 io.material.catalog.color; + +import android.content.Context; +import androidx.annotation.ColorRes; +import java.util.Arrays; +import java.util.List; + +/** + * Represents a color value as defined in the Material Spec. These are all defined by color name + + * color value. ie. blue500. + */ +public final class MaterialColorSpec { + public static final String SYSTEM_PREFIX = "system_"; + static final int TEXT_COLOR_SWITCH_VALUE = 400; + + @ColorRes private final int resourceId; + private final String resourceName; + private final String name; + private final int value; + + MaterialColorSpec(int resourceId, String resourceName, String name, int value) { + this.resourceId = resourceId; + this.resourceName = resourceName; + this.name = name; + this.value = value; + } + + @ColorRes + int getResourceId() { + return resourceId; + } + + String getResourceName() { + return resourceName; + } + + String getName() { + return name; + } + + int getValue() { + return value; + } + + static MaterialColorSpec create(Context context, @ColorRes int colorRes) { + String resName = context.getResources().getResourceEntryName(colorRes); + String name; + String value; + if (resName.startsWith(SYSTEM_PREFIX)) { + // Split the resource name into the color name and value, ie. system_accent1_500 to + // system_accent1 and 500. + int splitIndex = resName.lastIndexOf("_"); + name = resName.substring(0, splitIndex); + value = resName.substring(splitIndex + 1); + } else { + // Get the name of the color an value without prefixes + // String trimmedResName = resName; + int splitIndex = resName.lastIndexOf("_"); + String trimmedResName = resName.substring(splitIndex + 1); + // Split the resource name into the color name and value, ie. blue500 to blue and 500. + List parts = Arrays.asList(trimmedResName.split("(?<=\\D)(?=\\d)", -1)); + name = parts.get(0); + value = parts.get(1); + } + return new MaterialColorSpec(colorRes, resName, name, Integer.parseInt(value)); + } +} diff --git a/catalog/java/io/material/catalog/color/res/layout/cat_colors_fragment.xml b/catalog/java/io/material/catalog/color/res/layout/cat_colors_fragment.xml new file mode 100644 index 00000000000..2de79543291 --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/layout/cat_colors_fragment.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_fragment.xml b/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_fragment.xml new file mode 100644 index 00000000000..f622e682328 --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_fragment.xml @@ -0,0 +1,25 @@ + + + + diff --git a/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_header.xml b/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_header.xml new file mode 100644 index 00000000000..9f650906e82 --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_header.xml @@ -0,0 +1,27 @@ + + + + diff --git a/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_item.xml b/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_item.xml new file mode 100644 index 00000000000..225c5fad77e --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/layout/cat_colors_palette_item.xml @@ -0,0 +1,34 @@ + + + + + + + diff --git a/catalog/java/io/material/catalog/color/res/menu/cat_colors_menu.xml b/catalog/java/io/material/catalog/color/res/menu/cat_colors_menu.xml new file mode 100644 index 00000000000..9f2b6248597 --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/menu/cat_colors_menu.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/catalog/java/io/material/catalog/color/res/values-v31/arrays.xml b/catalog/java/io/material/catalog/color/res/values-v31/arrays.xml new file mode 100644 index 00000000000..424692fc7b6 --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/values-v31/arrays.xml @@ -0,0 +1,107 @@ + + + + + + + @array/m3_colors_accent1_array + @array/m3_colors_accent2_array + @array/m3_colors_accent3_array + @array/m3_colors_neutral1_array + @array/m3_colors_neutral2_array + + + + @android:color/system_accent1_1000 + @android:color/system_accent1_900 + @android:color/system_accent1_800 + @android:color/system_accent1_700 + @android:color/system_accent1_600 + @android:color/system_accent1_500 + @android:color/system_accent1_400 + @android:color/system_accent1_300 + @android:color/system_accent1_200 + @android:color/system_accent1_100 + @android:color/system_accent1_50 + @android:color/system_accent1_10 + @android:color/system_accent1_0 + + + + @android:color/system_accent2_1000 + @android:color/system_accent2_900 + @android:color/system_accent2_800 + @android:color/system_accent2_700 + @android:color/system_accent2_600 + @android:color/system_accent2_500 + @android:color/system_accent2_400 + @android:color/system_accent2_300 + @android:color/system_accent2_200 + @android:color/system_accent2_100 + @android:color/system_accent2_50 + @android:color/system_accent2_10 + @android:color/system_accent2_0 + + + + @android:color/system_accent3_1000 + @android:color/system_accent3_900 + @android:color/system_accent3_800 + @android:color/system_accent3_700 + @android:color/system_accent3_600 + @android:color/system_accent3_500 + @android:color/system_accent3_400 + @android:color/system_accent3_300 + @android:color/system_accent3_200 + @android:color/system_accent3_100 + @android:color/system_accent3_50 + @android:color/system_accent3_10 + @android:color/system_accent3_0 + + + + @android:color/system_neutral1_1000 + @android:color/system_neutral1_900 + @android:color/system_neutral1_800 + @android:color/system_neutral1_700 + @android:color/system_neutral1_600 + @android:color/system_neutral1_500 + @android:color/system_neutral1_400 + @android:color/system_neutral1_300 + @android:color/system_neutral1_200 + @android:color/system_neutral1_100 + @android:color/system_neutral1_50 + @android:color/system_neutral1_10 + @android:color/system_neutral1_0 + + + + @android:color/system_neutral2_1000 + @android:color/system_neutral2_900 + @android:color/system_neutral2_800 + @android:color/system_neutral2_700 + @android:color/system_neutral2_600 + @android:color/system_neutral2_500 + @android:color/system_neutral2_400 + @android:color/system_neutral2_300 + @android:color/system_neutral2_200 + @android:color/system_neutral2_100 + @android:color/system_neutral2_50 + @android:color/system_neutral2_10 + @android:color/system_neutral2_0 + + diff --git a/catalog/java/io/material/catalog/color/res/values/colors.xml b/catalog/java/io/material/catalog/color/res/values/colors.xml index 373f082b70d..5e6cd3284b8 100644 --- a/catalog/java/io/material/catalog/color/res/values/colors.xml +++ b/catalog/java/io/material/catalog/color/res/values/colors.xml @@ -19,5 +19,7 @@ #ffd93025 #ff1e8e3e #ffd9e6f9 + #ff202124 + diff --git a/catalog/java/io/material/catalog/color/res/values/dimens.xml b/catalog/java/io/material/catalog/color/res/values/dimens.xml new file mode 100644 index 00000000000..1351a61eb0b --- /dev/null +++ b/catalog/java/io/material/catalog/color/res/values/dimens.xml @@ -0,0 +1,20 @@ + + + + + 32dp + diff --git a/catalog/java/io/material/catalog/color/res/values/strings.xml b/catalog/java/io/material/catalog/color/res/values/strings.xml index 8e71bec494e..ad2b3e0f5ba 100644 --- a/catalog/java/io/material/catalog/color/res/values/strings.xml +++ b/catalog/java/io/material/catalog/color/res/values/strings.xml @@ -28,4 +28,11 @@ Unelevated button Color hex value: %1$s + Color Harmonization Demo + Dynamic Palette Demo + + Copy colors + + %1$s%2$s +