summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget/ActivityChooserView.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/widget/ActivityChooserView.java')
-rw-r--r--core/java/android/widget/ActivityChooserView.java765
1 files changed, 765 insertions, 0 deletions
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
new file mode 100644
index 0000000..2fe8162
--- /dev/null
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2011 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 android.widget;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Debug;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ActivityChooserModel.ActivityChooserModelClient;
+
+import com.android.internal.R;
+
+/**
+ * This class is a view for choosing an activity for handling a given {@link Intent}.
+ * <p>
+ * The view is composed of two adjacent buttons:
+ * <ul>
+ * <li>
+ * The left button is an immediate action and allows one click activity choosing.
+ * Tapping this button immediately executes the intent without requiring any further
+ * user input. Long press on this button shows a popup for changing the default
+ * activity.
+ * </li>
+ * <li>
+ * The right button is an overflow action and provides an optimized menu
+ * of additional activities. Tapping this button shows a popup anchored to this
+ * view, listing the most frequently used activities. This list is initially
+ * limited to a small number of items in frequency used order. The last item,
+ * "Show all..." serves as an affordance to display all available activities.
+ * </li>
+ * </ul>
+ * </p>
+ * </p>
+ * This view is backed by a {@link ActivityChooserModel}. Calling {@link #showPopup()}
+ * while this view is attached to the view hierarchy will show a popup with
+ * activities while if the view is not attached it will show a dialog.
+ * </p>
+ *
+ * @hide
+ */
+public class ActivityChooserView extends ViewGroup implements ActivityChooserModelClient {
+
+ /**
+ * An adapter for displaying the activities in an {@link AdapterView}.
+ */
+ private final ActivityChooserViewAdapter mAdapter;
+
+ /**
+ * Implementation of various interfaces to avoid publishing them in the APIs.
+ */
+ private final Callbacks mCallbacks;
+
+ /**
+ * The content of this view.
+ */
+ private final LinearLayout mActivityChooserContent;
+
+ /**
+ * The expand activities action button;
+ */
+ private final ImageButton mExpandActivityOverflowButton;
+
+ /**
+ * The default activities action button;
+ */
+ private final ImageButton mDefaultActionButton;
+
+ /**
+ * The header for handlers list.
+ */
+ private final View mListHeaderView;
+
+ /**
+ * The footer for handlers list.
+ */
+ private final View mListFooterView;
+
+ /**
+ * The title of the header view.
+ */
+ private TextView mListHeaderViewTitle;
+
+ /**
+ * The title for expanding the activities list.
+ */
+ private final String mListHeaderViewTitleSelectDefault;
+
+ /**
+ * The title if no activity exist.
+ */
+ private final String mListHeaderViewTitleNoActivities;
+
+ /**
+ * Popup window for showing the activity overflow list.
+ */
+ private ListPopupWindow mListPopupWindow;
+
+ /**
+ * Alert dialog for showing the activity overflow list.
+ */
+ private AlertDialog mAlertDialog;
+
+ /**
+ * Listener for the dismissal of the popup/alert.
+ */
+ private PopupWindow.OnDismissListener mOnDismissListener;
+
+ /**
+ * Flag whether a default activity currently being selected.
+ */
+ private boolean mIsSelectingDefaultActivity;
+
+ /**
+ * The count of activities in the popup.
+ */
+ private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT;
+
+ /**
+ * Flag whether this view is attached to a window.
+ */
+ private boolean mIsAttachedToWindow;
+
+ /**
+ * Flag whether this view is showing an alert dialog.
+ */
+ private boolean mIsShowingAlertDialog;
+
+ /**
+ * Flag whether this view is showing a popup window.
+ */
+ private boolean mIsShowingPopuWindow;
+
+ /**
+ * Create a new instance.
+ *
+ * @param context The application environment.
+ */
+ public ActivityChooserView(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param context The application environment.
+ * @param attrs A collection of attributes.
+ */
+ public ActivityChooserView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.actionButtonStyle);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param context The application environment.
+ * @param attrs A collection of attributes.
+ * @param defStyle The default style to apply to this view.
+ */
+ public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray attributesArray = context.obtainStyledAttributes(attrs,
+ R.styleable.ActivityChooserView, defStyle, 0);
+
+ mInitialActivityCount = attributesArray.getInt(
+ R.styleable.ActivityChooserView_initialActivityCount,
+ ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT);
+
+ Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable(
+ R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable);
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.activity_chooser_view, this, true);
+
+ mCallbacks = new Callbacks();
+
+ mActivityChooserContent = (LinearLayout) findViewById(R.id.activity_chooser_view_content);
+
+ mDefaultActionButton = (ImageButton) findViewById(R.id.default_activity_button);
+ mDefaultActionButton.setOnClickListener(mCallbacks);
+ mDefaultActionButton.setOnLongClickListener(mCallbacks);
+
+ mExpandActivityOverflowButton = (ImageButton) findViewById(R.id.expand_activities_button);
+ mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
+ mExpandActivityOverflowButton.setBackgroundDrawable(expandActivityOverflowButtonDrawable);
+
+ mListHeaderView = inflater.inflate(R.layout.activity_chooser_list_header, null);
+ mListFooterView = inflater.inflate(R.layout.activity_chooser_list_footer, null);
+
+ mListHeaderViewTitle = (TextView) mListHeaderView.findViewById(R.id.title);
+ mListHeaderViewTitleSelectDefault = context.getString(
+ R.string.activity_chooser_view_select_default);
+ mListHeaderViewTitleNoActivities = context.getString(
+ R.string.activity_chooser_view_no_activities);
+
+ mAdapter = new ActivityChooserViewAdapter();
+ mAdapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ updateButtons();
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setActivityChooserModel(ActivityChooserModel dataModel) {
+ mAdapter.setDataModel(dataModel);
+ if (isShowingPopup()) {
+ dismissPopup();
+ showPopup();
+ }
+ }
+
+ /**
+ * Sets the background for the button that expands the activity
+ * overflow list.
+ *
+ * <strong>Note:</strong> Clients would like to set this drawable
+ * as a clue about the action the chosen activity will perform. For
+ * example, if share activity is to be chosen the drawable should
+ * give a clue that sharing is to be performed.
+ *
+ * @param drawable The drawable.
+ */
+ public void setExpandActivityOverflowButtonDrawable(Drawable drawable) {
+ mExpandActivityOverflowButton.setBackgroundDrawable(drawable);
+ }
+
+ /**
+ * Shows the popup window with activities.
+ *
+ * @return True if the popup was shown, false if already showing.
+ */
+ public boolean showPopup() {
+ if (isShowingPopup()) {
+ return false;
+ }
+ mIsSelectingDefaultActivity = false;
+ showPopupUnchecked(mInitialActivityCount);
+ return true;
+ }
+
+ /**
+ * Shows the popup no matter if it was already showing.
+ *
+ * @param maxActivityCount The max number of activities to display.
+ */
+ private void showPopupUnchecked(int maxActivityCount) {
+ mAdapter.setMaxActivityCount(maxActivityCount);
+ if (mIsSelectingDefaultActivity) {
+ if (mAdapter.getActivityCount() > 0) {
+ mListHeaderViewTitle.setText(mListHeaderViewTitleSelectDefault);
+ } else {
+ mListHeaderViewTitle.setText(mListHeaderViewTitleNoActivities);
+ }
+ mAdapter.setHeaderView(mListHeaderView);
+ } else {
+ mAdapter.setHeaderView(null);
+ }
+
+ if (mAdapter.getActivityCount() > maxActivityCount + 1) {
+ mAdapter.setFooterView(mListFooterView);
+ } else {
+ mAdapter.setFooterView(null);
+ }
+
+ if (!mIsAttachedToWindow || mIsShowingAlertDialog) {
+ AlertDialog alertDialog = getAlertDilalog();
+ if (!alertDialog.isShowing()) {
+ alertDialog.setCustomTitle(this);
+ alertDialog.show();
+ mIsShowingAlertDialog = true;
+ }
+ } else {
+ ListPopupWindow popupWindow = getListPopupWindow();
+ if (!popupWindow.isShowing()) {
+ popupWindow.setContentWidth(mAdapter.measureContentWidth());
+ popupWindow.show();
+ mIsShowingPopuWindow = true;
+ }
+ }
+ }
+
+ /**
+ * Dismisses the popup window with activities.
+ *
+ * @return True if dismissed, false if already dismissed.
+ */
+ public boolean dismissPopup() {
+ if (!isShowingPopup()) {
+ return false;
+ }
+ if (mIsShowingAlertDialog) {
+ getAlertDilalog().dismiss();
+ } else if (mIsShowingPopuWindow) {
+ getListPopupWindow().dismiss();
+ }
+ return true;
+ }
+
+ /**
+ * Gets whether the popup window with activities is shown.
+ *
+ * @return True if the popup is shown.
+ */
+ public boolean isShowingPopup() {
+ if (mIsShowingAlertDialog) {
+ return getAlertDilalog().isShowing();
+ } else if (mIsShowingPopuWindow) {
+ return getListPopupWindow().isShowing();
+ }
+ return false;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ ActivityChooserModel dataModel = mAdapter.getDataModel();
+ if (dataModel != null) {
+ dataModel.readHistoricalData();
+ }
+ mIsAttachedToWindow = true;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ ActivityChooserModel dataModel = mAdapter.getDataModel();
+ if (dataModel != null) {
+ dataModel.persistHistoricalData();
+ }
+ mIsAttachedToWindow = false;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ mActivityChooserContent.measure(widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(mActivityChooserContent.getMeasuredWidth(),
+ mActivityChooserContent.getMeasuredHeight());
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ mActivityChooserContent.layout(left, top, right, bottom);
+ if (mIsShowingPopuWindow) {
+ if (isShown()) {
+ showPopupUnchecked(mAdapter.getMaxActivityCount());
+ } else {
+ dismissPopup();
+ }
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ mActivityChooserContent.onDraw(canvas);
+ }
+
+ public ActivityChooserModel getDataModel() {
+ return mAdapter.getDataModel();
+ }
+
+ /**
+ * Sets a listener to receive a callback when the popup is dismissed.
+ *
+ * @param listener The listener to be notified.
+ */
+ public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
+ mOnDismissListener = listener;
+ }
+
+ /**
+ * Sets the initial count of items shown in the activities popup
+ * i.e. the items before the popup is expanded. This is an upper
+ * bound since it is not guaranteed that such number of intent
+ * handlers exist.
+ *
+ * @param itemCount The initial popup item count.
+ */
+ public void setInitialActivityCount(int itemCount) {
+ mInitialActivityCount = itemCount;
+ }
+
+ /**
+ * Gets the list popup window which is lazily initialized.
+ *
+ * @return The popup.
+ */
+ private ListPopupWindow getListPopupWindow() {
+ if (mListPopupWindow == null) {
+ mListPopupWindow = new ListPopupWindow(getContext());
+ mListPopupWindow.setAdapter(mAdapter);
+ mListPopupWindow.setAnchorView(ActivityChooserView.this);
+ mListPopupWindow.setModal(true);
+ mListPopupWindow.setOnItemClickListener(mCallbacks);
+ mListPopupWindow.setOnDismissListener(mCallbacks);
+ }
+ return mListPopupWindow;
+ }
+
+ /**
+ * Gets the alert dialog which is lazily initialized.
+ *
+ * @return The popup.
+ */
+ private AlertDialog getAlertDilalog() {
+ if (mAlertDialog == null) {
+ Builder builder = new Builder(getContext());
+ builder.setAdapter(mAdapter, null);
+ mAlertDialog = builder.create();
+ mAlertDialog.getListView().setOnItemClickListener(mCallbacks);
+ mAlertDialog.setOnDismissListener(mCallbacks);
+ }
+ return mAlertDialog;
+ }
+
+ /**
+ * Updates the buttons state.
+ */
+ private void updateButtons() {
+ final int activityCount = mAdapter.getActivityCount();
+ if (activityCount > 0) {
+ mDefaultActionButton.setVisibility(VISIBLE);
+ if (mAdapter.getCount() > 0) {
+ mExpandActivityOverflowButton.setEnabled(true);
+ } else {
+ mExpandActivityOverflowButton.setEnabled(false);
+ }
+ ResolveInfo activity = mAdapter.getDefaultActivity();
+ PackageManager packageManager = mContext.getPackageManager();
+ mDefaultActionButton.setBackgroundDrawable(activity.loadIcon(packageManager));
+ } else {
+ mDefaultActionButton.setVisibility(View.INVISIBLE);
+ mExpandActivityOverflowButton.setEnabled(false);
+ }
+ }
+
+ /**
+ * Interface implementation to avoid publishing them in the APIs.
+ */
+ private class Callbacks implements AdapterView.OnItemClickListener,
+ View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener,
+ DialogInterface.OnDismissListener {
+
+ // AdapterView#OnItemClickListener
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter();
+ final int itemViewType = adapter.getItemViewType(position);
+ switch (itemViewType) {
+ case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_HEADER: {
+ /* do nothing */
+ } break;
+ case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: {
+ showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED);
+ } break;
+ case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: {
+ dismissPopup();
+ if (mIsSelectingDefaultActivity) {
+ mAdapter.getDataModel().setDefaultActivity(position);
+ } else {
+ // The first item in the model is default action => adjust index
+ Intent launchIntent = mAdapter.getDataModel().chooseActivity(position + 1);
+ mContext.startActivity(launchIntent);
+ }
+ } break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // View.OnClickListener
+ public void onClick(View view) {
+ if (view == mDefaultActionButton) {
+ dismissPopup();
+ ResolveInfo defaultActivity = mAdapter.getDefaultActivity();
+ final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity);
+ Intent launchIntent = mAdapter.getDataModel().chooseActivity(index);
+ mContext.startActivity(launchIntent);
+ } else if (view == mExpandActivityOverflowButton) {
+ mIsSelectingDefaultActivity = false;
+ showPopupUnchecked(mInitialActivityCount);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // OnLongClickListener#onLongClick
+ @Override
+ public boolean onLongClick(View view) {
+ if (view == mDefaultActionButton) {
+ if (mAdapter.getCount() > 0) {
+ mIsSelectingDefaultActivity = true;
+ showPopupUnchecked(mInitialActivityCount);
+ }
+ } else {
+ throw new IllegalArgumentException();
+ }
+ return true;
+ }
+
+ // PopUpWindow.OnDismissListener#onDismiss
+ public void onDismiss() {
+ mIsShowingPopuWindow = false;
+ notifyOnDismissListener();
+ }
+
+ // DialogInterface.OnDismissListener#onDismiss
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mIsShowingAlertDialog = false;
+ AlertDialog alertDialog = (AlertDialog) dialog;
+ alertDialog.setCustomTitle(null);
+ notifyOnDismissListener();
+ }
+
+ private void notifyOnDismissListener() {
+ if (mOnDismissListener != null) {
+ mOnDismissListener.onDismiss();
+ }
+ }
+ }
+
+ /**
+ * Adapter for backing the list of activities shown in the popup.
+ */
+ private class ActivityChooserViewAdapter extends BaseAdapter {
+
+ public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE;
+
+ public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4;
+
+ private static final int ITEM_VIEW_TYPE_HEADER = 0;
+
+ private static final int ITEM_VIEW_TYPE_ACTIVITY = 1;
+
+ private static final int ITEM_VIEW_TYPE_FOOTER = 2;
+
+ private static final int ITEM_VIEW_TYPE_COUNT = 3;
+
+ private final DataSetObserver mDataSetOberver = new DataSetObserver() {
+
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ notifyDataSetChanged();
+ }
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ notifyDataSetInvalidated();
+ }
+ };
+
+ private ActivityChooserModel mDataModel;
+
+ private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT;
+
+ private ResolveInfo mDefaultActivity;
+
+ private View mHeaderView;
+
+ private View mFooterView;
+
+ public void setDataModel(ActivityChooserModel dataModel) {
+ mDataModel = dataModel;
+ mDataModel.registerObserver(mDataSetOberver);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ if (mDataModel.getActivityCount() > 0) {
+ mDefaultActivity = mDataModel.getDefaultActivity();
+ } else {
+ mDefaultActivity = null;
+ }
+ super.notifyDataSetChanged();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (mHeaderView != null && position == 0) {
+ return ITEM_VIEW_TYPE_HEADER;
+ } else if (mFooterView != null && position == getCount() - 1) {
+ return ITEM_VIEW_TYPE_FOOTER;
+ } else {
+ return ITEM_VIEW_TYPE_ACTIVITY;
+ }
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return ITEM_VIEW_TYPE_COUNT;
+ }
+
+ public int getCount() {
+ int count = 0;
+ int activityCount = mDataModel.getActivityCount();
+ if (activityCount > 0) {
+ activityCount--;
+ }
+ count = Math.min(activityCount, mMaxActivityCount);
+ if (mHeaderView != null) {
+ count++;
+ }
+ if (mFooterView != null) {
+ count++;
+ }
+ return count;
+ }
+
+ public Object getItem(int position) {
+ final int itemViewType = getItemViewType(position);
+ switch (itemViewType) {
+ case ITEM_VIEW_TYPE_HEADER:
+ return mHeaderView;
+ case ITEM_VIEW_TYPE_FOOTER:
+ return mFooterView;
+ case ITEM_VIEW_TYPE_ACTIVITY:
+ int targetIndex = (mHeaderView == null) ? position : position - 1;
+ if (mDefaultActivity != null) {
+ targetIndex++;
+ }
+ return mDataModel.getActivity(targetIndex);
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ final int itemViewType = getItemViewType(position);
+ switch (itemViewType) {
+ case ITEM_VIEW_TYPE_HEADER:
+ return false;
+ case ITEM_VIEW_TYPE_FOOTER:
+ case ITEM_VIEW_TYPE_ACTIVITY:
+ return true;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final int itemViewType = getItemViewType(position);
+ switch (itemViewType) {
+ case ITEM_VIEW_TYPE_HEADER:
+ return mHeaderView;
+ case ITEM_VIEW_TYPE_FOOTER:
+ return mFooterView;
+ case ITEM_VIEW_TYPE_ACTIVITY:
+ if (convertView == null || convertView.getId() != R.id.list_item) {
+ convertView = LayoutInflater.from(getContext()).inflate(
+ R.layout.activity_chooser_view_list_item, parent, false);
+ }
+ PackageManager packageManager = mContext.getPackageManager();
+ // Set the icon
+ ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
+ ResolveInfo activity = (ResolveInfo) getItem(position);
+ iconView.setBackgroundDrawable(activity.loadIcon(packageManager));
+ // Set the title.
+ TextView titleView = (TextView) convertView.findViewById(R.id.title);
+ titleView.setText(activity.loadLabel(packageManager));
+ return convertView;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public int measureContentWidth() {
+ // The user may have specified some of the target not to be show but we
+ // want to measure all of them since after expansion they should fit.
+ final int oldMaxActivityCount = mMaxActivityCount;
+ mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED;
+
+ int contentWidth = 0;
+ View itemView = null;
+
+ final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ final int count = getCount();
+
+ for (int i = 0; i < count; i++) {
+ itemView = getView(i, itemView, null);
+ itemView.measure(widthMeasureSpec, heightMeasureSpec);
+ contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth());
+ }
+
+ mMaxActivityCount = oldMaxActivityCount;
+
+ return contentWidth;
+ }
+
+ public void setMaxActivityCount(int maxActivityCount) {
+ if (mMaxActivityCount != maxActivityCount) {
+ mMaxActivityCount = maxActivityCount;
+ notifyDataSetChanged();
+ }
+ }
+
+ public ResolveInfo getDefaultActivity() {
+ return mDefaultActivity;
+ }
+
+ public void setHeaderView(View headerView) {
+ if (mHeaderView != headerView) {
+ mHeaderView = headerView;
+ notifyDataSetChanged();
+ }
+ }
+
+ public void setFooterView(View footerView) {
+ if (mFooterView != footerView) {
+ mFooterView = footerView;
+ notifyDataSetChanged();
+ }
+ }
+
+ public int getActivityCount() {
+ return mDataModel.getActivityCount();
+ }
+
+ public int getMaxActivityCount() {
+ return mMaxActivityCount;
+ }
+
+ public ActivityChooserModel getDataModel() {
+ return mDataModel;
+ }
+ }
+}