Skip to content

Instantly share code, notes, and snippets.

@zhanghai
Created December 24, 2014 07:09
Show Gist options
  • Save zhanghai/c69dfac91c98434055bb to your computer and use it in GitHub Desktop.
Save zhanghai/c69dfac91c98434055bb to your computer and use it in GitHub Desktop.
Simple DialogFragment for showing dialogs that saves/restores its instance state.
/*
* Copyright (c) 2014 Zhang Hai
*
* 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 com.yourapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.KeyEvent;
public class SimpleDialogFragment extends DialogFragment {
private static final String ARGUMENT_REQUEST_CODE = "request_code";
private static final String ARGUMENT_THEME = "theme";
private static final String ARGUMENT_ICON_ID = "icon_id";
private static final String ARGUMENT_TITLE = "tle";
private static final String ARGUMENT_MESSAGE = "message";
private static final String ARGUMENT_POSITIVE_BUTTON_TEXT = "positive_button_text";
private static final String ARGUMENT_NEUTRAL_BUTTON_TEXT = "neutral_button_text";
private static final String ARGUMENT_NEGATIVE_BUTTON_TEXT = "negative_button_text";
private static final String ARGUMENT_CANCELABLE = "cancelable";
private SimpleDialogListener mListener;
private int mRequestCode;
private static SimpleDialogFragment makeClose(Fragment targetFragment, int requestCode,
int titleId, int messageId, Context context) {
return new Builder(context)
.setTargetFragment(targetFragment)
.setRequestCode(requestCode)
.setTitle(titleId)
.setMessage(messageId)
.setPositiveButtonText(R.string.close)
.build();
}
public static SimpleDialogFragment makeClose(Fragment fragment, int requestCode, int titleId,
int messageId) {
return makeClose(fragment, requestCode, titleId, messageId, fragment.getActivity());
}
public static SimpleDialogFragment makeClose(int titleId, int messageId, Fragment fragment) {
// NOTE: Prevent message from being sent to parent activity unexpectedly.
return makeClose(fragment, 0, titleId, messageId);
}
public static SimpleDialogFragment makeClose(Activity activity, int requestCode, int titleId,
int messageId) {
return makeClose(null, requestCode, titleId, messageId, activity);
}
public static SimpleDialogFragment makeClose(int titleId, int messageId, Activity activity) {
return makeClose(activity, 0, titleId, messageId);
}
private static SimpleDialogFragment makeOkCancel(Fragment targetFragment, int requestCode,
int titleId, int messageId, Context context) {
return new Builder(context)
.setTargetFragment(targetFragment)
.setRequestCode(requestCode)
.setTitle(titleId)
.setMessage(messageId)
.setPositiveButtonText(android.R.string.ok)
.setNegativeButtonText(android.R.string.cancel)
.build();
}
public static SimpleDialogFragment makeOkCancel(Fragment fragment, int requestCode, int titleId,
int messageId) {
return makeOkCancel(fragment, requestCode, titleId, messageId, fragment.getActivity());
}
public static SimpleDialogFragment makeOkCancel(int titleId, int messageId, Fragment fragment) {
return makeOkCancel(fragment, 0, titleId, messageId);
}
public static SimpleDialogFragment makeOkCancel(Activity activity, int requestCode, int titleId,
int messageId) {
return makeOkCancel(null, requestCode, titleId, messageId, activity);
}
public static SimpleDialogFragment makeOkCancel(int titleId, int messageId, Activity activity) {
return makeOkCancel(activity, 0, titleId, messageId);
}
private static SimpleDialogFragment makeYesNo(Fragment targetFragment, int requestCode,
int titleId, int messageId, Context context) {
return new Builder(context)
.setTargetFragment(targetFragment)
.setRequestCode(requestCode)
.setTitle(titleId)
.setMessage(messageId)
.setPositiveButtonText(android.R.string.yes)
.setNegativeButtonText(android.R.string.no)
.build();
}
public static SimpleDialogFragment makeYesNo(Fragment fragment, int requestCode,
int titleId, int messageId) {
return makeYesNo(fragment, requestCode, titleId, messageId, fragment.getActivity());
}
public static SimpleDialogFragment makeYesNo(int titleId, int messageId, Fragment fragment) {
return makeYesNo(fragment, 0, titleId, messageId);
}
public static SimpleDialogFragment makeYesNo(Activity activity, int requestCode, int titleId,
int messageId) {
return makeYesNo(null, requestCode, titleId, messageId, activity);
}
public static SimpleDialogFragment makeYesNo(int titleId, int messageId, Activity activity) {
return makeYesNo(activity, 0, titleId, messageId);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Fragment targetFragment = getTargetFragment();
if (targetFragment == null) {
Activity activity = getActivity();
if (activity instanceof SimpleDialogListenerProvider) {
mListener = ((SimpleDialogListenerProvider)activity).getListener();
}
mRequestCode = getArguments().getInt(ARGUMENT_REQUEST_CODE);
} else {
if (targetFragment instanceof SimpleDialogListenerProvider) {
mListener = ((SimpleDialogListenerProvider)targetFragment).getListener();
}
mRequestCode = getTargetRequestCode();
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alertDialogBuilder;
Bundle arguments = getArguments();
int theme = arguments.getInt(ARGUMENT_THEME);
if (theme == 0) {
alertDialogBuilder = new AlertDialog.Builder(getActivity());
} else {
alertDialogBuilder = new AlertDialog.Builder(getActivity(), theme);
}
alertDialogBuilder
.setIcon(arguments.getInt(ARGUMENT_ICON_ID))
.setTitle(arguments.getCharSequence(ARGUMENT_TITLE))
.setMessage(arguments.getCharSequence(ARGUMENT_MESSAGE))
.setPositiveButton(arguments.getCharSequence(ARGUMENT_POSITIVE_BUTTON_TEXT),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mListener != null) {
mListener.onPositiveButtonClicked(mRequestCode);
}
}
})
.setNeutralButton(arguments.getCharSequence(ARGUMENT_NEUTRAL_BUTTON_TEXT),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mListener != null) {
mListener.onNeutralButtonClicked(mRequestCode);
}
}
})
.setNegativeButton(arguments.getCharSequence(ARGUMENT_NEGATIVE_BUTTON_TEXT),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mListener != null) {
mListener.onNegativeButtonClicked(mRequestCode);
}
}
})
.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent keyEvent) {
if (mListener != null) {
return mListener.onKey(mRequestCode, keyCode, keyEvent);
} else {
return false;
}
}
})
.setCancelable(arguments.getBoolean(ARGUMENT_CANCELABLE));
return alertDialogBuilder.create();
}
/*
* NOTE:
* From DialogFragment.onCreateDialog documentation:
* DialogFragment own the Dialog.setOnCancelListener and Dialog.setOnDismissListener callbacks.
* You must not set them yourself.
* To find out about these events, override onCancel(DialogInterface) and
* onDismiss(DialogInterface).
*/
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
if (mListener != null) {
mListener.onCancel(mRequestCode);
}
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (mListener != null) {
mListener.onDismiss(mRequestCode);
}
}
public AlertDialog getAlertDialog() {
return (AlertDialog) getDialog();
}
public void show(FragmentManager manager) {
show(manager, null);
}
public void showIfNotAdded(FragmentManager manager) {
if (!isAdded()) {
show(manager);
}
}
public static class SimpleDialogListener {
public void onPositiveButtonClicked(int requestCode) {}
public void onNeutralButtonClicked(int requestCode) {}
public void onNegativeButtonClicked(int requestCode) {}
public void onCancel(int requestCode) {}
public void onDismiss(int requestCode) {}
public boolean onKey(int requestCode, int keyCode, KeyEvent keyEvent) {
return false;
}
}
public static interface SimpleDialogListenerProvider {
public SimpleDialogListener getListener();
}
public static class Builder {
private Context mContext;
private Fragment mTargetFragment;
private int mRequestCode;
private int mTheme;
private int mIconId;
private CharSequence mTitle;
private CharSequence mMessage;
private CharSequence mNegativeButtonText;
private CharSequence mNeutralButtonText;
private CharSequence mPositiveButtonText;
private boolean mCancelable;
public Builder(Context context) {
mContext = context;
}
public Builder setTargetFragment(Fragment fragment) {
mTargetFragment = fragment;
return this;
}
public Builder setRequestCode(int requestCode) {
mRequestCode = requestCode;
return this;
}
public Builder setTheme(int theme) {
mTheme = theme;
return this;
}
public Builder setIcon(int iconId) {
mIconId = iconId;
return this;
}
public Builder setIconAttribute(int attrId) {
TypedValue typedValue = new TypedValue();
mContext.getTheme().resolveAttribute(attrId, typedValue, true);
return setIcon(typedValue.resourceId);
}
public Builder setTitle(CharSequence title) {
mTitle = title;
return this;
}
public Builder setTitle(int titleId) {
return setTitle(mContext.getText(titleId));
}
public Builder setMessage(CharSequence message) {
mMessage = message;
return this;
}
public Builder setMessage(int messageId) {
return setMessage(mContext.getText(messageId));
}
public Builder setPositiveButtonText(CharSequence text) {
mPositiveButtonText = text;
return this;
}
public Builder setPositiveButtonText(int textId) {
return setPositiveButtonText(mContext.getText(textId));
}
public Builder setNeutralButtonText(CharSequence text) {
mNeutralButtonText = text;
return this;
}
public Builder setNeutralButtonText(int textId) {
return setNeutralButtonText(mContext.getText(textId));
}
public Builder setNegativeButtonText(CharSequence text) {
mNegativeButtonText = text;
return this;
}
public Builder setNegativeButtonText(int textId) {
return setNegativeButtonText(mContext.getText(textId));
}
public Builder setCancelable(boolean cancelable) {
mCancelable = cancelable;
return this;
}
public SimpleDialogFragment build() {
Bundle arguments = new Bundle();
if (mTargetFragment == null) {
arguments.putInt(ARGUMENT_REQUEST_CODE, mRequestCode);
}
arguments.putInt(ARGUMENT_THEME, mTheme);
arguments.putInt(ARGUMENT_ICON_ID, mIconId);
arguments.putCharSequence(ARGUMENT_TITLE, mTitle);
arguments.putCharSequence(ARGUMENT_MESSAGE, mMessage);
arguments.putCharSequence(ARGUMENT_POSITIVE_BUTTON_TEXT, mPositiveButtonText);
arguments.putCharSequence(ARGUMENT_NEUTRAL_BUTTON_TEXT, mNeutralButtonText);
arguments.putCharSequence(ARGUMENT_NEGATIVE_BUTTON_TEXT, mNegativeButtonText);
arguments.putBoolean(ARGUMENT_CANCELABLE, mCancelable);
SimpleDialogFragment simpleDialogFragment = new SimpleDialogFragment();
if (mTargetFragment != null) {
simpleDialogFragment.setTargetFragment(mTargetFragment, mRequestCode);
}
simpleDialogFragment.setArguments(arguments);
return simpleDialogFragment;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment