Java tutorial
/* * ================================================================================================= * Copyright (C) 2017 Universum Studios * ================================================================================================= * Licensed under the Apache License, Version 2.0 or later (further "License" only). * ------------------------------------------------------------------------------------------------- * You may use this file only in compliance with the License. More details and copy of this License * you may obtain at * * http://www.apache.org/licenses/LICENSE-2.0 * * You can redistribute, modify or publish any part of the code written within this file but as it * is described in the License, the software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF ANY KIND. * * See the License for the specific language governing permissions and limitations under the License. * ================================================================================================= */ package universum.studios.android.dialog; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Color; import android.os.Bundle; import android.os.Parcel; import android.support.annotation.AttrRes; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StyleRes; import android.support.v4.widget.Space; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import universum.studios.android.dialog.view.ColorPickerDialogView; /** * A {@link SimpleDialog} implementation that can be used to allow to a user to pick its desired color * via specifying values for <b>RGBA</b> color components using slider or text field. This dialog uses * default {@link ColorPickerDialogView} implementation as its content view which consists of * {@link universum.studios.android.dialog.widget.DialogColorView DialogColorView} used to present * picked color and 4 sliders with text input fields that can be used to input the desired value for * the mentioned color components. * <p> * The picked color may be obtained via {@link #getColor()}. * <p> * See {@link ColorOptions} for options that can be supplied to the ColorPickerDialog from the desired * context via {@link #newInstance(ColorOptions)} or via {@link #setOptions(DialogOptions)}. * <p> * <b>Note</b>, that current state of this dialog will be always preserved after orientation change, * as all dialog views from this library save theirs current state for that matter. * * <h3>Xml options</h3> * This dialog parses its global options from the current dialog theme referenced via * {@link R.attr#dialogColorOptions dialogColorOptions} attribute. * * @author Martin Albedinsky */ public class ColorPickerDialog extends SimpleDialog { /** * Constants =================================================================================== */ /** * Log TAG. */ // private static final String TAG = "ColorPickerDialog"; /* * Interface =================================================================================== */ /** * Static members ============================================================================== */ /** * Members ===================================================================================== */ /** * ColorPicker dialog view implementation. */ private ColorPickerDialogView mColorView; /** * Constructors ================================================================================ */ /** * Creates a new instance of ColorPickerDialog with a {@link universum.studios.android.dialog.widget.DialogColorView DialogColorView} * and 4 layouts with sliders and text fields allowing to pick a value of each of the color components * (RGBA) respectively. */ public ColorPickerDialog() { super(R.attr.dialogColorOptions); } /** * Methods ===================================================================================== */ /** * Creates a new instance of ColorPickerDialog with the specified options. * * @param options Specific options for this type of dialog. * @return New ColorPickerDialog instance. */ @NonNull public static ColorPickerDialog newInstance(@NonNull ColorOptions options) { final ColorPickerDialog dialog = new ColorPickerDialog(); dialog.setOptions(options); return dialog; } /** */ @NonNull @Override protected DialogOptions onCreateDefaultOptions(@NonNull Resources resources) { return new ColorOptions(resources); } /** */ @Override protected void onProcessOptionsStyle(@NonNull Context context, @StyleRes int optionsStyle) { super.onProcessOptionsStyle(context, optionsStyle); if (mOptions instanceof ColorOptions) { final TypedArray attributes = context.obtainStyledAttributes(optionsStyle, R.styleable.Dialog_Options_Color); final ColorOptions options = (ColorOptions) mOptions; for (int i = 0; i < attributes.getIndexCount(); i++) { int index = attributes.getIndex(i); if (index == R.styleable.Dialog_Options_Color_dialogColor) { if (!options.isSet(ColorOptions.COLOR)) { options.color(attributes.getColor(index, options.color)); } } else if (index == R.styleable.Dialog_Options_Color_dialogColorCanvas) { if (!options.isSet(ColorOptions.CANVAS_COLOR)) { options.canvasColor(attributes.getColor(index, options.canvasColor)); } } } attributes.recycle(); } } /** */ @NonNull @Override protected View onCreateContentView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.dialog_content_color, container, false); } /** */ @NonNull @Override protected View onCreateButtonsView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { // Content view already contains buttons view. final View view = new Space(mContext); view.setVisibility(View.GONE); return view; } /** */ @Override void onBindContentView(View contentView, DialogOptions options) { if (contentView instanceof ColorPickerDialogView && options instanceof ColorOptions) { final ColorOptions colorOptions = (ColorOptions) options; final ColorPickerDialogView colorView = (ColorPickerDialogView) contentView; if (colorOptions.color != 0) { colorView.setColor(colorOptions.color); } colorView.setCanvasColor(colorOptions.canvasColor); } } /** */ @Override protected void onUpdateContentViewPadding() { // Do not update content view padding. } /** */ @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); final View contentView = getContentView(); if (contentView instanceof ColorPickerDialogView) { this.mColorView = (ColorPickerDialogView) contentView; } } /** * Returns the current value of <b>color</b> picked within this picker dialog. * * @return Picked color either by user or initially specified via options. */ @ColorInt public int getColor() { return mColorView != null ? mColorView.getColor() : Color.TRANSPARENT; } /** * Inner classes =============================================================================== */ /** * A {@link DialogOptions} implementation specific for the {@link ColorPickerDialog}. * <p> * Below are listed setters which may be used to supply desired data to {@link ColorPickerDialog} * through these options: * <ul> * <li>{@link #color(int)}</li> * <li>{@link #canvasColor(int)}</li> * </ul> * * <h3>Xml attributes</h3> * See {@link R.styleable#Dialog_Options_Color ColorOptions Attributes}, * {@link R.styleable#Dialog_Options DialogOptions Attributes} * * @author Martin Albedinsky */ public static class ColorOptions extends DialogOptions<ColorOptions> { /** * Creator used to create an instance or array of instances of ColorOptions from {@link Parcel}. */ public static final Creator<ColorOptions> CREATOR = new Creator<ColorOptions>() { /** */ @Override public ColorOptions createFromParcel(@NonNull Parcel source) { return new ColorOptions(source); } /** */ @Override public ColorOptions[] newArray(int size) { return new ColorOptions[size]; } }; /** * Flag for <b>color</b> parameter. */ static final int COLOR = 0x00000001; /** * Flag for <b>canvas color</b> parameter. */ static final int CANVAS_COLOR = 0x00000001 << 1; /** * Initial color for ColorView. */ int color; /** * Background color for ColorView. */ int canvasColor = Color.WHITE; /** * Creates a new instance of ColorOptions. */ public ColorOptions() { super(); } /** * Creates a new instance of ColorOptions. * * @param resources Application resources used to obtain values for these options when they * are requested by theirs resource ids. */ public ColorOptions(@NonNull Resources resources) { super(resources); } /** * Called form {@link #CREATOR} to create an instance of ColorOptions form the given parcel * <var>source</var>. * * @param source Parcel with data for the new instance. */ protected ColorOptions(@NonNull Parcel source) { super(source); this.color = source.readInt(); this.canvasColor = source.readInt(); } /** */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(color); dest.writeInt(canvasColor); } /** */ @Override public ColorOptions merge(@NonNull DialogOptions options) { if (!(options instanceof ColorOptions)) { return super.merge(options); } final ColorOptions colorOptions = (ColorOptions) options; if (colorOptions.isSet(COLOR)) { this.color = colorOptions.color; updateIsSet(COLOR); } if (colorOptions.isSet(CANVAS_COLOR)) { this.canvasColor = colorOptions.canvasColor; updateIsSet(CANVAS_COLOR); } return super.merge(options); } /** * Sets the initial color for ColorView of a dialog associated with these options. * <p> * Default color: <b>{@link Color#TRANSPARENT}</b> * * @param color The desired initial color. * @return These options to allow methods chaining. * @see R.attr#dialogColor dialog:dialogColor * @see #color() */ public ColorOptions color(@ColorInt int color) { updateIsSet(COLOR); if (this.color != color) { this.color = color; notifyChanged(); } return this; } /** * Returns the initial color for ColorView, set to these options. * * @return The initial color specified via {@link #color(int)} or {@link Color#TRANSPARENT} * by default. * @see #color(int) */ @ColorInt public int color() { return color; } /** * Sets the color for canvas (background) of ColorView of a dialog associated with these * options. * <p> * Default color: <b>{@link Color#WHITE}</b> * * @param color The desired canvas (background) color. * @return These options to allow methods chaining. * @see R.attr#dialogColorCanvas dialog:dialogColorCanvas * @see #canvasColor() */ public ColorOptions canvasColor(@ColorInt int color) { updateIsSet(CANVAS_COLOR); if (this.canvasColor != color) { this.canvasColor = color; notifyChanged(); } return this; } /** * Returns the canvas color of ColorView, set to these options. * * @return The canvas (background) color specified via {@link #canvasColor(int)} or * {@link Color#WHITE} by default. * @see #canvasColor(int) */ @ColorInt public int canvasColor() { return canvasColor; } /** */ @Override protected void onParseXmlAttribute(@NonNull XmlResourceParser xmlParser, int index, @AttrRes int attr, @NonNull Resources resources, @Nullable Resources.Theme theme) { if (attr == R.attr.dialogColor) { color(xmlParser.getAttributeIntValue(index, color)); } else if (attr == R.attr.dialogColorCanvas) { canvasColor(xmlParser.getAttributeIntValue(index, canvasColor)); } else { super.onParseXmlAttribute(xmlParser, index, attr, resources, theme); } } } }