• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.xtremelabs.robolectric.shadows;
2 
3 import android.app.Activity;
4 import android.app.Dialog;
5 import android.content.Context;
6 import android.content.DialogInterface;
7 import android.os.Bundle;
8 import android.view.LayoutInflater;
9 import android.view.View;
10 import android.view.ViewGroup;
11 import android.view.Window;
12 import com.xtremelabs.robolectric.Robolectric;
13 import com.xtremelabs.robolectric.internal.Implementation;
14 import com.xtremelabs.robolectric.internal.Implements;
15 import com.xtremelabs.robolectric.internal.RealObject;
16 import com.xtremelabs.robolectric.tester.android.view.TestWindow;
17 
18 import java.lang.reflect.Method;
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
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     private DialogInterface.OnDismissListener onDismissListener;
37     protected CharSequence title;
38     private DialogInterface.OnCancelListener onCancelListener;
39     private Window window;
40     private Activity ownerActivity;
41     private boolean isCancelable = true;
42     private boolean hasShownBefore;
43     private static final ArrayList<Dialog> shownDialogs = new ArrayList<Dialog>();
44     private boolean isCancelableOnTouchOutside;
45 
reset()46     public static void reset() {
47         setLatestDialog(null);
48         shownDialogs.clear();
49     }
50 
getLatestDialog()51     public static Dialog getLatestDialog() {
52         ShadowDialog dialog = Robolectric.getShadowApplication().getLatestDialog();
53         return dialog == null ? null : dialog.realDialog;
54     }
55 
setLatestDialog(ShadowDialog latestDialog)56     public static void setLatestDialog(ShadowDialog latestDialog) {
57         Robolectric.getShadowApplication().setLatestDialog(latestDialog);
58     }
59 
__constructor__(Context context)60     public void __constructor__(Context context) {
61         __constructor__(context, -1);
62     }
63 
__constructor__(Context context, int themeId)64     public void __constructor__(Context context, int themeId) {
65         this.context = context;
66         this.themeId = themeId;
67     }
68 
69     @Implementation
setContentView(int layoutResID)70     public void setContentView(int layoutResID) {
71         layoutId = layoutResID;
72     }
73 
74     @Implementation
setContentView(View view)75     public void setContentView(View view) {
76         inflatedView = view;
77     }
78 
79     @Implementation
setTitle(int stringResourceId)80     public void setTitle(int stringResourceId) {
81         this.title = context.getResources().getText(stringResourceId);
82     }
83 
84     @Implementation(i18nSafe = false)
setTitle(CharSequence title)85     public void setTitle(CharSequence title) {
86         this.title = title;
87     }
88 
89     @Implementation
setOwnerActivity(Activity activity)90     public void setOwnerActivity(Activity activity) {
91         this.ownerActivity = activity;
92     }
93 
94     @Implementation
getOwnerActivity()95     public Activity getOwnerActivity() {
96         return this.ownerActivity;
97     }
98 
99     @Implementation
getContext()100     public Context getContext() {
101         return context;
102     }
103 
104     @Implementation
onBackPressed()105     public void onBackPressed() {
106         cancel();
107     }
108 
109     @Implementation
show()110     public void show() {
111         setLatestDialog(this);
112         shownDialogs.add(realDialog);
113         isShowing = true;
114         try {
115             if (!hasShownBefore) {
116                 Method onCreateMethod = Dialog.class.getDeclaredMethod("onCreate", Bundle.class);
117                 onCreateMethod.setAccessible(true);
118                 onCreateMethod.invoke(realDialog, (Bundle) null);
119             }
120 
121             Method onStartMethod = Dialog.class.getDeclaredMethod("onStart");
122             onStartMethod.setAccessible(true);
123             onStartMethod.invoke(realDialog);
124         } catch (Exception e) {
125             throw new RuntimeException(e);
126         }
127         hasShownBefore = true;
128     }
129 
130     @Implementation
hide()131     public void hide() {
132         isShowing = false;
133     }
134 
135     @Implementation
isShowing()136     public boolean isShowing() {
137         return isShowing;
138     }
139 
140     @Implementation
dismiss()141     public void dismiss() {
142         isShowing = false;
143         hasBeenDismissed = true;
144 
145         if (onDismissListener != null) {
146             onDismissListener.onDismiss(realDialog);
147         }
148     }
149 
150     @Implementation
findViewById(int viewId)151     public View findViewById(int viewId) {
152         if (inflatedView != null) {
153             return inflatedView.findViewById(viewId);
154         }
155         if (layoutId > 0 && context != null) {
156             inflatedView = ShadowLayoutInflater.from(context).inflate(layoutId, null);
157             return inflatedView.findViewById(viewId);
158         }
159         return null;
160     }
161 
clickOn(int viewId)162     public void clickOn(int viewId) {
163         findViewById(viewId).performClick();
164     }
165 
166     @Implementation
setOnDismissListener(DialogInterface.OnDismissListener onDismissListener)167     public void setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) {
168         this.onDismissListener = onDismissListener;
169     }
170 
171     @Implementation
setCancelable(boolean flag)172     public void setCancelable(boolean flag) {
173         isCancelable = flag;
174     }
175 
176     @Implementation
setCanceledOnTouchOutside(boolean flag)177     public void setCanceledOnTouchOutside(boolean flag) {
178         isCancelableOnTouchOutside = flag;
179     }
180 
isCancelable()181     public boolean isCancelable() {
182         return isCancelable;
183     }
184 
isCancelableOnTouchOutside()185     public boolean isCancelableOnTouchOutside() {
186         return isCancelableOnTouchOutside;
187     }
188 
189     @Implementation
cancel()190     public void cancel() {
191         if (onCancelListener != null) {
192             onCancelListener.onCancel(realDialog);
193         }
194         realDialog.dismiss();
195     }
196 
197     @Implementation
setOnCancelListener(DialogInterface.OnCancelListener listener)198     public void setOnCancelListener(DialogInterface.OnCancelListener listener) {
199         this.onCancelListener = listener;
200     }
201 
getOnCancelListener()202     public DialogInterface.OnCancelListener getOnCancelListener() {
203         return onCancelListener;
204     }
205 
206     @Implementation
getWindow()207     public Window getWindow() {
208         if (window == null) {
209             window = new TestWindow(realDialog.getContext());
210         }
211         return window;
212     }
213 
214 
215     @Implementation
getLayoutInflater()216     public LayoutInflater getLayoutInflater() {
217         return LayoutInflater.from(realDialog.getContext());
218     }
219 
getLayoutId()220     public int getLayoutId() {
221         return layoutId;
222     }
223 
getThemeId()224     public int getThemeId() {
225         return themeId;
226     }
227 
hasBeenDismissed()228     public boolean hasBeenDismissed() {
229         return hasBeenDismissed;
230     }
231 
getTitle()232     public CharSequence getTitle() {
233         return title;
234     }
235 
clickOnText(int textId)236     public void clickOnText(int textId) {
237         if (inflatedView == null) {
238             inflatedView = ShadowLayoutInflater.from(context).inflate(layoutId, null);
239         }
240         String text = getContext().getResources().getString(textId);
241         if (!clickOnText(inflatedView, text)) {
242             throw new IllegalArgumentException("Text not found: " + text);
243         }
244     }
245 
clickOnText(View view, String text)246     private boolean clickOnText(View view, String text) {
247         if (text.equals(shadowOf(view).innerText())) {
248             view.performClick();
249             return true;
250         }
251         if (view instanceof ViewGroup) {
252             ViewGroup viewGroup = (ViewGroup) view;
253             for (int i = 0; i < viewGroup.getChildCount(); i++) {
254                 View child = viewGroup.getChildAt(i);
255                 if (clickOnText(child, text)) {
256                     return true;
257                 }
258             }
259         }
260         return false;
261     }
262 
getShownDialogs()263     public static List<Dialog> getShownDialogs() {
264         return shownDialogs;
265     }
266 }
267