1 /* 2 * Copyright 2016, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.managedprovisioning.common; 18 19 import android.app.Activity; 20 import android.app.AlertDialog; 21 import android.app.Dialog; 22 import android.app.DialogFragment; 23 import android.content.DialogInterface; 24 import android.os.Bundle; 25 26 /** 27 * Utility class wrapping a {@link AlertDialog} in a {@link DialogFragment} 28 * <p> In order to properly handle Dialog lifecycle we follow the practice of wrapping of them 29 * in a Dialog Fragment. 30 * <p> If buttons are to be used (enabled by setting a button message), the creator {@link Activity} 31 * must implement {@link SimpleDialogListener}. 32 */ 33 public class SimpleDialog extends DialogFragment { 34 private static final String TITLE = "title"; 35 private static final String MESSAGE = "message"; 36 private static final String LOCALIZED_MESSAGE = "localized_message"; 37 private static final String NEGATIVE_BUTTON_MESSAGE = "negativeButtonMessage"; 38 private static final String POSITIVE_BUTTON_MESSAGE = "positiveButtonMessage"; 39 40 /** 41 * Use the {@link Builder} instead. Keeping the constructor public only because 42 * a {@link DialogFragment} must have an empty constructor that is public. 43 */ SimpleDialog()44 public SimpleDialog() { 45 } 46 47 @Override onCreateDialog(Bundle savedInstanceState)48 public AlertDialog onCreateDialog(Bundle savedInstanceState) { 49 final SimpleDialogListener dialogListener = (SimpleDialogListener) getActivity(); 50 51 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 52 53 Bundle args = getArguments(); 54 if (args.containsKey(TITLE)) { 55 builder.setTitle(args.getInt(TITLE)); 56 } 57 58 if (args.containsKey(MESSAGE)) { 59 builder.setMessage(args.getInt(MESSAGE)); 60 } 61 62 if (args.containsKey(LOCALIZED_MESSAGE)) { 63 builder.setMessage(args.getString(LOCALIZED_MESSAGE)); 64 } 65 66 if (args.containsKey(NEGATIVE_BUTTON_MESSAGE)) { 67 builder.setNegativeButton(args.getInt(NEGATIVE_BUTTON_MESSAGE), 68 new DialogInterface.OnClickListener() { 69 @Override 70 public void onClick(DialogInterface dialog, int which) { 71 dialogListener.onNegativeButtonClick(SimpleDialog.this); 72 } 73 }); 74 } 75 76 if (args.containsKey(POSITIVE_BUTTON_MESSAGE)) { 77 builder.setPositiveButton(args.getInt(POSITIVE_BUTTON_MESSAGE), 78 new DialogInterface.OnClickListener() { 79 @Override 80 public void onClick(DialogInterface dialog, int which) { 81 dialogListener.onPositiveButtonClick(SimpleDialog.this); 82 } 83 }); 84 } 85 86 return builder.create(); 87 } 88 89 /** 90 * Throws an exception informing of a lack of a handler for a dialog button click 91 * <p> Useful when implementing {@link SimpleDialogListener} 92 */ throwButtonClickHandlerNotImplemented(DialogFragment dialog)93 public static void throwButtonClickHandlerNotImplemented(DialogFragment dialog) { 94 throw new IllegalArgumentException("Button click handler not implemented for dialog: " 95 + dialog.getTag()); 96 } 97 98 public static class Builder implements DialogBuilder { 99 private Integer mTitle; 100 private Integer mMessage; 101 private String mLocalizedMessage; 102 private Integer mNegativeButtonMessage; 103 private Integer mPositiveButtonMessage; 104 private Boolean mCancelable; 105 106 /** 107 * Sets the title 108 * @param title Title resource id. 109 */ setTitle(Integer title)110 public Builder setTitle(Integer title) { 111 mTitle = title; 112 return this; 113 } 114 115 /** 116 * Sets the message 117 * @param message Message resource id. 118 */ setMessage(int message)119 public Builder setMessage(int message) { 120 mMessage = message; 121 return this; 122 } 123 124 /** 125 * Sets the message 126 * @param localizedMessage Message resource id. 127 */ setMessage(String localizedMessage)128 public Builder setMessage(String localizedMessage) { 129 mLocalizedMessage = localizedMessage; 130 return this; 131 } 132 133 /** 134 * Sets a message for the button. 135 * <p> Makes the button appear (without setting a button message, a button is not displayed) 136 * <p> Callback must be handled by a creator {@link Activity}, 137 * which must implement {@link SimpleDialogListener}. 138 * @param negativeButtonMessage Message resource id. 139 */ setNegativeButtonMessage(int negativeButtonMessage)140 public Builder setNegativeButtonMessage(int negativeButtonMessage) { 141 mNegativeButtonMessage = negativeButtonMessage; 142 return this; 143 } 144 145 /** 146 * Sets a message for the button. 147 * <p> Makes the button appear (without setting a button message, a button is not displayed) 148 * <p> Callback must be handled by a creator {@link Activity}, 149 * which must implement {@link SimpleDialogListener}. 150 * @param positiveButtonMessage Message resource id. 151 */ setPositiveButtonMessage(int positiveButtonMessage)152 public Builder setPositiveButtonMessage(int positiveButtonMessage) { 153 mPositiveButtonMessage = positiveButtonMessage; 154 return this; 155 } 156 157 /** 158 * Sets whether the dialog is cancelable or not. Default is true. 159 */ setCancelable(boolean cancelable)160 public Builder setCancelable(boolean cancelable) { 161 mCancelable = cancelable; 162 return this; 163 } 164 165 /** 166 * Creates an {@link SimpleDialog} with the arguments supplied to this builder. 167 */ 168 @Override build()169 public SimpleDialog build() { 170 SimpleDialog instance = new SimpleDialog(); 171 Bundle args = new Bundle(); 172 173 if (mTitle != null) { 174 args.putInt(TITLE, mTitle); 175 } 176 177 if (mMessage != null) { 178 args.putInt(MESSAGE, mMessage); 179 } 180 181 if (mLocalizedMessage != null) { 182 args.putString(LOCALIZED_MESSAGE, mLocalizedMessage); 183 } 184 185 if (mNegativeButtonMessage != null) { 186 args.putInt(NEGATIVE_BUTTON_MESSAGE, mNegativeButtonMessage); 187 } 188 189 if (mPositiveButtonMessage != null) { 190 args.putInt(POSITIVE_BUTTON_MESSAGE, mPositiveButtonMessage); 191 } 192 193 if (mCancelable != null) { 194 instance.setCancelable(mCancelable); 195 } 196 197 instance.setArguments(args); 198 return instance; 199 } 200 } 201 202 /** 203 * Interface for handling callbacks from {@link SimpleDialog} buttons. 204 * 205 * <p>If multiple dialogs are used in a context of a single {@link Activity}, 206 * a consumer of the interface can differentiate between dialogs using 207 * e.g. a {@link DialogFragment#getTag()}, or {@link DialogFragment#getArguments()}. 208 */ 209 public interface SimpleDialogListener { 210 /** 211 * Called when a user clicks on the positive dialog button. 212 * <p> To be implemented by a host {@link Activity} object. 213 * @param dialog {@link DialogFragment} where the click happened. 214 */ onPositiveButtonClick(DialogFragment dialog)215 void onPositiveButtonClick(DialogFragment dialog); 216 217 /** 218 * Called when a user clicks on the negative dialog button. 219 * <p> To be implemented by a host {@link Activity} object. 220 * @param dialog {@link DialogFragment} where the click happened. 221 */ onNegativeButtonClick(DialogFragment dialog)222 void onNegativeButtonClick(DialogFragment dialog); 223 } 224 }