MaterialDialogPreference.java 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package com.afollestad.materialdialogs.prefs;
  2. import android.annotation.TargetApi;
  3. import android.app.Dialog;
  4. import android.content.Context;
  5. import android.content.DialogInterface;
  6. import android.content.res.TypedArray;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.os.Parcel;
  10. import android.os.Parcelable;
  11. import android.preference.DialogPreference;
  12. import android.preference.PreferenceManager;
  13. import android.support.annotation.NonNull;
  14. import android.util.AttributeSet;
  15. import android.view.View;
  16. import com.afollestad.materialdialogs.MaterialDialog;
  17. import com.afollestad.materialdialogs.commons.R;
  18. import java.lang.reflect.Method;
  19. /**
  20. * @author Aidan Follestad (afollestad)
  21. */
  22. public class MaterialDialogPreference extends DialogPreference {
  23. private Context context;
  24. private MaterialDialog mDialog;
  25. @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  26. public MaterialDialogPreference(Context context) {
  27. super(context);
  28. init(context, null, 0, 0);
  29. }
  30. public MaterialDialogPreference(Context context, AttributeSet attrs) {
  31. super(context, attrs);
  32. init(context, attrs, 0, 0);
  33. }
  34. public MaterialDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
  35. super(context, attrs, defStyleAttr);
  36. init(context, attrs, defStyleAttr, 0);
  37. }
  38. @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  39. public MaterialDialogPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  40. super(context, attrs, defStyleAttr, defStyleRes);
  41. init(context, attrs, defStyleAttr, defStyleRes);
  42. }
  43. private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  44. this.context = context;
  45. final TypedArray a = context.obtainStyledAttributes(
  46. attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
  47. try {
  48. final int layoutResource = a.getResourceId(com.android.internal.R.styleable.Preference_layout, 0);
  49. if (layoutResource == 0)
  50. setLayoutResource(R.layout.md_preference_custom);
  51. } finally {
  52. a.recycle();
  53. }
  54. }
  55. @Override
  56. public Dialog getDialog() {
  57. return mDialog;
  58. }
  59. @Override
  60. protected void showDialog(Bundle state) {
  61. MaterialDialog.Builder builder = new MaterialDialog.Builder(context)
  62. .title(getDialogTitle())
  63. .content(getDialogMessage())
  64. .icon(getDialogIcon())
  65. .dismissListener(this)
  66. .callback(new MaterialDialog.ButtonCallback() {
  67. @Override
  68. public void onNeutral(MaterialDialog dialog) {
  69. onClick(dialog, DialogInterface.BUTTON_NEUTRAL);
  70. }
  71. @Override
  72. public void onNegative(MaterialDialog dialog) {
  73. onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
  74. }
  75. @Override
  76. public void onPositive(MaterialDialog dialog) {
  77. onClick(dialog, DialogInterface.BUTTON_POSITIVE);
  78. }
  79. })
  80. .positiveText(getPositiveButtonText())
  81. .negativeText(getNegativeButtonText())
  82. .autoDismiss(true); // immediately close the dialog after selection
  83. final View contentView = onCreateDialogView();
  84. if (contentView != null) {
  85. onBindDialogView(contentView);
  86. builder.customView(contentView, false);
  87. } else {
  88. builder.content(getDialogMessage());
  89. }
  90. try {
  91. PreferenceManager pm = getPreferenceManager();
  92. Method method = pm.getClass().getDeclaredMethod(
  93. "registerOnActivityDestroyListener",
  94. PreferenceManager.OnActivityDestroyListener.class);
  95. method.setAccessible(true);
  96. method.invoke(pm, this);
  97. } catch (Exception ignored) {
  98. }
  99. mDialog = builder.build();
  100. if (state != null)
  101. mDialog.onRestoreInstanceState(state);
  102. mDialog.show();
  103. }
  104. @Override
  105. public void onDismiss(DialogInterface dialog) {
  106. super.onDismiss(dialog);
  107. try {
  108. PreferenceManager pm = getPreferenceManager();
  109. Method method = pm.getClass().getDeclaredMethod(
  110. "unregisterOnActivityDestroyListener",
  111. PreferenceManager.OnActivityDestroyListener.class);
  112. method.setAccessible(true);
  113. method.invoke(pm, this);
  114. } catch (Exception ignored) {
  115. }
  116. }
  117. @Override
  118. public void onActivityDestroy() {
  119. super.onActivityDestroy();
  120. if (mDialog != null && mDialog.isShowing())
  121. mDialog.dismiss();
  122. }
  123. @Override
  124. protected Parcelable onSaveInstanceState() {
  125. final Parcelable superState = super.onSaveInstanceState();
  126. Dialog dialog = getDialog();
  127. if (dialog == null || !dialog.isShowing()) {
  128. return superState;
  129. }
  130. final SavedState myState = new SavedState(superState);
  131. myState.isDialogShowing = true;
  132. myState.dialogBundle = dialog.onSaveInstanceState();
  133. return myState;
  134. }
  135. @Override
  136. protected void onRestoreInstanceState(Parcelable state) {
  137. if (state == null || !state.getClass().equals(SavedState.class)) {
  138. // Didn't save state for us in onSaveInstanceState
  139. super.onRestoreInstanceState(state);
  140. return;
  141. }
  142. SavedState myState = (SavedState) state;
  143. super.onRestoreInstanceState(myState.getSuperState());
  144. if (myState.isDialogShowing) {
  145. showDialog(myState.dialogBundle);
  146. }
  147. }
  148. // From DialogPreference
  149. private static class SavedState extends BaseSavedState {
  150. boolean isDialogShowing;
  151. Bundle dialogBundle;
  152. public SavedState(Parcel source) {
  153. super(source);
  154. isDialogShowing = source.readInt() == 1;
  155. dialogBundle = source.readBundle();
  156. }
  157. @Override
  158. public void writeToParcel(@NonNull Parcel dest, int flags) {
  159. super.writeToParcel(dest, flags);
  160. dest.writeInt(isDialogShowing ? 1 : 0);
  161. dest.writeBundle(dialogBundle);
  162. }
  163. public SavedState(Parcelable superState) {
  164. super(superState);
  165. }
  166. public static final Creator<SavedState> CREATOR =
  167. new Creator<SavedState>() {
  168. public SavedState createFromParcel(Parcel in) {
  169. return new SavedState(in);
  170. }
  171. public SavedState[] newArray(int size) {
  172. return new SavedState[size];
  173. }
  174. };
  175. }
  176. }