ActivityChooserViewpublic class ActivityChooserView extends android.view.ViewGroup implements android.widget.ActivityChooserModel.ActivityChooserModelClientThis class is a view for choosing an activity for handling a given {@link Intent}.
The view is composed of two adjacent buttons:
-
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.
-
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.
|
Fields Summary |
---|
private static final String | LOG_TAG | private final ActivityChooserViewAdapter | mAdapterAn adapter for displaying the activities in an {@link AdapterView}. | private final Callbacks | mCallbacksImplementation of various interfaces to avoid publishing them in the APIs. | private final LinearLayout | mActivityChooserContentThe content of this view. | private final android.graphics.drawable.Drawable | mActivityChooserContentBackgroundStores the background drawable to allow hiding and latter showing. | private final FrameLayout | mExpandActivityOverflowButtonThe expand activities action button; | private final ImageView | mExpandActivityOverflowButtonImageThe image for the expand activities action button; | private final FrameLayout | mDefaultActivityButtonThe default activities action button; | private final ImageView | mDefaultActivityButtonImageThe image for the default activities action button; | private final int | mListPopupMaxWidthThe maximal width of the list popup. | android.view.ActionProvider | mProviderThe ActionProvider hosting this view, if applicable. | private final android.database.DataSetObserver | mModelDataSetOberverObserver for the model data. | private final android.view.ViewTreeObserver.OnGlobalLayoutListener | mOnGlobalLayoutListener | private ListPopupWindow | mListPopupWindowPopup window for showing the activity overflow list. | private PopupWindow.OnDismissListener | mOnDismissListenerListener for the dismissal of the popup/alert. | private boolean | mIsSelectingDefaultActivityFlag whether a default activity currently being selected. | private int | mInitialActivityCountThe count of activities in the popup. | private boolean | mIsAttachedToWindowFlag whether this view is attached to a window. | private int | mDefaultActionButtonContentDescriptionString resource for formatting content description of the default target. |
Constructors Summary |
---|
public ActivityChooserView(android.content.Context context)Create a new instance.
this(context, null);
| public ActivityChooserView(android.content.Context context, android.util.AttributeSet attrs)Create a new instance.
this(context, attrs, 0);
| public ActivityChooserView(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)Create a new instance.
this(context, attrs, defStyleAttr, 0);
| public ActivityChooserView(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes)Create a new instance.
super(context, attrs, defStyleAttr, defStyleRes);
TypedArray attributesArray = context.obtainStyledAttributes(attrs,
R.styleable.ActivityChooserView, defStyleAttr, defStyleRes);
mInitialActivityCount = attributesArray.getInt(
R.styleable.ActivityChooserView_initialActivityCount,
ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT);
Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable(
R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable);
attributesArray.recycle();
LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(R.layout.activity_chooser_view, this, true);
mCallbacks = new Callbacks();
mActivityChooserContent = (LinearLayout) findViewById(R.id.activity_chooser_view_content);
mActivityChooserContentBackground = mActivityChooserContent.getBackground();
mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
mDefaultActivityButton.setOnClickListener(mCallbacks);
mDefaultActivityButton.setOnLongClickListener(mCallbacks);
mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
expandButton.setOnClickListener(mCallbacks);
expandButton.setAccessibilityDelegate(new AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setCanOpenPopup(true);
}
});
expandButton.setOnTouchListener(new ForwardingListener(expandButton) {
@Override
public ListPopupWindow getPopup() {
return getListPopupWindow();
}
@Override
protected boolean onForwardingStarted() {
showPopup();
return true;
}
@Override
protected boolean onForwardingStopped() {
dismissPopup();
return true;
}
});
mExpandActivityOverflowButton = expandButton;
mExpandActivityOverflowButtonImage =
(ImageView) expandButton.findViewById(R.id.image);
mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
mAdapter = new ActivityChooserViewAdapter();
mAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
updateAppearance();
}
});
Resources resources = context.getResources();
mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2,
resources.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth));
|
Methods Summary |
---|
public boolean | dismissPopup()Dismisses the popup window with activities.
if (isShowingPopup()) {
getListPopupWindow().dismiss();
ViewTreeObserver viewTreeObserver = getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
}
}
return true;
| public ActivityChooserModel | getDataModel()
return mAdapter.getDataModel();
| private ListPopupWindow | getListPopupWindow()Gets the list popup window which is lazily initialized.
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;
| public boolean | isShowingPopup()Gets whether the popup window with activities is shown.
return getListPopupWindow().isShowing();
| protected void | onAttachedToWindow()
super.onAttachedToWindow();
ActivityChooserModel dataModel = mAdapter.getDataModel();
if (dataModel != null) {
dataModel.registerObserver(mModelDataSetOberver);
}
mIsAttachedToWindow = true;
| protected void | onDetachedFromWindow()
super.onDetachedFromWindow();
ActivityChooserModel dataModel = mAdapter.getDataModel();
if (dataModel != null) {
dataModel.unregisterObserver(mModelDataSetOberver);
}
ViewTreeObserver viewTreeObserver = getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
}
if (isShowingPopup()) {
dismissPopup();
}
mIsAttachedToWindow = false;
| protected void | onLayout(boolean changed, int left, int top, int right, int bottom)
mActivityChooserContent.layout(0, 0, right - left, bottom - top);
if (!isShowingPopup()) {
dismissPopup();
}
| protected void | onMeasure(int widthMeasureSpec, int heightMeasureSpec)
View child = mActivityChooserContent;
// If the default action is not visible we want to be as tall as the
// ActionBar so if this widget is used in the latter it will look as
// a normal action button.
if (mDefaultActivityButton.getVisibility() != VISIBLE) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
MeasureSpec.EXACTLY);
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight());
| public void | setActivityChooserModel(ActivityChooserModel dataModel){@inheritDoc}
mAdapter.setDataModel(dataModel);
if (isShowingPopup()) {
dismissPopup();
showPopup();
}
| public void | setDefaultActionButtonContentDescription(int resourceId)Sets a content description of the default action button. This
resource should be a string taking one formatting argument and
will be used for formatting the content description of the button
dynamically as the default target changes. For example, a resource
pointing to the string "share with %1$s" will result in a content
description "share with Bluetooth" for the Bluetooth activity.
mDefaultActionButtonContentDescription = resourceId;
| public void | setExpandActivityOverflowButtonContentDescription(int resourceId)Sets the content description for the button that expands the activity
overflow list.
description as a clue about the action performed by the button.
For example, if a share activity is to be chosen the content
description should be something like "Share with".
CharSequence contentDescription = mContext.getString(resourceId);
mExpandActivityOverflowButtonImage.setContentDescription(contentDescription);
| public void | setExpandActivityOverflowButtonDrawable(android.graphics.drawable.Drawable drawable)Sets the background for the button that expands the activity
overflow list.
Note: Clients would like to set this drawable
as a clue about the action the chosen activity will perform. For
example, if a share activity is to be chosen the drawable should
give a clue that sharing is to be performed.
mExpandActivityOverflowButtonImage.setImageDrawable(drawable);
| public void | setInitialActivityCount(int itemCount)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.
mInitialActivityCount = itemCount;
| public void | setOnDismissListener(PopupWindow.OnDismissListener listener)Sets a listener to receive a callback when the popup is dismissed.
mOnDismissListener = listener;
| public void | setProvider(android.view.ActionProvider provider)Set the provider hosting this view, if applicable.
mProvider = provider;
| public boolean | showPopup()Shows the popup window with activities.
if (isShowingPopup() || !mIsAttachedToWindow) {
return false;
}
mIsSelectingDefaultActivity = false;
showPopupUnchecked(mInitialActivityCount);
return true;
| private void | showPopupUnchecked(int maxActivityCount)Shows the popup no matter if it was already showing.
if (mAdapter.getDataModel() == null) {
throw new IllegalStateException("No data model. Did you call #setDataModel?");
}
getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
final boolean defaultActivityButtonShown =
mDefaultActivityButton.getVisibility() == VISIBLE;
final int activityCount = mAdapter.getActivityCount();
final int maxActivityCountOffset = defaultActivityButtonShown ? 1 : 0;
if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED
&& activityCount > maxActivityCount + maxActivityCountOffset) {
mAdapter.setShowFooterView(true);
mAdapter.setMaxActivityCount(maxActivityCount - 1);
} else {
mAdapter.setShowFooterView(false);
mAdapter.setMaxActivityCount(maxActivityCount);
}
ListPopupWindow popupWindow = getListPopupWindow();
if (!popupWindow.isShowing()) {
if (mIsSelectingDefaultActivity || !defaultActivityButtonShown) {
mAdapter.setShowDefaultActivity(true, defaultActivityButtonShown);
} else {
mAdapter.setShowDefaultActivity(false, false);
}
final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth);
popupWindow.setContentWidth(contentWidth);
popupWindow.show();
if (mProvider != null) {
mProvider.subUiVisibilityChanged(true);
}
popupWindow.getListView().setContentDescription(mContext.getString(
R.string.activitychooserview_choose_application));
}
| private void | updateAppearance()Updates the buttons state.
// Expand overflow button.
if (mAdapter.getCount() > 0) {
mExpandActivityOverflowButton.setEnabled(true);
} else {
mExpandActivityOverflowButton.setEnabled(false);
}
// Default activity button.
final int activityCount = mAdapter.getActivityCount();
final int historySize = mAdapter.getHistorySize();
if (activityCount==1 || activityCount > 1 && historySize > 0) {
mDefaultActivityButton.setVisibility(VISIBLE);
ResolveInfo activity = mAdapter.getDefaultActivity();
PackageManager packageManager = mContext.getPackageManager();
mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager));
if (mDefaultActionButtonContentDescription != 0) {
CharSequence label = activity.loadLabel(packageManager);
String contentDescription = mContext.getString(
mDefaultActionButtonContentDescription, label);
mDefaultActivityButton.setContentDescription(contentDescription);
}
} else {
mDefaultActivityButton.setVisibility(View.GONE);
}
// Activity chooser content.
if (mDefaultActivityButton.getVisibility() == VISIBLE) {
mActivityChooserContent.setBackground(mActivityChooserContentBackground);
} else {
mActivityChooserContent.setBackground(null);
}
|
|