1 package org.robolectric.shadows; 2 3 import static org.robolectric.shadow.api.Shadow.directlyOn; 4 5 import android.app.Activity; 6 import android.app.Dialog; 7 import android.content.Context; 8 import android.content.DialogInterface; 9 import android.os.Bundle; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.view.Window; 14 import java.util.ArrayList; 15 import java.util.List; 16 import org.robolectric.annotation.Implementation; 17 import org.robolectric.annotation.Implements; 18 import org.robolectric.annotation.RealObject; 19 import org.robolectric.annotation.Resetter; 20 import org.robolectric.shadow.api.Shadow; 21 import org.robolectric.util.ReflectionHelpers; 22 import org.robolectric.util.ReflectionHelpers.ClassParameter; 23 24 @SuppressWarnings({"UnusedDeclaration"}) 25 @Implements(Dialog.class) 26 public class ShadowDialog { 27 28 @RealObject private Dialog realDialog; 29 30 private boolean isShowing; 31 Context context; 32 private int layoutId; 33 private int themeId; 34 private View inflatedView; 35 private boolean hasBeenDismissed; 36 protected CharSequence title; 37 private DialogInterface.OnCancelListener onCancelListener; 38 private Window window; 39 private Activity ownerActivity; 40 private boolean hasShownBefore; 41 private static final ArrayList<Dialog> shownDialogs = new ArrayList<>(); 42 private boolean isCancelableOnTouchOutside; 43 44 @Resetter reset()45 public static void reset() { 46 setLatestDialog(null); 47 shownDialogs.clear(); 48 } 49 getLatestDialog()50 public static Dialog getLatestDialog() { 51 ShadowDialog dialog = ShadowApplication.getInstance().getLatestDialog(); 52 return dialog == null ? null : dialog.realDialog; 53 } 54 setLatestDialog(ShadowDialog latestDialog)55 public static void setLatestDialog(ShadowDialog latestDialog) { 56 ShadowApplication shadowApplication = ShadowApplication.getInstance(); 57 if (shadowApplication != null) shadowApplication.setLatestDialog(latestDialog); 58 } 59 60 @Implementation show()61 protected void show() { 62 setLatestDialog(this); 63 shownDialogs.add(realDialog); 64 directlyOn(realDialog, Dialog.class).show(); 65 } 66 67 @Implementation dismiss()68 protected void dismiss() { 69 directlyOn(realDialog, Dialog.class).dismiss(); 70 hasBeenDismissed = true; 71 } 72 clickOn(int viewId)73 public void clickOn(int viewId) { 74 realDialog.findViewById(viewId).performClick(); 75 } 76 77 @Implementation setCanceledOnTouchOutside(boolean flag)78 protected void setCanceledOnTouchOutside(boolean flag) { 79 isCancelableOnTouchOutside = flag; 80 directlyOn(realDialog, Dialog.class).setCanceledOnTouchOutside(flag); 81 } 82 isCancelable()83 public boolean isCancelable() { 84 return ReflectionHelpers.getField(realDialog, "mCancelable"); 85 } 86 isCancelableOnTouchOutside()87 public boolean isCancelableOnTouchOutside() { 88 return isCancelableOnTouchOutside; 89 } 90 getOnCancelListener()91 public DialogInterface.OnCancelListener getOnCancelListener() { 92 return onCancelListener; 93 } 94 95 @Implementation setOnCancelListener(DialogInterface.OnCancelListener listener)96 protected void setOnCancelListener(DialogInterface.OnCancelListener listener) { 97 this.onCancelListener = listener; 98 directlyOn(realDialog, Dialog.class).setOnCancelListener(listener); 99 } 100 hasBeenDismissed()101 public boolean hasBeenDismissed() { 102 return hasBeenDismissed; 103 } 104 getTitle()105 public CharSequence getTitle() { 106 ShadowWindow shadowWindow = Shadow.extract(realDialog.getWindow()); 107 return shadowWindow.getTitle(); 108 } 109 clickOnText(int textId)110 public void clickOnText(int textId) { 111 if (inflatedView == null) { 112 inflatedView = LayoutInflater.from(context).inflate(layoutId, null); 113 } 114 String text = realDialog.getContext().getResources().getString(textId); 115 if (!clickOnText(inflatedView, text)) { 116 throw new IllegalArgumentException("Text not found: " + text); 117 } 118 } 119 clickOnText(String text)120 public void clickOnText(String text) { 121 if (!clickOnText(inflatedView, text)) { 122 throw new IllegalArgumentException("Text not found: " + text); 123 } 124 } 125 clickOnText(View view, String text)126 private boolean clickOnText(View view, String text) { 127 ShadowView shadowView = Shadow.extract(view); 128 if (text.equals(shadowView.innerText())) { 129 view.performClick(); 130 return true; 131 } 132 if (view instanceof ViewGroup) { 133 ViewGroup viewGroup = (ViewGroup) view; 134 for (int i = 0; i < viewGroup.getChildCount(); i++) { 135 View child = viewGroup.getChildAt(i); 136 if (clickOnText(child, text)) { 137 return true; 138 } 139 } 140 } 141 return false; 142 } 143 getShownDialogs()144 public static List<Dialog> getShownDialogs() { 145 return shownDialogs; 146 } 147 callOnCreate(Bundle bundle)148 public void callOnCreate(Bundle bundle) { 149 ReflectionHelpers.callInstanceMethod(realDialog, "onCreate", ClassParameter.from(Bundle.class, bundle)); 150 } 151 } 152