|
@@ -0,0 +1,665 @@
|
|
|
+package com.afollestad.materialdialogs;
|
|
|
+
|
|
|
+import android.annotation.SuppressLint;
|
|
|
+import android.app.Activity;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.res.ColorStateList;
|
|
|
+import android.content.res.TypedArray;
|
|
|
+import android.graphics.Paint;
|
|
|
+import android.graphics.Typeface;
|
|
|
+import android.os.Build;
|
|
|
+import android.support.annotation.ArrayRes;
|
|
|
+import android.support.annotation.ColorRes;
|
|
|
+import android.support.annotation.LayoutRes;
|
|
|
+import android.support.annotation.NonNull;
|
|
|
+import android.support.annotation.StringRes;
|
|
|
+import android.text.method.LinkMovementMethod;
|
|
|
+import android.view.ContextThemeWrapper;
|
|
|
+import android.view.Gravity;
|
|
|
+import android.view.LayoutInflater;
|
|
|
+import android.view.View;
|
|
|
+import android.view.ViewGroup;
|
|
|
+import android.widget.CheckBox;
|
|
|
+import android.widget.LinearLayout;
|
|
|
+import android.widget.RadioButton;
|
|
|
+import android.widget.TextView;
|
|
|
+
|
|
|
+import com.afollestad.materialdialogs.base.DialogBase;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+
|
|
|
+ * @author Aidan Follestad (afollestad)
|
|
|
+ */
|
|
|
+public class MaterialDialog extends DialogBase implements View.OnClickListener {
|
|
|
+
|
|
|
+ private Context mContext;
|
|
|
+ private CharSequence positiveText;
|
|
|
+ private TextView positiveButton;
|
|
|
+ private CharSequence neutralText;
|
|
|
+ private TextView neutralButton;
|
|
|
+ private CharSequence negativeText;
|
|
|
+ private TextView negativeButton;
|
|
|
+ private View view;
|
|
|
+ private int positiveColor;
|
|
|
+ private SimpleCallback callback;
|
|
|
+ private ListCallback listCallback;
|
|
|
+ private ListCallback listCallbackSingle;
|
|
|
+ private ListCallbackMulti listCallbackMulti;
|
|
|
+ private View customView;
|
|
|
+ private float buttonHeight;
|
|
|
+ private String[] items;
|
|
|
+ private boolean isStacked;
|
|
|
+ private int selectedIndex;
|
|
|
+ private Integer[] selectedIndices;
|
|
|
+
|
|
|
+ private Typeface regularFont;
|
|
|
+ private Typeface mediumFont;
|
|
|
+
|
|
|
+ MaterialDialog(Builder builder) {
|
|
|
+ super(new ContextThemeWrapper(builder.context, builder.theme == Theme.LIGHT ? R.style.Light : R.style.Dark));
|
|
|
+
|
|
|
+ this.mContext = builder.context;
|
|
|
+ this.view = LayoutInflater.from(builder.context).inflate(R.layout.material_dialog, null);
|
|
|
+ this.customView = builder.customView;
|
|
|
+ this.callback = builder.callback;
|
|
|
+ this.listCallback = builder.listCallback;
|
|
|
+ this.listCallbackSingle = builder.listCallbackSingle;
|
|
|
+ this.listCallbackMulti = builder.listCallbackMulti;
|
|
|
+ this.positiveText = builder.positiveText;
|
|
|
+ this.neutralText = builder.neutralText;
|
|
|
+ this.negativeText = builder.negativeText;
|
|
|
+ this.positiveColor = builder.positiveColor;
|
|
|
+ this.items = builder.items;
|
|
|
+ this.setCancelable(builder.cancelable);
|
|
|
+ this.regularFont = Typeface.createFromAsset(getContext().getResources().getAssets(), "Roboto-Regular.ttf");
|
|
|
+ this.mediumFont = Typeface.createFromAsset(getContext().getResources().getAssets(), "Roboto-Medium.ttf");
|
|
|
+ this.selectedIndex = builder.selectedIndex;
|
|
|
+ this.selectedIndices = builder.selectedIndicies;
|
|
|
+
|
|
|
+ TextView title = (TextView) view.findViewById(R.id.title);
|
|
|
+ TextView content = (TextView) view.findViewById(R.id.content);
|
|
|
+
|
|
|
+ content.setText(builder.content);
|
|
|
+ content.setMovementMethod(new LinkMovementMethod());
|
|
|
+ content.setVisibility(View.VISIBLE);
|
|
|
+ content.setTypeface(regularFont);
|
|
|
+ content.setTextColor(Utils.resolveColor(getContext(), R.attr.content_color));
|
|
|
+ content.setLineSpacing(0f, builder.contentLineSpacingMultiplier);
|
|
|
+ if (this.positiveColor == 0) {
|
|
|
+ content.setLinkTextColor(Utils.resolveColor(getContext(), R.attr.button_color));
|
|
|
+ } else {
|
|
|
+ content.setLinkTextColor(this.positiveColor);
|
|
|
+ }
|
|
|
+ if (builder.contentAlignment == Alignment.CENTER) {
|
|
|
+ content.setGravity(Gravity.CENTER_HORIZONTAL);
|
|
|
+ } else if (builder.contentAlignment == Alignment.RIGHT) {
|
|
|
+ content.setGravity(Gravity.RIGHT);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (customView != null) {
|
|
|
+ title = (TextView) view.findViewById(R.id.titleCustomView);
|
|
|
+ buttonHeight = mContext.getResources().getDimension(R.dimen.button_height_customview);
|
|
|
+ view.findViewById(R.id.mainFrame).setVisibility(View.GONE);
|
|
|
+ view.findViewById(R.id.customViewScrollParent).setVisibility(View.VISIBLE);
|
|
|
+ view.findViewById(R.id.customViewDivider).setVisibility(View.VISIBLE);
|
|
|
+ view.findViewById(R.id.customViewDivider).setBackgroundColor(Utils.resolveColor(getContext(), R.attr.divider_color));
|
|
|
+ View firstChild = customView;
|
|
|
+ View lastChild = customView;
|
|
|
+ final int frameMargin = (int) mContext.getResources().getDimension(R.dimen.dialog_frame_margin);
|
|
|
+ if (customView instanceof ViewGroup) {
|
|
|
+ ViewGroup group = (ViewGroup) customView;
|
|
|
+ firstChild = group.getChildAt(0);
|
|
|
+ lastChild = group.getChildAt(group.getChildCount() - 1);
|
|
|
+ }
|
|
|
+ if (builder.title == null || builder.title.toString().trim().isEmpty())
|
|
|
+ setMargin(firstChild, frameMargin, -1, -1, -1);
|
|
|
+ setMargin(lastChild, -1, frameMargin, -1, -1);
|
|
|
+ ((LinearLayout) view.findViewById(R.id.customViewFrame)).addView(customView);
|
|
|
+ } else {
|
|
|
+ buttonHeight = mContext.getResources().getDimension(R.dimen.button_height);
|
|
|
+ view.findViewById(R.id.mainFrame).setVisibility(View.VISIBLE);
|
|
|
+ view.findViewById(R.id.customViewScrollParent).setVisibility(View.GONE);
|
|
|
+ view.findViewById(R.id.customViewDivider).setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (builder.title == null || builder.title.toString().trim().isEmpty()) {
|
|
|
+ title.setVisibility(View.GONE);
|
|
|
+ } else {
|
|
|
+ title.setText(builder.title);
|
|
|
+ title.setTypeface(mediumFont);
|
|
|
+ if (builder.titleColor != -1) {
|
|
|
+ title.setTextColor(builder.titleColor);
|
|
|
+ } else {
|
|
|
+ title.setTextColor(Utils.resolveColor(getContext(), R.attr.title_color));
|
|
|
+ }
|
|
|
+ if (builder.titleAlignment == Alignment.CENTER) {
|
|
|
+ title.setGravity(Gravity.CENTER_HORIZONTAL);
|
|
|
+ } else if (builder.titleAlignment == Alignment.RIGHT) {
|
|
|
+ title.setGravity(Gravity.RIGHT);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ invalidateList();
|
|
|
+ invalidateActions();
|
|
|
+ checkIfStackingNeeded();
|
|
|
+ setViewInternal(view);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Invalidates the radio buttons in the single choice mode list so that only the radio button that
|
|
|
+ * was previous selected is checked.
|
|
|
+ */
|
|
|
+ private void invalidateSingleChoice(int newSelection) {
|
|
|
+ LinearLayout list = (LinearLayout) view.findViewById(R.id.listFrame);
|
|
|
+ for (int i = 0; i < list.getChildCount(); i++) {
|
|
|
+ View v = list.getChildAt(i);
|
|
|
+ @SuppressLint("WrongViewCast")
|
|
|
+ RadioButton rb = (RadioButton) v.findViewById(R.id.control);
|
|
|
+ rb.setChecked(newSelection == i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Constructs the dialog's list content and sets up click listeners.
|
|
|
+ */
|
|
|
+ @SuppressLint("WrongViewCast")
|
|
|
+ private void invalidateList() {
|
|
|
+ if (items == null || items.length == 0) return;
|
|
|
+ view.findViewById(R.id.content).setVisibility(View.GONE);
|
|
|
+
|
|
|
+ View title = view.findViewById(R.id.title);
|
|
|
+ setMargin(title, -1, (int) mContext.getResources().getDimension(R.dimen.button_padding), 0, 0);
|
|
|
+ View mainFrame = view.findViewById(R.id.mainFrame);
|
|
|
+ int dpPadding = (int) mContext.getResources().getDimension(R.dimen.button_frame_margin);
|
|
|
+ setMargin(mainFrame, dpPadding, 0, dpPadding, dpPadding);
|
|
|
+
|
|
|
+ view.findViewById(R.id.listFrameScrollParent).setVisibility(View.VISIBLE);
|
|
|
+ LinearLayout list = (LinearLayout) view.findViewById(R.id.listFrame);
|
|
|
+ LayoutInflater li = LayoutInflater.from(mContext);
|
|
|
+
|
|
|
+ final int itemColor = Utils.resolveColor(getContext(), R.attr.item_color);
|
|
|
+ for (int index = 0; index < items.length; index++) {
|
|
|
+ View il;
|
|
|
+ if (listCallbackSingle != null) {
|
|
|
+ il = li.inflate(R.layout.dialog_listitem_singlechoice, null);
|
|
|
+ if (selectedIndex > -1) {
|
|
|
+ ((RadioButton) il.findViewById(R.id.control)).setChecked(selectedIndex == index);
|
|
|
+ }
|
|
|
+ } else if (listCallbackMulti != null) {
|
|
|
+ il = li.inflate(R.layout.dialog_listitem_multichoice, null);
|
|
|
+ if (selectedIndices != null) {
|
|
|
+ if (Arrays.asList(selectedIndices).contains(index))
|
|
|
+ ((CheckBox) il.findViewById(R.id.control)).setChecked(true);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ il = li.inflate(R.layout.dialog_listitem, null);
|
|
|
+ }
|
|
|
+ TextView tv = (TextView) il.findViewById(R.id.title);
|
|
|
+ tv.setText(items[index]);
|
|
|
+ tv.setTextColor(itemColor);
|
|
|
+ il.setTag(index + ":" + items[index]);
|
|
|
+ il.setOnClickListener(this);
|
|
|
+ list.addView(il);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Measures the action button's and their text to decide whether or not the button should be stacked.
|
|
|
+ */
|
|
|
+ private void checkIfStackingNeeded() {
|
|
|
+ if (((negativeButton == null || negativeButton.getVisibility() == View.GONE) &&
|
|
|
+ (neutralButton == null || neutralButton.getVisibility() == View.GONE))) {
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Paint paint = positiveButton.getPaint();
|
|
|
+ float buttonMinWidth = mContext.getResources().getDimension(R.dimen.button_min_width);
|
|
|
+ float totalWidth = paint.measureText(positiveButton.getText().toString());
|
|
|
+ if (this.neutralText != null)
|
|
|
+ totalWidth += paint.measureText(neutralButton.getText().toString());
|
|
|
+ if (this.negativeText != null)
|
|
|
+ totalWidth += paint.measureText(negativeButton.getText().toString());
|
|
|
+ isStacked = totalWidth > (buttonMinWidth * 3);
|
|
|
+ invalidateActions();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Invalidates the positive/neutral/negative action buttons. Decides whether they should be visible
|
|
|
+ * and sets their properties (such as height, text color, etc.).
|
|
|
+ */
|
|
|
+ private void invalidateActions() {
|
|
|
+ if (items != null && listCallbackSingle == null && listCallbackMulti == null) {
|
|
|
+
|
|
|
+ view.findViewById(R.id.buttonDefaultFrame).setVisibility(View.GONE);
|
|
|
+ view.findViewById(R.id.buttonStackedFrame).setVisibility(View.GONE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ final int buttonFrameMargin = (int) mContext.getResources().getDimension(R.dimen.button_frame_margin);
|
|
|
+ if (isStacked) {
|
|
|
+ view.findViewById(R.id.buttonDefaultFrame).setVisibility(View.GONE);
|
|
|
+ view.findViewById(R.id.buttonStackedFrame).setVisibility(View.VISIBLE);
|
|
|
+ if (customView == null)
|
|
|
+ setMargin(view.findViewById(R.id.buttonStackedFrame), -1, buttonFrameMargin, -1, -1);
|
|
|
+ } else {
|
|
|
+ view.findViewById(R.id.buttonDefaultFrame).setVisibility(View.VISIBLE);
|
|
|
+ view.findViewById(R.id.buttonStackedFrame).setVisibility(View.GONE);
|
|
|
+ if (customView == null)
|
|
|
+ setMargin(view.findViewById(R.id.buttonDefaultFrame), -1, buttonFrameMargin, -1, -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ positiveButton = (TextView) view.findViewById(
|
|
|
+ isStacked ? R.id.buttonStackedPositive : R.id.buttonDefaultPositive);
|
|
|
+ setHeight(positiveButton, buttonHeight);
|
|
|
+ positiveButton.setTypeface(mediumFont);
|
|
|
+ if (this.positiveText == null)
|
|
|
+ this.positiveText = mContext.getString(R.string.accept);
|
|
|
+ positiveButton.setText(this.positiveText);
|
|
|
+ positiveButton.setTextColor(getActionTextStateList(this.positiveColor));
|
|
|
+
|
|
|
+ positiveButton.setTag(POSITIVE);
|
|
|
+ positiveButton.setOnClickListener(this);
|
|
|
+
|
|
|
+ neutralButton = (TextView) view.findViewById(
|
|
|
+ isStacked ? R.id.buttonStackedNeutral : R.id.buttonDefaultNeutral);
|
|
|
+ setHeight(neutralButton, buttonHeight);
|
|
|
+ neutralButton.setTypeface(mediumFont);
|
|
|
+ if (this.neutralText != null) {
|
|
|
+ neutralButton.setVisibility(View.VISIBLE);
|
|
|
+ neutralButton.setTextColor(getActionTextStateList(0));
|
|
|
+ neutralButton.setText(this.neutralText);
|
|
|
+ neutralButton.setTag(NEUTRAL);
|
|
|
+ neutralButton.setOnClickListener(this);
|
|
|
+ } else {
|
|
|
+ neutralButton.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+
|
|
|
+ negativeButton = (TextView) view.findViewById(
|
|
|
+ isStacked ? R.id.buttonStackedNegative : R.id.buttonDefaultNegative);
|
|
|
+ setHeight(negativeButton, buttonHeight);
|
|
|
+ negativeButton.setTypeface(mediumFont);
|
|
|
+ if (this.negativeText != null) {
|
|
|
+ negativeButton.setVisibility(View.VISIBLE);
|
|
|
+ negativeButton.setTextColor(getActionTextStateList(0));
|
|
|
+ negativeButton.setText(this.negativeText);
|
|
|
+ negativeButton.setTag(NEGATIVE);
|
|
|
+ negativeButton.setOnClickListener(this);
|
|
|
+ } else {
|
|
|
+ negativeButton.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final void onClick(View v) {
|
|
|
+ String tag = (String) v.getTag();
|
|
|
+ if (tag.equals(POSITIVE)) {
|
|
|
+ if (listCallbackSingle != null) {
|
|
|
+ dismiss();
|
|
|
+ LinearLayout list = (LinearLayout) view.findViewById(R.id.listFrame);
|
|
|
+ for (int i = 0; i < list.getChildCount(); i++) {
|
|
|
+ View itemView = list.getChildAt(i);
|
|
|
+ @SuppressLint("WrongViewCast")
|
|
|
+ RadioButton rb = (RadioButton) itemView.findViewById(R.id.control);
|
|
|
+ if (rb.isChecked()) {
|
|
|
+ listCallbackSingle.onSelection(this, i, ((TextView) itemView.findViewById(R.id.title)).getText().toString());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (listCallbackMulti != null) {
|
|
|
+ dismiss();
|
|
|
+ List<Integer> selectedIndices = new ArrayList<Integer>();
|
|
|
+ List<String> selectedTitles = new ArrayList<String>();
|
|
|
+ LinearLayout list = (LinearLayout) view.findViewById(R.id.listFrame);
|
|
|
+ for (int i = 0; i < list.getChildCount(); i++) {
|
|
|
+ View itemView = list.getChildAt(i);
|
|
|
+ CheckBox rb = (CheckBox) itemView.findViewById(R.id.control);
|
|
|
+ if (rb.isChecked()) {
|
|
|
+ selectedIndices.add(i);
|
|
|
+ selectedTitles.add(((TextView) itemView.findViewById(R.id.title)).getText().toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ listCallbackMulti.onSelection(this,
|
|
|
+ selectedIndices.toArray(new Integer[selectedIndices.size()]),
|
|
|
+ selectedTitles.toArray(new String[selectedTitles.size()]));
|
|
|
+ } else if (callback != null) {
|
|
|
+ dismiss();
|
|
|
+ callback.onPositive(this);
|
|
|
+ }
|
|
|
+ } else if (tag.equals(NEGATIVE)) {
|
|
|
+ if (callback != null && callback instanceof Callback) {
|
|
|
+ dismiss();
|
|
|
+ ((Callback) callback).onNegative(this);
|
|
|
+ }
|
|
|
+ } else if (tag.equals(NEUTRAL)) {
|
|
|
+ if (callback != null && callback instanceof FullCallback) {
|
|
|
+ dismiss();
|
|
|
+ ((FullCallback) callback).onNeutral(this);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ String[] split = tag.split(":");
|
|
|
+ int index = Integer.parseInt(split[0]);
|
|
|
+ if (listCallback != null) {
|
|
|
+ dismiss();
|
|
|
+ listCallback.onSelection(this, index, split[1]);
|
|
|
+ } else if (listCallbackSingle != null) {
|
|
|
+ RadioButton cb = (RadioButton) ((LinearLayout) v).getChildAt(0);
|
|
|
+ cb.performClick();
|
|
|
+ invalidateSingleChoice(index);
|
|
|
+ } else if (listCallbackMulti != null) {
|
|
|
+ CheckBox cb = (CheckBox) ((LinearLayout) v).getChildAt(0);
|
|
|
+ cb.performClick();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * The class used to construct a MaterialDialog.
|
|
|
+ */
|
|
|
+ public static class Builder {
|
|
|
+
|
|
|
+ protected Activity context;
|
|
|
+ protected CharSequence title;
|
|
|
+ protected Alignment titleAlignment = Alignment.LEFT;
|
|
|
+ protected Alignment contentAlignment = Alignment.LEFT;
|
|
|
+ protected int titleColor = -1;
|
|
|
+ protected CharSequence content;
|
|
|
+ protected String[] items;
|
|
|
+ protected CharSequence positiveText;
|
|
|
+ protected CharSequence neutralText;
|
|
|
+ protected CharSequence negativeText;
|
|
|
+ protected View customView;
|
|
|
+ protected int positiveColor;
|
|
|
+ protected SimpleCallback callback;
|
|
|
+ protected ListCallback listCallback;
|
|
|
+ protected ListCallback listCallbackSingle;
|
|
|
+ private ListCallbackMulti listCallbackMulti;
|
|
|
+ protected Theme theme = Theme.LIGHT;
|
|
|
+ protected boolean cancelable = true;
|
|
|
+ protected float contentLineSpacingMultiplier = 1.0f;
|
|
|
+ protected int selectedIndex = -1;
|
|
|
+ protected Integer[] selectedIndicies = null;
|
|
|
+
|
|
|
+ public Builder(@NonNull Activity context) {
|
|
|
+ this.context = context;
|
|
|
+ this.positiveText = context.getString(android.R.string.ok);
|
|
|
+ final int materialBlue = context.getResources().getColor(R.color.material_blue_500);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
|
+ TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
|
|
|
+ try {
|
|
|
+ this.positiveColor = a.getColor(0, materialBlue);
|
|
|
+ } finally {
|
|
|
+ a.recycle();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.positiveColor = materialBlue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder title(@StringRes int titleRes) {
|
|
|
+ title(this.context.getString(titleRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder title(CharSequence title) {
|
|
|
+ this.title = title;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder titleAlignment(Alignment align) {
|
|
|
+ this.titleAlignment = align;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder titleColorRes(@ColorRes int colorRes) {
|
|
|
+ titleColor(this.context.getResources().getColor(colorRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder titleColor(int color) {
|
|
|
+ this.titleColor = color;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder content(@StringRes int contentRes) {
|
|
|
+ content(this.context.getString(contentRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder content(CharSequence content) {
|
|
|
+ this.content = content;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder content(@StringRes int contentRes, Object... formatArgs) {
|
|
|
+ content(this.context.getString(contentRes, formatArgs));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder contentAlignment(Alignment align) {
|
|
|
+ this.contentAlignment = align;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder contentLineSpacing(float multiplier) {
|
|
|
+ this.contentLineSpacingMultiplier = multiplier;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder items(@ArrayRes int itemsRes) {
|
|
|
+ items(this.context.getResources().getStringArray(itemsRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder items(String[] items) {
|
|
|
+ this.items = items;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder itemsCallback(ListCallback callback) {
|
|
|
+ this.listCallback = callback;
|
|
|
+ this.listCallbackSingle = null;
|
|
|
+ this.listCallbackMulti = null;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Pass anything below 0 (such as -1) for the selected index to leave all options unselected initially.
|
|
|
+ * Otherwise pass the index of an item that will be selected initially.
|
|
|
+ */
|
|
|
+ public Builder itemsCallbackSingleChoice(int selectedIndex, ListCallback callback) {
|
|
|
+ this.selectedIndex = selectedIndex;
|
|
|
+ this.listCallback = null;
|
|
|
+ this.listCallbackSingle = callback;
|
|
|
+ this.listCallbackMulti = null;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Pass null for the selected indices to leave all options unselected initially. Otherwise pass
|
|
|
+ * an array of indices that will be selected initially.
|
|
|
+ */
|
|
|
+ public Builder itemsCallbackMultiChoice(Integer[] selectedIndices, ListCallbackMulti callback) {
|
|
|
+ this.selectedIndicies = selectedIndices;
|
|
|
+ this.listCallback = null;
|
|
|
+ this.listCallbackSingle = null;
|
|
|
+ this.listCallbackMulti = callback;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder positiveText(@StringRes int postiveRes) {
|
|
|
+ positiveText(this.context.getString(postiveRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder positiveText(CharSequence message) {
|
|
|
+ this.positiveText = message;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder neutralText(@StringRes int neutralRes) {
|
|
|
+ neutralText(this.context.getString(neutralRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder neutralText(CharSequence message) {
|
|
|
+ this.neutralText = message;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder negativeText(@StringRes int negativeRes) {
|
|
|
+ negativeText(this.context.getString(negativeRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder negativeText(CharSequence message) {
|
|
|
+ this.negativeText = message;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder customView(@LayoutRes int layoutRes) {
|
|
|
+ LayoutInflater li = LayoutInflater.from(this.context);
|
|
|
+ customView(li.inflate(layoutRes, null));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder customView(View view) {
|
|
|
+ this.customView = view;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder positiveColorRes(@ColorRes int colorRes) {
|
|
|
+ positiveColor(this.context.getResources().getColor(colorRes));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder positiveColor(int color) {
|
|
|
+ this.positiveColor = color;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder callback(SimpleCallback callback) {
|
|
|
+ this.callback = callback;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder theme(Theme theme) {
|
|
|
+ this.theme = theme;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder cancelable(boolean cancelable) {
|
|
|
+ this.cancelable = cancelable;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public MaterialDialog build() {
|
|
|
+ return new MaterialDialog(this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private ColorStateList getActionTextStateList(int newPrimaryColor) {
|
|
|
+ final int buttonColor = Utils.resolveColor(getContext(), R.attr.button_color);
|
|
|
+ if (newPrimaryColor == 0) newPrimaryColor = buttonColor;
|
|
|
+ int[][] states = new int[][]{
|
|
|
+ new int[]{-android.R.attr.state_enabled},
|
|
|
+ new int[]{}
|
|
|
+ };
|
|
|
+ int[] colors = new int[]{
|
|
|
+ Utils.adjustAlpha(buttonColor, 0.6f),
|
|
|
+ newPrimaryColor
|
|
|
+ };
|
|
|
+ return new ColorStateList(states, colors);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Retrieves the view of an action button, allowing you to modify properties such as whether or not it's enabled.
|
|
|
+ */
|
|
|
+ public final View getActionButton(DialogAction which) {
|
|
|
+ if (view == null) return null;
|
|
|
+ if (isStacked) {
|
|
|
+ switch (which) {
|
|
|
+ default:
|
|
|
+ return view.findViewById(R.id.buttonStackedPositive);
|
|
|
+ case NEUTRAL:
|
|
|
+ return view.findViewById(R.id.buttonStackedNeutral);
|
|
|
+ case NEGATIVE:
|
|
|
+ return view.findViewById(R.id.buttonStackedNegative);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ switch (which) {
|
|
|
+ default:
|
|
|
+ return view.findViewById(R.id.buttonDefaultPositive);
|
|
|
+ case NEUTRAL:
|
|
|
+ return view.findViewById(R.id.buttonDefaultNeutral);
|
|
|
+ case NEGATIVE:
|
|
|
+ return view.findViewById(R.id.buttonDefaultNegative);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Updates an action button's title, causing invalidation to check if the action buttons should be stacked.
|
|
|
+ *
|
|
|
+ * @param which The action button to update.
|
|
|
+ * @param title The new title of the action button.
|
|
|
+ */
|
|
|
+ public final void setActionButton(DialogAction which, CharSequence title) {
|
|
|
+ switch (which) {
|
|
|
+ default:
|
|
|
+ this.positiveText = title;
|
|
|
+ break;
|
|
|
+ case NEUTRAL:
|
|
|
+ this.neutralText = title;
|
|
|
+ break;
|
|
|
+ case NEGATIVE:
|
|
|
+ this.negativeText = title;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ invalidateActions();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Updates an action button's title, causing invalidation to check if the action buttons should be stacked.
|
|
|
+ *
|
|
|
+ * @param which The action button to update.
|
|
|
+ * @param titleRes The string resource of the new title of the action button.
|
|
|
+ */
|
|
|
+ public final void setActionButton(DialogAction which, @StringRes int titleRes) {
|
|
|
+ setActionButton(which, mContext.getString(titleRes));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Retrieves the custom view that was inflated or set to the MaterialDialog during building.
|
|
|
+ */
|
|
|
+ public final View getCustomView() {
|
|
|
+ return customView;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static interface ListCallback {
|
|
|
+ void onSelection(MaterialDialog dialog, int which, String text);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static interface ListCallbackMulti {
|
|
|
+ void onSelection(MaterialDialog dialog, Integer[] which, String[] text);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static interface SimpleCallback {
|
|
|
+ void onPositive(MaterialDialog dialog);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static interface Callback extends SimpleCallback {
|
|
|
+ void onPositive(MaterialDialog dialog);
|
|
|
+
|
|
|
+ void onNegative(MaterialDialog dialog);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static interface FullCallback extends Callback {
|
|
|
+ void onNeutral(MaterialDialog dialog);
|
|
|
+ }
|
|
|
+}
|