de.mrapp.android.dialog.builder.AbstractMaterialDialogBuilder.java Source code

Java tutorial

Introduction

Here is the source code for de.mrapp.android.dialog.builder.AbstractMaterialDialogBuilder.java

Source

/*
 * Copyright 2014 - 2016 Michael Rapp
 *
 * 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 de.mrapp.android.dialog.builder;

import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.support.annotation.AttrRes;
import android.support.annotation.CallSuper;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.annotation.StyleRes;
import android.support.v4.content.ContextCompat;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.View;

import de.mrapp.android.dialog.R;
import de.mrapp.android.dialog.model.Dialog;
import de.mrapp.android.dialog.model.MaterialDialog;
import de.mrapp.android.util.ThemeUtil;

/**
 * An abstract base class for all builders, which allow to create and show dialogs, which are
 * designed according to Android 5's Material Design guidelines even on pre-Lollipop devices.
 *
 * @param <DialogType>
 *         The type of the dialog, which is created by the builder
 * @param <BuilderType>
 *         The type of the builder
 * @author Michael Rapp
 * @since 3.3.0
 */
public abstract class AbstractMaterialDialogBuilder<DialogType extends MaterialDialog, BuilderType extends AbstractMaterialDialogBuilder<DialogType, ?>>
        extends AbstractBuilder<DialogType, BuilderType> {

    /**
     * The resource if of the theme, which is used by the dialog.
     */
    private int themeResourceId;

    /**
     * Initializes the builder.
     *
     * @param themeResourceId
     *         The resource id of the theme, which should be used by the dialog, as an {@link
     *         Integer} value or 0, if the default theme should be used
     */
    private void initialize(@StyleRes final int themeResourceId) {
        int themeId = themeResourceId;

        if (themeId == 0) {
            TypedValue typedValue = new TypedValue();
            getContext().getTheme().resolveAttribute(R.attr.materialDialogTheme, typedValue, true);
            themeId = typedValue.resourceId;
            themeId = themeId != 0 ? themeId : R.style.MaterialDialog_Light;
        }

        setContext(new ContextThemeWrapper(getContext(), themeId));
        this.themeResourceId = themeId;
        obtainStyledAttributes(themeId);
    }

    /**
     * Obtains the boolean value, which specified whether the dialog should be shown fullscreen, or
     * not, from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the boolean value should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainFullscreen(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogFullscreen });
        setFullscreen(typedArray.getBoolean(0, false));
    }

    /**
     * Obtains the gravity from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the gravity should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainGravity(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogGravity });
        setGravity(typedArray.getInteger(0, Dialog.Gravity.CENTER));
    }

    /**
     * Obtains the width from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the width should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainWidth(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogWidth });
        int defaultValue = getContext().getResources().getDimensionPixelSize(R.dimen.dialog_width);

        try {
            setWidth(typedArray.getDimensionPixelSize(0, defaultValue));
        } catch (Resources.NotFoundException | UnsupportedOperationException e) {
            setWidth(typedArray.getInteger(0, defaultValue));
        }
    }

    /**
     * Obtains the height from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the height should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainHeight(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogHeight });
        int defaultValue = Dialog.WRAP_CONTENT;

        try {
            setHeight(typedArray.getDimensionPixelSize(0, defaultValue));
        } catch (Resources.NotFoundException | UnsupportedOperationException e) {
            setHeight(typedArray.getInteger(0, defaultValue));
        }
    }

    /**
     * Obtains the maximum width from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the maximum width should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainMaxWidth(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogMaxWidth });
        int defaultValue;

        try {
            defaultValue = getContext().getResources().getDimensionPixelSize(R.dimen.dialog_max_width);
        } catch (Resources.NotFoundException | UnsupportedOperationException e) {
            defaultValue = -1;
        }

        try {
            setMaxWidth(typedArray.getDimensionPixelSize(0, defaultValue));
        } catch (Resources.NotFoundException | UnsupportedOperationException e) {
            setMaxWidth(-1);
        }
    }

    /**
     * Obtains the maximum height from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the maximum height should be obtained from, as an
     *         {@link Integer} value
     */
    private void obtainMaxHeight(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogMaxHeight });
        int defaultValue;

        try {
            defaultValue = getContext().getResources().getDimensionPixelSize(R.dimen.dialog_max_height);
        } catch (Resources.NotFoundException | UnsupportedOperationException e) {
            defaultValue = -1;
        }

        try {
            setMaxHeight(typedArray.getDimensionPixelSize(0, defaultValue));
        } catch (Resources.NotFoundException | UnsupportedOperationException e) {
            setMaxHeight(-1);
        }
    }

    /**
     * Obtains the margin from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the margin should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainMargin(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogMarginLeft, R.attr.materialDialogMarginTop,
                        R.attr.materialDialogMarginRight, R.attr.materialDialogMarginBottom });
        int defaultHorizontalMargin = getContext().getResources()
                .getDimensionPixelSize(R.dimen.dialog_horizontal_margin);
        int defaultVerticalMargin = getContext().getResources()
                .getDimensionPixelSize(R.dimen.dialog_vertical_margin);
        int left = typedArray.getDimensionPixelSize(0, defaultHorizontalMargin);
        int top = typedArray.getDimensionPixelSize(1, defaultVerticalMargin);
        int right = typedArray.getDimensionPixelSize(2, defaultHorizontalMargin);
        int bottom = typedArray.getDimensionPixelSize(3, defaultVerticalMargin);
        setMargin(left, top, right, bottom);
    }

    /**
     * Obtains, whether the dialog's content should be inset, from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the boolean value, which specifies whether the dialog's
     *         content should be inset, should be obtained from, as a {@link Integer} value
     */
    private void obtainFitsSystemWindows(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogFitsSystemWindowsLeft, R.attr.materialDialogFitsSystemWindowsTop,
                        R.attr.materialDialogFitsSystemWindowsRight,
                        R.attr.materialDialogFitsSystemWindowsBottom });
        boolean left = typedArray.getBoolean(0, true);
        boolean top = typedArray.getBoolean(1, true);
        boolean right = typedArray.getBoolean(2, true);
        boolean bottom = typedArray.getBoolean(3, true);
        setFitsSystemWindows(left, top, right, bottom);
    }

    /**
     * Obtains the background from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the background should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainBackground(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogBackground });
        int resourceId = typedArray.getResourceId(0, 0);

        if (resourceId != 0) {
            setBackground(resourceId);
        } else {
            setBackgroundColor(ContextCompat.getColor(getContext(), R.color.dialog_background_light));
        }
    }

    /**
     * Obtains the message color from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the message color should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainMessageColor(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogMessageColor });
        int defaultColor = ThemeUtil.getColor(getContext(), themeResourceId, android.R.attr.textColorSecondary);
        setMessageColor(typedArray.getColor(0, defaultColor));
    }

    /**
     * Obtains the title color from a specific theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, the title color should be obtained from, as an {@link
     *         Integer} value
     */
    private void obtainTitleColor(@StyleRes final int themeResourceId) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(themeResourceId,
                new int[] { R.attr.materialDialogTitleColor });
        int defaultColor = ThemeUtil.getColor(getContext(), themeResourceId, android.R.attr.textColorPrimary);
        setTitleColor(typedArray.getColor(0, defaultColor));
    }

    /**
     * Obtains all relevant attributes from the current theme.
     *
     * @param themeResourceId
     *         The resource id of the theme, which should be used by the dialog, as an {@link
     *         Integer} value. The resource id must correspond to a valid style resource
     */
    @CallSuper
    protected void obtainStyledAttributes(@StyleRes final int themeResourceId) {
        obtainFullscreen(themeResourceId);
        obtainGravity(themeResourceId);
        obtainWidth(themeResourceId);
        obtainHeight(themeResourceId);
        obtainMaxWidth(themeResourceId);
        obtainMaxHeight(themeResourceId);
        obtainMargin(themeResourceId);
        obtainFitsSystemWindows(themeResourceId);
        obtainBackground(themeResourceId);
        obtainMessageColor(themeResourceId);
        obtainTitleColor(themeResourceId);
    }

    /**
     * Returns the resource id of the theme, which is used by the dialog.
     *
     * @return The resource id of the theme, which is used by the dialog, as an {@link Integer}
     * value
     */
    @StyleRes
    protected final int getThemeResourceId() {
        return themeResourceId;
    }

    /**
     * Creates a new builder, which allows to create and show dialogs, which are designed according
     * to Android 5's Material Design guidelines even on pre-Lollipop devices.
     *
     * @param context
     *         The context, which should be used by the builder, as an instance of the class {@link
     *         Context}. The context may not be null
     */
    public AbstractMaterialDialogBuilder(@NonNull final Context context) {
        super(context);
        initialize(0);
    }

    /**
     * Creates a new builder, which allows to create and show dialogs, which are designed according
     * to Android 5's Material Design guidelines even on pre-Lollipop devices.
     *
     * @param context
     *         The context, which should be used by the builder, as an instance of the class {@link
     *         Context}. The context may not be null
     * @param themeResourceId
     *         The resource id of the theme, which should be used by the dialog, as an {@link
     *         Integer} value. The resource id must correspond to a valid theme
     */
    public AbstractMaterialDialogBuilder(@NonNull final Context context, @StyleRes final int themeResourceId) {
        super(context);
        initialize(themeResourceId);
    }

    /**
     * Sets, whether the dialog, which is created by the builder, should be cancelable, or not.
     *
     * @param cancelable
     *         True, if the dialog, which is created by the builder, should be cancelable, false
     *         otherwise
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setCancelable(final boolean cancelable) {
        getProduct().setCancelable(cancelable);
        return self();
    }

    /**
     * Sets, whether the dialog, which is created by the builder, should be canceled, when touched
     * outside the window's bounds. If set to true, the dialog is set to be cancelable, if not
     * already set.
     *
     * @param canceledOnTouchOutside
     *         True, if the dialog should be canceled, when touched outside the window, false
     *         otherwise
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setCanceledOnTouchOutside(final boolean canceledOnTouchOutside) {
        getProduct().setCanceledOnTouchOutside(canceledOnTouchOutside);
        return self();
    }

    /**
     * Sets the listener, which should be notified, when the dialog has been shown.
     *
     * @param listener
     *         The listener, which should be set, as an instance of the type {@link
     *         DialogInterface.OnShowListener}, or null, if no listener should be set
     */
    public BuilderType setOnShowListener(@Nullable final DialogInterface.OnShowListener listener) {
        getProduct().setOnShowListener(listener);
        return self();
    }

    /**
     * Sets the listener, which should be notified, when the dialog, which is created by the
     * builder, is canceled.
     *
     * Even in a cancelable dialog, the dialog may be dismissed for reasons other than being
     * canceled or one of the supplied choices being selected. If you are interested in listening
     * for all cases where the dialog is dismissed and not just when it is canceled, see {@link
     * #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
     * setOnDismissListener}.
     *
     * @param listener
     *         The listener, which should be set, as an instance of the type {@link
     *         DialogInterface.OnCancelListener}, or null, if no listener should be set
     * @return The builder, the method has been called upon, as an instance of the class BuilderType
     * @see #setCancelable(boolean)
     * @see #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
     */
    public BuilderType setOnCancelListener(@Nullable final DialogInterface.OnCancelListener listener) {
        getProduct().setOnCancelListener(listener);
        return self();
    }

    /**
     * Sets the listener, which should be notified, when the dialog, which is created by the
     * builder, is dismissed for any reason.
     *
     * @param listener
     *         The listener, which should be set, as an instance of the type {@link
     *         DialogInterface.OnDismissListener}, or null, if no listener should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setOnDismissListener(@Nullable final DialogInterface.OnDismissListener listener) {
        getProduct().setOnDismissListener(listener);
        return self();
    }

    /**
     * Sets, whether the dialog, which is created by the builder, should be shown fullscreen, or
     * not.
     *
     * @param fullscreen
     *         True, if the dialog should be shown fullscreen, false otherwise
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setFullscreen(final boolean fullscreen) {
        getProduct().setFullscreen(fullscreen);
        return self();
    }

    /**
     * Sets the gravity of the dialog, which is created by the builder.
     *
     * @param gravity
     *         The gravity, which should be set, as an {@link Integer} value. The gravity must
     *         consist of the flags given in {@link Dialog.Gravity}
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setGravity(final int gravity) {
        getProduct().setGravity(gravity);
        return self();
    }

    /**
     * Sets the width of the dialog, which is created by the builder.
     *
     * @param width
     *         The width, which should be set, in pixels as an {@link Integer} value. The width must
     *         be at least 1 or {@link Dialog#MATCH_PARENT}, respectively {@link
     *         Dialog#WRAP_CONTENT}
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setWidth(final int width) {
        getProduct().setWidth(width);
        return self();
    }

    /**
     * Sets the height of the dialog, which is created by the builder.
     *
     * @param height
     *         The height, which should be set, in pixels as an {@link Integer} value. The width
     *         must be at least 1 or {@link Dialog#MATCH_PARENT}, respectively {@link
     *         Dialog#WRAP_CONTENT}
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setHeight(final int height) {
        getProduct().setHeight(height);
        return self();
    }

    /**
     * Sets the maximum width of the dialog, which is created by the builder.
     *
     * @param maxWidth
     *         The maximum width, which should be set, in pixels as an {@link Integer} value. The
     *         maximum width must be at least 1, or -1, if no maximum width should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setMaxWidth(final int maxWidth) {
        getProduct().setMaxWidth(maxWidth);
        return self();
    }

    /**
     * Sets the maximum height of the dialog, which is created by the builder.
     *
     * @param maxHeight
     *         The maximum height, which should be set, in pixels as an {@link Integer} value. The
     *         maximum height must be at least 1, or -1, if no maximum height should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setMaxHeight(final int maxHeight) {
        getProduct().setMaxHeight(maxHeight);
        return self();
    }

    /**
     * Sets the margin of the dialog, which is created by the builder.
     *
     * @param left
     *         The left margin, which should be set, in pixels as an {@link Integer} value. The left
     *         margin must be at least 0
     * @param top
     *         The top margin, which should be set, in pixels as an {@link Integer} value. The top
     *         margin must be at least 0
     * @param right
     *         The right margin, which should be set, in pixels as an {@link Integer} value. The
     *         right margin must be at least 0
     * @param bottom
     *         The bottom margin, which should be set, in pixels as an {@link Integer} value. The
     *         bottom margin must be at least 0
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setMargin(final int left, final int top, final int right, final int bottom) {
        getProduct().setMargin(left, top, right, bottom);
        return self();
    }

    /**
     * Sets, whether the dialog, which is created by the builder, should account for system screen
     * decorations such as the status bar and inset its content, or not.
     *
     * @param fitsSystemWindows
     *         True, if the dialog should inset its content, false otherwise
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setFitsSystemWindows(final boolean fitsSystemWindows) {
        getProduct().setFitsSystemWindows(fitsSystemWindows);
        return self();
    }

    /**
     * Sets, whether the dialog, which is created by the builder, should account for system screen
     * decorations such as the status bar and inset its content, or not.
     *
     * @param left
     *         True, if the dialog should inset its content at the left edge, false otherwise
     * @param top
     *         True, if the dialog should inset its content at the top edge, false otherwise
     * @param right
     *         True, if the dialog should inset its content at the right edge, false otherwise
     * @param bottom
     *         True, if the dialog should inset its content at the bottom edge, false otherwise
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setFitsSystemWindows(final boolean left, final boolean top, final boolean right,
            final boolean bottom) {
        getProduct().setFitsSystemWindows(left, top, right, bottom);
        return self();
    }

    /**
     * Sets the color of the title of the dialog, which is created by the builder.
     *
     * @param color
     *         The color, which should be set, as an {@link Integer} value or -1, if no custom color
     *         should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setTitleColor(@ColorInt final int color) {
        getProduct().setTitleColor(color);
        return self();
    }

    /**
     * Sets the color of the message of the dialog, which is created by the builder.
     *
     * @param color
     *         The color, which should be set, as an {@link Integer} value or -1, if no custom color
     *         should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setMessageColor(@ColorInt final int color) {
        getProduct().setMessageColor(color);
        return self();
    }

    /**
     * Sets the background of the dialog, which is created by the builder.
     *
     * @param background
     *         The background, which should be set, as an instance of the class {@link Bitmap} or
     *         null, if no custom background should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setBackground(@Nullable final Bitmap background) {
        getProduct().setBackground(background);
        return self();
    }

    /**
     * Sets the background of the dialog, which is created by the builder.
     *
     * @param resourceId
     *         The resource id of the background, which should be set, as an {@link Integer} value.
     *         The resource id must correspond to a valid drawable resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setBackground(@DrawableRes final int resourceId) {
        getProduct().setBackground(resourceId);
        return self();
    }

    /**
     * Sets the background color of the dialog, which is created by the builder.
     *
     * @param color
     *         The background color, which should be set, as an {@link Integer} value or -1, if no
     *         custom background color should be set
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setBackgroundColor(@ColorInt final int color) {
        getProduct().setBackgroundColor(color);
        return self();
    }

    /**
     * Sets the title of the dialog, which is created by the builder.
     *
     * @param title
     *         The title, which should be set, as an instance of the type {@link CharSequence} or
     *         null, if no title should be shown
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setTitle(@Nullable final CharSequence title) {
        getProduct().setTitle(title);
        return self();
    }

    /**
     * Sets the title of the dialog, which is created by the builder.
     *
     * @param resourceId
     *         The resource id of the title, which should be set, as an {@link Integer} value. The
     *         resource id must correspond to a valid string resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setTitle(@StringRes final int resourceId) {
        getProduct().setTitle(resourceId);
        return self();
    }

    /**
     * Sets the message of the dialog, which is created by the builder.
     *
     * @param message
     *         The message, which should be set, as an instance of the type {@link CharSequence} or
     *         null, if no message should be shown
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setMessage(@Nullable final CharSequence message) {
        getProduct().setMessage(message);
        return self();
    }

    /**
     * Sets the message of the dialog, which is created by the builder.
     *
     * @param resourceId
     *         The resource id of the message, which should be set, as an {@link Integer} value. The
     *         resource id must correspond to a valid string resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setMessage(@StringRes final int resourceId) {
        getProduct().setMessage(resourceId);
        return self();
    }

    /**
     * Sets the icon of the dialog, which is created by the builder.
     *
     * @param icon
     *         The icon, which should be set, as an instance of the class {@link Bitmap} or null, if
     *         no icon should be shown
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setIcon(@Nullable final Bitmap icon) {
        getProduct().setIcon(icon);
        return self();
    }

    /**
     * Sets the icon of the dialog, which is created by the builder.
     *
     * @param resourceId
     *         The resource id of the icon, which should be set, as an {@link Integer} value. The
     *         resource id must correspond to a valid drawable resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setIcon(@DrawableRes final int resourceId) {
        getProduct().setIcon(resourceId);
        return self();
    }

    /**
     * Set the icon of the dialog, which is created by the builder.
     *
     * @param attributeId
     *         The id of the theme attribute, which supplies the icon, which should be set, as an
     *         {@link Integer} value. The id must point to a valid drawable resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setIconAttribute(@AttrRes final int attributeId) {
        getProduct().setIconAttribute(attributeId);
        return self();
    }

    /**
     * Sets the custom view, which should be shown by the dialog, which is created by the builder.
     *
     * @param view
     *         The view, which should be set, as an instance of the class {@link View} or null, if
     *         no custom view should be shown
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setView(@Nullable final View view) {
        getProduct().setView(view);
        return self();
    }

    /**
     * Sets the custom view, which should be shown by the dialog, which is created by the builder.
     *
     * @param resourceId
     *         The resource id of the view, which should be set, as an {@link Integer} value. The
     *         resource id must correspond to a valid layout resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setView(@LayoutRes final int resourceId) {
        getProduct().setView(resourceId);
        return self();
    }

    /**
     * Sets the custom view, which should be used to show the title of the dialog, which is created
     * by the builder.
     *
     * @param view
     *         The view, which should be set, as an instance of the class {@link View} or null, if
     *         no custom view should be used to show the title
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setCustomTitle(@Nullable final View view) {
        getProduct().setCustomTitle(view);
        return self();
    }

    /**
     * Sets the custom view, which should be used to show the title of the dialog, which is created
     * by the builder.
     *
     * @param resourceId
     *         The resource id of the view, which should be set, as an {@link Integer} value. The
     *         resource id must correspond to a valid layout resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setCustomTitle(@LayoutRes final int resourceId) {
        getProduct().setCustomTitle(resourceId);
        return self();
    }

    /**
     * Sets the custom view, which should be used to show the message of the dialog, which is
     * created by the builder.
     *
     * @param view
     *         The view, which should be set, as an instance of the class {@link View} or null, if
     *         no custom view should be used to show the message
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setCustomMessage(@Nullable final View view) {
        getProduct().setCustomMessage(view);
        return self();
    }

    /**
     * Sets the custom view, which should be used to show the message of the dialog, which is
     * created by the builder.
     *
     * @param resourceId
     *         The resource id of the view, which should be set, as an {@link Integer} value. The
     *         resource id must correspond to a valid layout resource
     * @return The builder, the method has been called upon, as an instance of the generic type
     * BuilderType
     */
    public final BuilderType setCustomMessage(@LayoutRes final int resourceId) {
        getProduct().setCustomMessage(resourceId);
        return self();
    }

}