diff --git a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/ColorView.java b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/ColorView.java index f983b22..0eca373 100644 --- a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/ColorView.java +++ b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/ColorView.java @@ -46,6 +46,8 @@ import android.widget.FrameLayout; import android.widget.ImageView; +import java.util.Locale; + import eltos.simpledialogfragment.R; @@ -108,12 +110,17 @@ public void setStyle(Style style){ return mColor; } + /** + * Will implicitly set content description. Thus custom content description must be set after this + * method is called + */ public void setColor(@ColorInt int color) { if ((color & 0xFF000000) == 0 && color != 0){ // if alpha value omitted, set now color = color | 0xFF000000; } if (mColor != color) { mColor = color; + setContentDescription(colorToRGBString(mColor)); update(); } } @@ -289,6 +296,12 @@ public static boolean isColorDark(@ColorInt int color) { return Color.HSVToColor(hsv); } + public static String colorToRGBString(int color) { + int red = Color.red(color); + int green = Color.green(color); + int blue = Color.blue(color); + return String.format(Locale.ROOT, "RGB(%d, %d, %d)", red, green, blue); + } } diff --git a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/SimpleColorDialog.java b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/SimpleColorDialog.java index 6b19734..0b0bc89 100644 --- a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/SimpleColorDialog.java +++ b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/color/SimpleColorDialog.java @@ -23,6 +23,7 @@ import androidx.annotation.ArrayRes; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.core.util.Pair; import android.util.TypedValue; import android.view.View; @@ -95,6 +96,28 @@ public SimpleColorDialog colors(Context context, @ArrayRes int colorArrayRes){ return colors(context.getResources().getIntArray(colorArrayRes)); } + /** + * Sets the color names for accessibility purpose + * + * @param colorNames array of names that match the colors defined via {@link #colors(int[])} + * @return this instance + */ + public SimpleColorDialog colorNames(String[] colorNames){ + getArgs().putStringArray(COLOR_NAMES, colorNames); + return this; + } + + /** + * Sets the color names for accessibility purpose + * + * @param context a context to resolve the resource + * @param colorNameArrayRes String array resource id + * @return this instance + */ + public SimpleColorDialog colorNames(Context context, @ArrayRes int colorNameArrayRes){ + return colorNames(context.getResources().getStringArray(colorNameArrayRes)); + } + /** * Sets the initially selected color * @@ -183,9 +206,6 @@ public SimpleColorDialog showOutline(@ColorInt int color){ return setArg(OUTLINE, color); } - - - public static final @ColorInt int[] DEFAULT_COLORS = new int[]{ 0xfff44336, 0xffe91e63, 0xff9c27b0, 0xff673ab7, 0xff3f51b5, 0xff2196f3, 0xff03a9f4, 0xff00bcd4, @@ -206,6 +226,8 @@ public SimpleColorDialog showOutline(@ColorInt int color){ private static final String SELECTED = TAG + "selected"; private static final String OUTLINE = TAG + "outline"; + private static final String COLOR_NAMES = TAG + "color_names"; + private @ColorInt int mCustomColor = NONE; private @ColorInt int mSelectedColor = NONE; @@ -256,7 +278,7 @@ protected AdvancedAdapter onCreateAdapter() { // Selector provided by ColorView getListView().setSelector(new ColorDrawable(Color.TRANSPARENT)); - return new ColorAdapter(colors, custom); + return new ColorAdapter(colors, getArgs().getStringArray(COLOR_NAMES), custom); } private int indexOf(int[] array, int item){ @@ -349,19 +371,19 @@ protected Bundle onResult(int which) { } - protected class ColorAdapter extends AdvancedAdapter{ + protected class ColorAdapter extends AdvancedAdapter>{ - public ColorAdapter(int[] colors, boolean addCustomField){ + public ColorAdapter(int[] colors, String[] contentDescriptions, boolean addCustomField){ if (colors == null) colors = new int[0]; - Integer[] cs = new Integer[colors.length + (addCustomField ? 1 : 0)]; + Pair[] cs = new Pair[colors.length + (addCustomField ? 1 : 0)]; for (int i = 0; i < colors.length; i++) { - cs[i] = colors[i]; + cs[i] = Pair.create(colors[i], contentDescriptions != null && contentDescriptions.length > i ? contentDescriptions[i] : null); } if (addCustomField){ - cs[cs.length-1] = PICKER; + cs[cs.length-1] = Pair.create(PICKER, getString(R.string.color_picker)); } - setData(cs, Long::valueOf); + setData(cs, pair -> pair.first.longValue()); } @Override @@ -374,14 +396,18 @@ public View getView(int position, View convertView, ViewGroup parent) { item = new ColorView(getContext()); } - int color = getItem(position); + Pair pair = getItem(position); - if ( color == PICKER){ + if (pair.first == PICKER){ item.setColor(mCustomColor); item.setStyle(ColorView.Style.PALETTE); + item.setContentDescription(getString(R.string.color_picker) + (mCustomColor == NONE ? "" : ": " + ColorView.colorToRGBString(mCustomColor))); } else { - item.setColor(getItem(position)); + item.setColor(pair.first); item.setStyle(ColorView.Style.CHECK); + if (pair.second != null) { + item.setContentDescription(pair.second); + } } @ColorInt int outline = getArgs().getInt(OUTLINE, ColorView.NONE); diff --git a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorField.java b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorField.java index 94bd858..525eb49 100644 --- a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorField.java +++ b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorField.java @@ -44,6 +44,7 @@ public class ColorField extends FormElement { private @ColorInt int preset = NONE; private int presetId = NO_ID; protected int[] colors = SimpleColorDialog.DEFAULT_COLORS; + protected String[] colorNames = null; protected boolean allowCustom = true; protected int outline = NONE; @@ -100,6 +101,28 @@ public ColorField colors(@ColorInt int[] colors){ return this; } + /** + * Sets the color names for accessibility purpose + * + * @param colorNames array of names that match the colors defined via {@link #colors(int[])} + * @return this instance + */ + public ColorField colorNames(String[] colorNames) { + this.colorNames = colorNames; + return this; + } + + /** + * Sets the color names for accessibility purpose + * + * @param context a context to resolve the resource + * @param colorNameArrayRes String array resource id + * @return this instance + */ + public ColorField colorNames(Context context, @ArrayRes int colorNameArrayRes){ + return colorNames(context.getResources().getStringArray(colorNameArrayRes)); + } + /** * Sets the color pallet to choose from * May be one of {@link SimpleColorDialog#MATERIAL_COLOR_PALLET}, diff --git a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorViewHolder.java b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorViewHolder.java index 516d3e1..4939219 100644 --- a/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorViewHolder.java +++ b/simpledialogfragments/src/main/java/eltos/simpledialogfragment/form/ColorViewHolder.java @@ -88,6 +88,7 @@ protected void setUpView(View view, final Context context, Bundle savedInstanceS colorView.setOnClickListener(v -> actions.showDialog(SimpleColorDialog.build() .title(field.getText(context)) .colors(field.colors) + .colorNames(field.colorNames) .allowCustom(field.allowCustom) .colorPreset(colorView.getColor()) .neut(), @@ -99,6 +100,14 @@ protected void setUpView(View view, final Context context, Bundle savedInstanceS private void setColor(@ColorInt int color){ colorView.setColor(color); + if (field.colorNames != null && field.colorNames.length >= field.colors.length) { + for (int i = 0; i < field.colors.length; i++) { + if (field.colors[i] == color) { + colorView.setContentDescription(field.colorNames[i]); + break; + } + } + } clearButton.setVisibility(field.required || colorView.getColor() == ColorView.NONE ? View.GONE : View.VISIBLE); } diff --git a/simpledialogfragments/src/main/res/layout/simpledialogfragment_form_item_color.xml b/simpledialogfragments/src/main/res/layout/simpledialogfragment_form_item_color.xml index 3d6ff27..c9a32a0 100644 --- a/simpledialogfragments/src/main/res/layout/simpledialogfragment_form_item_color.xml +++ b/simpledialogfragments/src/main/res/layout/simpledialogfragment_form_item_color.xml @@ -35,6 +35,7 @@ android:layout_gravity="center" android:scaleType="fitCenter" android:visibility="gone" + android:contentDescription="@string/clear_color" android:src="@drawable/ic_clear_search" /> diff --git a/simpledialogfragments/src/main/res/values/strings.xml b/simpledialogfragments/src/main/res/values/strings.xml index 754bbb0..2f933cd 100644 --- a/simpledialogfragments/src/main/res/values/strings.xml +++ b/simpledialogfragments/src/main/res/values/strings.xml @@ -20,4 +20,6 @@ Date Time Clear + Color picker + Clear color \ No newline at end of file diff --git a/testApp/src/main/java/eltos/simpledialogfragments/MainActivity.java b/testApp/src/main/java/eltos/simpledialogfragments/MainActivity.java index 3d0f50b..d46dd79 100644 --- a/testApp/src/main/java/eltos/simpledialogfragments/MainActivity.java +++ b/testApp/src/main/java/eltos/simpledialogfragments/MainActivity.java @@ -393,13 +393,16 @@ public void showColorPicker(View view){ pallet == SimpleColorDialog.BEIGE_COLOR_PALLET ? SimpleColorDialog.AUTO : SimpleColorDialog.NONE; - SimpleColorDialog.build() + SimpleColorDialog dialog = SimpleColorDialog.build() .title(R.string.pick_a_color) .colors(this, pallet) .colorPreset(color) .allowCustom(true) - .showOutline(outline) - .show(this, COLOR_DIALOG); + .showOutline(outline); + if (pallet == SimpleColorDialog.MATERIAL_COLOR_PALLET) { + dialog.colorNames(this, R.array.material_color_names); + } + dialog.show(this, COLOR_DIALOG); /** Results: {@link MainActivity#onResult} **/ @@ -551,7 +554,9 @@ public void showForm(View view){ Input.plain(COUNTRY).hint(R.string.country) .inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) .suggest(R.array.countries_locale).forceSuggestion(), - ColorField.picker(COLOR).label(R.string.favourite_color), + ColorField.picker(COLOR).colors(SimpleColorDialog.DEFAULT_COLORS) + .colorNames(this,R.array.material_color_names) + .label(R.string.favourite_color), Input.email(EMAIL).required(), Check.box(NEWSLETTER).label(R.string.receive_newsletter).check(true), Input.password(PASSWORD).max(20).required().validatePatternStrongPassword(), diff --git a/testApp/src/main/res/values/arrays.xml b/testApp/src/main/res/values/arrays.xml index e8764ac..e68294e 100644 --- a/testApp/src/main/res/values/arrays.xml +++ b/testApp/src/main/res/values/arrays.xml @@ -73,5 +73,25 @@ Intersex Dyadic - + + red + magenta + purple + deep purple + indigo + blue + light blue + cyan + teal + green + light green + lime + yellow + amber + orange + deep orange + brown + gray + blue gray + \ No newline at end of file