ShadowAlertDialog.java revision 753d062a9106040be10c39595219774ae656b8f9
133873d2b41a5cd2597b20a4e88eb8942944c0f23Tyler Schultzpackage com.xtremelabs.robolectric.shadows;
250e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richard
350e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richardimport android.app.AlertDialog;
450e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richardimport android.content.Context;
550e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richardimport android.content.DialogInterface;
650e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richardimport android.view.View;
7f5856a910e7581637c23b0e8568ef299be1bcd04Christian Williams & Tyler Schultzimport android.widget.Button;
8854ca0a46da43847ab5b2ed9ce4ad8f580ae5a17Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.Robolectric;
922c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implementation;
1022c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implements;
1122c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.RealObject;
1250e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richard
1372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwinimport java.lang.reflect.Constructor;
1472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
159c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwinimport static com.xtremelabs.robolectric.Robolectric.getShadowApplication;
1672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwinimport static com.xtremelabs.robolectric.Robolectric.shadowOf;
1772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
18c1939651f1f399da668bdd59b900ad897f2b3a27pivotal@SuppressWarnings({"UnusedDeclaration"})
1950e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richard@Implements(AlertDialog.class)
20afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williamspublic class ShadowAlertDialog extends ShadowDialog {
2172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private CharSequence[] items;
2272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private String title;
2372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private String message;
2472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private DialogInterface.OnClickListener clickListener;
2572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private AlertDialog realDialog;
2672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private boolean isMultiItem;
2772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private boolean isSingleItem;
2872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private DialogInterface.OnMultiChoiceClickListener multiChoiceClickListener;
2972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private boolean[] checkedItems;
3072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private int checkedItemIndex;
3172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private Button positiveButton;
3272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private Button negativeButton;
3372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    private Button neutralButton;
3472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
3572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
3672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Non-Android accessor.
3772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     *
3872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * @return the most recently created {@code AlertDialog}, or null if none has been created during this test run
3972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
4072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public static ShadowAlertDialog getLatestAlertDialog() {
419c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin        return getShadowApplication().getLatestAlertDialog();
4272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
4372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
4472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
4572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Resets the tracking of the most recently created {@code AlertDialog}
4672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
4772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public static void reset() {
489c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin        getShadowApplication().setLatestAlertDialog(null);
4972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
5072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
5172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
5272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Simulates a click on the {@code Dialog} item indicated by {@code index}. Handles both multi- and single-choice dialogs, tracks which items are currently
5372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * checked and calls listeners appropriately.
5472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     *
55c1939651f1f399da668bdd59b900ad897f2b3a27pivotal     * @param index the index of the item to click on
5672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
5772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public void clickOnItem(int index) {
5872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        if (isMultiItem) {
5972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            checkedItems[index] = !checkedItems[index];
6072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            multiChoiceClickListener.onClick(realDialog, index, checkedItems[index]);
6172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        } else {
6272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            if (isSingleItem) {
6372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                checkedItemIndex = index;
6472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            }
6572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            clickListener.onClick(realDialog, index);
6672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
6772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
6872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
6972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    @Implementation
7072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public Button getButton(int whichButton) {
7172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        switch (whichButton) {
72c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            case AlertDialog.BUTTON_POSITIVE:
73c1939651f1f399da668bdd59b900ad897f2b3a27pivotal                return positiveButton;
74c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            case AlertDialog.BUTTON_NEGATIVE:
75c1939651f1f399da668bdd59b900ad897f2b3a27pivotal                return negativeButton;
76c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            case AlertDialog.BUTTON_NEUTRAL:
77c1939651f1f399da668bdd59b900ad897f2b3a27pivotal                return neutralButton;
7872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
7972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        throw new RuntimeException("Only positive, negative, or neutral button choices are recognized");
8072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
8172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
8272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
8372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Non-Android accessor.
8472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     *
8572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * @return the items that are available to be clicked on
8672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
8772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public CharSequence[] getItems() {
8872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        return items;
8972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
90c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
9172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
9272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Non-Android accessor.
9372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     *
9472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * @return the title of the dialog
9572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
9672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public String getTitle() {
9772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        return title;
9872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
9972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
10072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
10172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Non-Android accessor.
10272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     *
10372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * @return the message displayed in the dialog
10472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
10572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public String getMessage() {
10672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        return message;
10772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
10872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
10928dfcd9a7137bc117ca50634314848c0b1d4403cronald.mai    @Implementation
11028dfcd9a7137bc117ca50634314848c0b1d4403cronald.mai    public void setMessage(CharSequence message) {
11128dfcd9a7137bc117ca50634314848c0b1d4403cronald.mai        this.message = (message == null ? null : message.toString());
11228dfcd9a7137bc117ca50634314848c0b1d4403cronald.mai    }
11328dfcd9a7137bc117ca50634314848c0b1d4403cronald.mai
11472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
11572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Non-Android accessor.
11672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     *
11772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * @return an array indicating which items are and are not clicked on a multi-choice dialog
11872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
11972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public boolean[] getCheckedItems() {
12072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        return checkedItems;
12172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
12272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
123753d062a9106040be10c39595219774ae656b8f9Mike Grafton    /**
124753d062a9106040be10c39595219774ae656b8f9Mike Grafton     * Non-Android accessor.
125753d062a9106040be10c39595219774ae656b8f9Mike Grafton     *
126753d062a9106040be10c39595219774ae656b8f9Mike Grafton     * @return return the index of the checked item clicked on a single-choice dialog
127753d062a9106040be10c39595219774ae656b8f9Mike Grafton     */
128753d062a9106040be10c39595219774ae656b8f9Mike Grafton    public int getCheckedItemIndex() {
129753d062a9106040be10c39595219774ae656b8f9Mike Grafton        return checkedItemIndex;
130753d062a9106040be10c39595219774ae656b8f9Mike Grafton    }
131753d062a9106040be10c39595219774ae656b8f9Mike Grafton
1329c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin    @Implementation
1339c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin    public void show() {
1349c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin        super.show();
1359c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin        getShadowApplication().setLatestAlertDialog(this);
1369c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin    }
1379c6f1b1bf3d0bb2c6bb2abbf7fe8f21a137891f3Glenn Jahnke & Phil Goodwin
13872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    /**
13972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     * Shadows the {@code android.app.AlertDialog.Builder} class.
14072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin     */
14172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    @Implements(AlertDialog.Builder.class)
14272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    public static class ShadowBuilder {
14372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @RealObject
14472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private AlertDialog.Builder realBuilder;
14572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
14672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private CharSequence[] items;
14772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private DialogInterface.OnClickListener clickListener;
148c1939651f1f399da668bdd59b900ad897f2b3a27pivotal        private DialogInterface.OnCancelListener cancelListener;
14972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private String title;
15072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private String message;
15172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private Context context;
15272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private boolean isMultiItem;
15372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private DialogInterface.OnMultiChoiceClickListener multiChoiceClickListener;
15472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private boolean[] checkedItems;
15572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private CharSequence positiveText;
15672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private DialogInterface.OnClickListener positiveListener;
15772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private CharSequence negativeText;
15872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private DialogInterface.OnClickListener negativeListener;
15972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private CharSequence neutralText;
16072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private DialogInterface.OnClickListener neutralListener;
16172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private boolean isCancelable;
16272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private boolean isSingleItem;
16372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private int checkedItem;
16472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
16572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        /**
16672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         * just stashes the context for later use
16772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         *
168c1939651f1f399da668bdd59b900ad897f2b3a27pivotal         * @param context the context
16972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         */
17072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public void __constructor__(Context context) {
17172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.context = context;
17272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
17372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
17472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        /**
17572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         * Set a list of items to be displayed in the dialog as the content, you will be notified of the selected item via the supplied listener. This should be
17672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         * an array type i.e. R.array.foo
17772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         *
17872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         * @return This Builder object to allow for chaining of calls to set methods
17972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin         */
18072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
18172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setItems(int itemsId, final DialogInterface.OnClickListener listener) {
18272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.isMultiItem = false;
18372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
18472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.items = context.getResources().getTextArray(itemsId);
18572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.clickListener = listener;
18672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
18772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
18872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
18972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
19072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setItems(CharSequence[] items, final DialogInterface.OnClickListener listener) {
19172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.isMultiItem = false;
19272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
19372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.items = items;
19472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.clickListener = listener;
19572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
19672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
19772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
19872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
19972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setSingleChoiceItems(CharSequence[] items, int checkedItem, final DialogInterface.OnClickListener listener) {
20072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.isSingleItem = true;
20172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.checkedItem = checkedItem;
20272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.items = items;
20372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.clickListener = listener;
20472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
20572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
20672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
20772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
20872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, final DialogInterface.OnMultiChoiceClickListener listener) {
20972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.isMultiItem = true;
21072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
21172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.items = items;
21272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.multiChoiceClickListener = listener;
21372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
21472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            if (checkedItems == null) {
21572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                checkedItems = new boolean[items.length];
21672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            } else if (checkedItems.length != items.length) {
21772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                throw new IllegalArgumentException("checkedItems must be the same length as items, or pass null to specify no checked items");
21872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            }
21972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.checkedItems = checkedItems;
22072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
22172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
22272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
22372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
22472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
22572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setTitle(CharSequence title) {
22672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.title = title.toString();
22772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
22872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
22972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
23072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
23172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setTitle(int titleId) {
23238ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore            return setTitle(context.getResources().getString(titleId));
23372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
234c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
23572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
23672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setMessage(CharSequence message) {
23772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.message = message.toString();
23872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
23972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
24072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
24172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
24238ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore        public AlertDialog.Builder setMessage(int messageId) {
243b38fc2077a6ef0880426abc6bba8b10fb4a27933Yuan Mai            setMessage(context.getResources().getString(messageId));
244b38fc2077a6ef0880426abc6bba8b10fb4a27933Yuan Mai            return realBuilder;
24538ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore        }
24638ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore
24738ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore        @Implementation
24833284708d30b1b9aa82b44afed58ca54d789bb29David Farber & Ryan Richard        public AlertDialog.Builder setIcon(int iconId) {
24933284708d30b1b9aa82b44afed58ca54d789bb29David Farber & Ryan Richard            return realBuilder;
25033284708d30b1b9aa82b44afed58ca54d789bb29David Farber & Ryan Richard        }
251c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
25233284708d30b1b9aa82b44afed58ca54d789bb29David Farber & Ryan Richard        @Implementation
25372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setPositiveButton(CharSequence text, final DialogInterface.OnClickListener listener) {
25472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.positiveText = text;
25572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.positiveListener = listener;
25672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
25772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
25872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
25972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
2602d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        public AlertDialog.Builder setPositiveButton(int positiveTextId, final DialogInterface.OnClickListener listener) {
261c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            return setPositiveButton(context.getResources().getText(positiveTextId), listener);
26238ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore        }
26338ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore
26438ee4a4da68e1faf7338f5f7124b057cbd8a6813Joe Moore        @Implementation
26572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setNegativeButton(CharSequence text, final DialogInterface.OnClickListener listener) {
26672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.negativeText = text;
26772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.negativeListener = listener;
26872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
26972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
27072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
27172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
2722d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        public AlertDialog.Builder setNegativeButton(int negativeTextId, final DialogInterface.OnClickListener listener) {
273c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            return setNegativeButton(context.getResources().getString(negativeTextId), listener);
2742d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        }
275c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
2762d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        @Implementation
27772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setNeutralButton(CharSequence text, final DialogInterface.OnClickListener listener) {
27872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.neutralText = text;
27972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.neutralListener = listener;
28072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
28172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
28272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
28372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
2842d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        public AlertDialog.Builder setNeutralButton(int neutralTextId, final DialogInterface.OnClickListener listener) {
285c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            return setNegativeButton(context.getResources().getText(neutralTextId), listener);
2862d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        }
287c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
288c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
2892d62e13a03392e4596cc30edd64d46f73cbc04d7Graeme Duncan        @Implementation
29072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog.Builder setCancelable(boolean cancelable) {
29172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            this.isCancelable = cancelable;
29272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realBuilder;
29372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
294c1939651f1f399da668bdd59b900ad897f2b3a27pivotal
295705748ea9a08e8e91369d1dac47d64d2ee4b8e02Graeme Duncan        @Implementation
296705748ea9a08e8e91369d1dac47d64d2ee4b8e02Graeme Duncan        public AlertDialog.Builder setOnCancelListener(DialogInterface.OnCancelListener listener) {
297c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            this.cancelListener = listener;
298c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            return realBuilder;
299705748ea9a08e8e91369d1dac47d64d2ee4b8e02Graeme Duncan        }
30072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
30172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
30272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog create() {
30372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            AlertDialog realDialog;
30472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            try {
30572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                Constructor<AlertDialog> c = AlertDialog.class.getDeclaredConstructor(Context.class);
30672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                c.setAccessible(true);
30772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                realDialog = c.newInstance((Context) null);
30872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            } catch (Exception e) {
30972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                throw new RuntimeException(e);
31072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            }
31172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
31272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            ShadowAlertDialog latestAlertDialog = shadowOf(realDialog);
31372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.context = context;
31472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.realDialog = realDialog;
31572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.items = items;
31672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.title = title;
31772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.message = message;
31872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.clickListener = clickListener;
319705748ea9a08e8e91369d1dac47d64d2ee4b8e02Graeme Duncan            latestAlertDialog.setOnCancelListener(cancelListener);
32072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.isMultiItem = isMultiItem;
32172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.isSingleItem = isSingleItem;
32272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.checkedItemIndex = checkedItem;
32372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.multiChoiceClickListener = multiChoiceClickListener;
32472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.checkedItems = checkedItems;
32572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.positiveButton = createButton(realDialog, AlertDialog.BUTTON_POSITIVE, positiveText, positiveListener);
32672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.negativeButton = createButton(realDialog, AlertDialog.BUTTON_NEGATIVE, negativeText, negativeListener);
32772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            latestAlertDialog.neutralButton = createButton(realDialog, AlertDialog.BUTTON_NEUTRAL, neutralText, neutralListener);
328c1939651f1f399da668bdd59b900ad897f2b3a27pivotal            latestAlertDialog.setCancelable(isCancelable);
32972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
33072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return realDialog;
33172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
33272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
33372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        @Implementation
33472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        public AlertDialog show() {
33572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            AlertDialog dialog = realBuilder.create();
33672ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            dialog.show();
33772ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return dialog;
33872ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
33972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin
34072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        private Button createButton(final DialogInterface dialog, final int which, CharSequence text, final DialogInterface.OnClickListener listener) {
34172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            Button button = new Button(context);
34272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            button.setText(text);
34372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            button.setOnClickListener(new View.OnClickListener() {
34472ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                @Override
34572ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                public void onClick(View v) {
346fd6517720932e1d9c426d15edbb81b8213b1f8f5Lowell Kirsh & Ryan Richard                    if (listener != null) {
347fd6517720932e1d9c426d15edbb81b8213b1f8f5Lowell Kirsh & Ryan Richard                        listener.onClick(dialog, which);
348fd6517720932e1d9c426d15edbb81b8213b1f8f5Lowell Kirsh & Ryan Richard                    }
34972ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin                }
35072ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            });
35172ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin            return button;
35272ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin        }
35372ee6c0e205c424f0706051d89e1c7f184bf8269Phil Goodwin    }
35450e71a2777cae2b5f630448c5ab22be4066d4d6dChristian Williams & Ryan Richard}
355