blob: 661c5d327fccd2af3fd94462f6e87d68bbbaeac8 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.contacts.util;
import com.android.contacts.R;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.os.Bundle;
import android.view.View;
/**
* Manages creation and destruction of Dialogs that are to be shown by Views. Unlike how Dialogs
* are regularly used, the Dialogs are not recycled but immediately destroyed after dismissal.
* To be able to do that, two IDs are required which are used consecutively.
* How to use:<ul>
* <li>The owning Activity creates on instance of this class, passing itself and two Ids that are
* not used by other Dialogs of the Activity.</li>
* <li>Views owning Dialogs must implement {@link DialogManager.DialogShowingView}</li>
* <li>After creating the Views, configureManagingViews must be called to configure all views
* that implement {@link DialogManager.DialogShowingView}</li>
* <li>In the implementation of {@link Activity#onCreateDialog}, calls for the
* ViewId are forwarded to {@link DialogManager#onCreateDialog(int, Bundle)}</li>
* </ul>
* To actually show a Dialog, the View uses {@link DialogManager#showDialogInView(View, Bundle)},
* passing itself as a first parameter
*/
public class DialogManager {
private final Activity mActivity;
private boolean mUseDialogId2 = false;
public final static String VIEW_ID_KEY = "view_id";
public static final boolean isManagedId(int id) {
return (id == R.id.dialog_manager_id_1) || (id == R.id.dialog_manager_id_2);
}
/**
* Creates a new instance of this class for the given Activity.
* @param activity The activity this object is used for
*/
public DialogManager(final Activity activity) {
if (activity == null) throw new IllegalArgumentException("activity must not be null");
mActivity = activity;
}
/**
* Called by a View to show a dialog. It has to pass itself and a Bundle with extra information.
* If the view can show several dialogs, it should distinguish them using an item in the Bundle.
* The View needs to have a valid and unique Id. This function modifies the bundle by adding a
* new item named {@link DialogManager#VIEW_ID_KEY}
*/
public void showDialogInView(final View view, final Bundle bundle) {
final int viewId = view.getId();
if (bundle.containsKey(VIEW_ID_KEY)) {
throw new IllegalArgumentException("Bundle already contains a " + VIEW_ID_KEY);
}
if (viewId == View.NO_ID) {
throw new IllegalArgumentException("View does not have a proper ViewId");
}
bundle.putInt(VIEW_ID_KEY, viewId);
int dialogId = mUseDialogId2 ? R.id.dialog_manager_id_2 : R.id.dialog_manager_id_1;
mActivity.showDialog(dialogId, bundle);
}
/**
* Callback function called by the Activity to handle View-managed Dialogs.
* This function returns null if the id is not one of the two reserved Ids.
*/
public Dialog onCreateDialog(final int id, final Bundle bundle) {
if (id == R.id.dialog_manager_id_1) {
mUseDialogId2 = true;
} else if (id == R.id.dialog_manager_id_2) {
mUseDialogId2 = false;
} else {
return null;
}
if (!bundle.containsKey(VIEW_ID_KEY)) {
throw new IllegalArgumentException("Bundle does not contain a ViewId");
}
final int viewId = bundle.getInt(VIEW_ID_KEY);
final View view = mActivity.findViewById(viewId);
if (view == null || !(view instanceof DialogShowingView)) {
return null;
}
final Dialog dialog = ((DialogShowingView)view).createDialog(bundle);
if (dialog == null) {
return dialog;
}
// As we will never re-use this dialog, we can completely kill it here
dialog.setOnDismissListener(new OnDismissListener() {
public void onDismiss(DialogInterface dialogInterface) {
mActivity.removeDialog(id);
}
});
return dialog;
}
/**
* Interface to implemented by Views that show Dialogs
*/
public interface DialogShowingView {
/**
* Callback function to create a Dialog. Notice that the DialogManager overwrites the
* OnDismissListener on the returned Dialog, so the View should not use this Listener itself
*/
Dialog createDialog(Bundle bundle);
}
/**
* Interface to implemented by Activities that host View-showing dialogs
*/
public interface DialogShowingViewActivity {
DialogManager getDialogManager();
}
}