1 /*
2  * Copyright (C) 2010 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.contacts.util;
18 
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.content.DialogInterface;
22 import android.content.DialogInterface.OnDismissListener;
23 import android.os.Bundle;
24 import android.view.View;
25 
26 import com.android.contacts.R;
27 
28 /**
29  * Manages creation and destruction of Dialogs that are to be shown by Views. Unlike how Dialogs
30  * are regularly used, the Dialogs are not recycled but immediately destroyed after dismissal.
31  * To be able to do that, two IDs are required which are used consecutively.
32  * How to use:<ul>
33  * <li>The owning Activity creates on instance of this class, passing itself and two Ids that are
34  *    not used by other Dialogs of the Activity.</li>
35  * <li>Views owning Dialogs must implement {@link DialogManager.DialogShowingView}</li>
36  * <li>After creating the Views, configureManagingViews must be called to configure all views
37  *    that implement {@link DialogManager.DialogShowingView}</li>
38  * <li>In the implementation of {@link Activity#onCreateDialog}, calls for the
39  *    ViewId are forwarded to {@link DialogManager#onCreateDialog(int, Bundle)}</li>
40  * </ul>
41  * To actually show a Dialog, the View uses {@link DialogManager#showDialogInView(View, Bundle)},
42  * passing itself as a first parameter
43  */
44 public class DialogManager {
45     private final Activity mActivity;
46     private boolean mUseDialogId2 = false;
47     public final static String VIEW_ID_KEY = "view_id";
48 
isManagedId(int id)49     public static final boolean isManagedId(int id) {
50         return (id == R.id.dialog_manager_id_1) || (id == R.id.dialog_manager_id_2);
51     }
52 
53     /**
54      * Creates a new instance of this class for the given Activity.
55      * @param activity The activity this object is used for
56      */
DialogManager(final Activity activity)57     public DialogManager(final Activity activity) {
58         if (activity == null) throw new IllegalArgumentException("activity must not be null");
59         mActivity = activity;
60     }
61 
62     /**
63      * Called by a View to show a dialog. It has to pass itself and a Bundle with extra information.
64      * If the view can show several dialogs, it should distinguish them using an item in the Bundle.
65      * The View needs to have a valid and unique Id. This function modifies the bundle by adding a
66      * new item named {@link DialogManager#VIEW_ID_KEY}
67      */
showDialogInView(final View view, final Bundle bundle)68     public void showDialogInView(final View view, final Bundle bundle) {
69         final int viewId = view.getId();
70         if (bundle.containsKey(VIEW_ID_KEY)) {
71             throw new IllegalArgumentException("Bundle already contains a " + VIEW_ID_KEY);
72         }
73         if (viewId == View.NO_ID) {
74             throw new IllegalArgumentException("View does not have a proper ViewId");
75         }
76         bundle.putInt(VIEW_ID_KEY, viewId);
77         int dialogId = mUseDialogId2 ? R.id.dialog_manager_id_2 : R.id.dialog_manager_id_1;
78         mActivity.showDialog(dialogId, bundle);
79     }
80 
81     /**
82      * Callback function called by the Activity to handle View-managed Dialogs.
83      * This function returns null if the id is not one of the two reserved Ids.
84      */
onCreateDialog(final int id, final Bundle bundle)85     public Dialog onCreateDialog(final int id, final Bundle bundle) {
86         if (id == R.id.dialog_manager_id_1) {
87             mUseDialogId2 = true;
88         } else if (id == R.id.dialog_manager_id_2) {
89             mUseDialogId2 = false;
90         } else {
91             return null;
92         }
93         if (!bundle.containsKey(VIEW_ID_KEY)) {
94             throw new IllegalArgumentException("Bundle does not contain a ViewId");
95         }
96         final int viewId = bundle.getInt(VIEW_ID_KEY);
97         final View view = mActivity.findViewById(viewId);
98         if (view == null || !(view instanceof DialogShowingView)) {
99             return null;
100         }
101         final Dialog dialog = ((DialogShowingView)view).createDialog(bundle);
102         if (dialog == null) {
103             return dialog;
104         }
105 
106         // As we will never re-use this dialog, we can completely kill it here
107         dialog.setOnDismissListener(new OnDismissListener() {
108             public void onDismiss(DialogInterface dialogInterface) {
109                 mActivity.removeDialog(id);
110             }
111         });
112         return dialog;
113     }
114 
115     /**
116      * Interface to implemented by Views that show Dialogs
117      */
118     public interface DialogShowingView {
119         /**
120          * Callback function to create a Dialog. Notice that the DialogManager overwrites the
121          * OnDismissListener on the returned Dialog, so the View should not use this Listener itself
122          */
createDialog(Bundle bundle)123         Dialog createDialog(Bundle bundle);
124     }
125 
126     /**
127      * Interface to implemented by Activities that host View-showing dialogs
128      */
129     public interface DialogShowingViewActivity {
getDialogManager()130         DialogManager getDialogManager();
131     }
132 }
133