14cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann/* 2ef3f8f045ed4150caa64749742227acd0e6b85d8Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project 34cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * 44cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 54cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * you may not use this file except in compliance with the License. 64cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * You may obtain a copy of the License at 74cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * 84cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 94cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * 104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Unless required by applicable law or agreed to in writing, software 114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 124cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * See the License for the specific language governing permissions and 144cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * limitations under the License 154cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann */ 164cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 17c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmannpackage com.android.contacts.util; 187e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 197e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.app.Activity; 207e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.app.Dialog; 217e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.content.DialogInterface; 227e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.content.DialogInterface.OnDismissListener; 237e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.os.Bundle; 247e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.view.View; 257e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 26e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 27e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 287e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann/** 297e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Manages creation and destruction of Dialogs that are to be shown by Views. Unlike how Dialogs 307e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * are regularly used, the Dialogs are not recycled but immediately destroyed after dismissal. 317e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * To be able to do that, two IDs are required which are used consecutively. 327e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * How to use:<ul> 337e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>The owning Activity creates on instance of this class, passing itself and two Ids that are 347e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * not used by other Dialogs of the Activity.</li> 357e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>Views owning Dialogs must implement {@link DialogManager.DialogShowingView}</li> 367e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>After creating the Views, configureManagingViews must be called to configure all views 377e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * that implement {@link DialogManager.DialogShowingView}</li> 387e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>In the implementation of {@link Activity#onCreateDialog}, calls for the 397e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * ViewId are forwarded to {@link DialogManager#onCreateDialog(int, Bundle)}</li> 407e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * </ul> 417e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * To actually show a Dialog, the View uses {@link DialogManager#showDialogInView(View, Bundle)}, 427e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * passing itself as a first parameter 437e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 447e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannpublic class DialogManager { 457e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann private final Activity mActivity; 467e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann private boolean mUseDialogId2 = false; 477e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann public final static String VIEW_ID_KEY = "view_id"; 487e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 493b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann public static final boolean isManagedId(int id) { 503b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann return (id == R.id.dialog_manager_id_1) || (id == R.id.dialog_manager_id_2); 513b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann } 523b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann 537e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann /** 547e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Creates a new instance of this class for the given Activity. 557e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * @param activity The activity this object is used for 567e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 573b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann public DialogManager(final Activity activity) { 587e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann if (activity == null) throw new IllegalArgumentException("activity must not be null"); 597e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann mActivity = activity; 607e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 617e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 627e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann /** 637e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Called by a View to show a dialog. It has to pass itself and a Bundle with extra information. 647e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * If the view can show several dialogs, it should distinguish them using an item in the Bundle. 657e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * The View needs to have a valid and unique Id. This function modifies the bundle by adding a 667e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * new item named {@link DialogManager#VIEW_ID_KEY} 677e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 687e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann public void showDialogInView(final View view, final Bundle bundle) { 697e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann final int viewId = view.getId(); 707e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann if (bundle.containsKey(VIEW_ID_KEY)) { 717e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann throw new IllegalArgumentException("Bundle already contains a " + VIEW_ID_KEY); 727e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 737e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann if (viewId == View.NO_ID) { 747e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann throw new IllegalArgumentException("View does not have a proper ViewId"); 757e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 767e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann bundle.putInt(VIEW_ID_KEY, viewId); 773b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann int dialogId = mUseDialogId2 ? R.id.dialog_manager_id_2 : R.id.dialog_manager_id_1; 787e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann mActivity.showDialog(dialogId, bundle); 797e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 807e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 817e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann /** 827e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Callback function called by the Activity to handle View-managed Dialogs. 837e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * This function returns null if the id is not one of the two reserved Ids. 847e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 857e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann public Dialog onCreateDialog(final int id, final Bundle bundle) { 863b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann if (id == R.id.dialog_manager_id_1) { 877e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann mUseDialogId2 = true; 883b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann } else if (id == R.id.dialog_manager_id_2) { 897e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann mUseDialogId2 = false; 907e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } else { 917e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann return null; 927e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 937e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann if (!bundle.containsKey(VIEW_ID_KEY)) { 947e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann throw new IllegalArgumentException("Bundle does not contain a ViewId"); 957e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 967e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann final int viewId = bundle.getInt(VIEW_ID_KEY); 977e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann final View view = mActivity.findViewById(viewId); 987e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann if (view == null || !(view instanceof DialogShowingView)) { 997e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann return null; 1007e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 1017e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann final Dialog dialog = ((DialogShowingView)view).createDialog(bundle); 1020a6fa1de53d1c95c75b5841d4dc25e2a3367bdc1Dmitri Plotnikov if (dialog == null) { 1030a6fa1de53d1c95c75b5841d4dc25e2a3367bdc1Dmitri Plotnikov return dialog; 1040a6fa1de53d1c95c75b5841d4dc25e2a3367bdc1Dmitri Plotnikov } 1057e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 1067e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann // As we will never re-use this dialog, we can completely kill it here 1077e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann dialog.setOnDismissListener(new OnDismissListener() { 1087e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann public void onDismiss(DialogInterface dialogInterface) { 1097e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann mActivity.removeDialog(id); 1107e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 1117e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann }); 1127e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann return dialog; 1137e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 1147e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 1157e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann /** 1167e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Interface to implemented by Views that show Dialogs 1177e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 1187e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann public interface DialogShowingView { 11994c70ac5e5c8c261e962ef96b4b7974e25927fd9Daniel Lehmann /** 12094c70ac5e5c8c261e962ef96b4b7974e25927fd9Daniel Lehmann * Callback function to create a Dialog. Notice that the DialogManager overwrites the 1217e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * OnDismissListener on the returned Dialog, so the View should not use this Listener itself 1227e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 1237e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann Dialog createDialog(Bundle bundle); 1247e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 1257e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann 1267e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann /** 1277e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Interface to implemented by Activities that host View-showing dialogs 1287e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */ 1297e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann public interface DialogShowingViewActivity { 1307e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann DialogManager getDialogManager(); 1317e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann } 1327e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann} 133