ActivityChooserView.java revision f2e754002166b8126e6faf8c494da5835432d572
1/*
2 * Copyright (C) 2011 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
17package android.widget;
18
19import android.content.Context;
20import android.content.Intent;
21import android.content.pm.PackageManager;
22import android.content.pm.ResolveInfo;
23import android.content.res.Resources;
24import android.content.res.TypedArray;
25import android.database.DataSetObserver;
26import android.graphics.Canvas;
27import android.graphics.drawable.Drawable;
28import android.util.AttributeSet;
29import android.view.LayoutInflater;
30import android.view.View;
31import android.view.View.MeasureSpec;
32import android.view.ViewGroup;
33import android.view.ViewTreeObserver;
34import android.view.ViewTreeObserver.OnGlobalLayoutListener;
35import android.widget.ActivityChooserModel.ActivityChooserModelClient;
36
37import com.android.internal.R;
38
39/**
40 * This class is a view for choosing an activity for handling a given {@link Intent}.
41 * <p>
42 * The view is composed of two adjacent buttons:
43 * <ul>
44 * <li>
45 * The left button is an immediate action and allows one click activity choosing.
46 * Tapping this button immediately executes the intent without requiring any further
47 * user input. Long press on this button shows a popup for changing the default
48 * activity.
49 * </li>
50 * <li>
51 * The right button is an overflow action and provides an optimized menu
52 * of additional activities. Tapping this button shows a popup anchored to this
53 * view, listing the most frequently used activities. This list is initially
54 * limited to a small number of items in frequency used order. The last item,
55 * "Show all..." serves as an affordance to display all available activities.
56 * </li>
57 * </ul>
58 * </p>
59 *
60 * @hide
61 */
62public class ActivityChooserView extends ViewGroup implements ActivityChooserModelClient {
63
64    /**
65     * An adapter for displaying the activities in an {@link AdapterView}.
66     */
67    private final ActivityChooserViewAdapter mAdapter;
68
69    /**
70     * Implementation of various interfaces to avoid publishing them in the APIs.
71     */
72    private final Callbacks mCallbacks;
73
74    /**
75     * The content of this view.
76     */
77    private final LinearLayout mActivityChooserContent;
78
79    /**
80     * Stores the background drawable to allow hiding and latter showing.
81     */
82    private final Drawable mActivityChooserContentBackground;
83
84    /**
85     * The expand activities action button;
86     */
87    private final FrameLayout mExpandActivityOverflowButton;
88
89    /**
90     * The image for the expand activities action button;
91     */
92    private final ImageView mExpandActivityOverflowButtonImage;
93
94    /**
95     * The default activities action button;
96     */
97    private final FrameLayout mDefaultActivityButton;
98
99    /**
100     * The image for the default activities action button;
101     */
102    private final ImageView mDefaultActivityButtonImage;
103
104    /**
105     * The maximal width of the list popup.
106     */
107    private final int mListPopupMaxWidth;
108
109    /**
110     * Observer for the model data.
111     */
112    private final DataSetObserver mModelDataSetOberver = new DataSetObserver() {
113
114        @Override
115        public void onChanged() {
116            super.onChanged();
117            mAdapter.notifyDataSetChanged();
118        }
119        @Override
120        public void onInvalidated() {
121            super.onInvalidated();
122            mAdapter.notifyDataSetInvalidated();
123        }
124    };
125
126    private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
127        @Override
128        public void onGlobalLayout() {
129            if (isShowingPopup()) {
130                if (!isShown()) {
131                    getListPopupWindow().dismiss();
132                } else {
133                    getListPopupWindow().show();
134                }
135            }
136        }
137    };
138
139    /**
140     * Popup window for showing the activity overflow list.
141     */
142    private ListPopupWindow mListPopupWindow;
143
144    /**
145     * Listener for the dismissal of the popup/alert.
146     */
147    private PopupWindow.OnDismissListener mOnDismissListener;
148
149    /**
150     * Flag whether a default activity currently being selected.
151     */
152    private boolean mIsSelectingDefaultActivity;
153
154    /**
155     * The count of activities in the popup.
156     */
157    private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT;
158
159    /**
160     * Flag whether this view is attached to a window.
161     */
162    private boolean mIsAttachedToWindow;
163
164    /**
165     * Create a new instance.
166     *
167     * @param context The application environment.
168     */
169    public ActivityChooserView(Context context) {
170        this(context, null);
171    }
172
173    /**
174     * Create a new instance.
175     *
176     * @param context The application environment.
177     * @param attrs A collection of attributes.
178     */
179    public ActivityChooserView(Context context, AttributeSet attrs) {
180        this(context, attrs, 0);
181    }
182
183    /**
184     * Create a new instance.
185     *
186     * @param context The application environment.
187     * @param attrs A collection of attributes.
188     * @param defStyle The default style to apply to this view.
189     */
190    public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) {
191        super(context, attrs, defStyle);
192
193        TypedArray attributesArray = context.obtainStyledAttributes(attrs,
194                R.styleable.ActivityChooserView, defStyle, 0);
195
196        mInitialActivityCount = attributesArray.getInt(
197                R.styleable.ActivityChooserView_initialActivityCount,
198                ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT);
199
200        Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable(
201                R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable);
202
203        attributesArray.recycle();
204
205        LayoutInflater inflater = LayoutInflater.from(mContext);
206        inflater.inflate(R.layout.activity_chooser_view, this, true);
207
208        mCallbacks = new Callbacks();
209
210        mActivityChooserContent = (LinearLayout) findViewById(R.id.activity_chooser_view_content);
211        mActivityChooserContentBackground = mActivityChooserContent.getBackground();
212
213        mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
214        mDefaultActivityButton.setOnClickListener(mCallbacks);
215        mDefaultActivityButton.setOnLongClickListener(mCallbacks);
216        mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
217
218        mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.expand_activities_button);
219        mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
220        mExpandActivityOverflowButtonImage =
221            (ImageView) mExpandActivityOverflowButton.findViewById(R.id.image);
222        mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
223
224        mAdapter = new ActivityChooserViewAdapter();
225        mAdapter.registerDataSetObserver(new DataSetObserver() {
226            @Override
227            public void onChanged() {
228                super.onChanged();
229                updateAppearance();
230            }
231        });
232
233        Resources resources = context.getResources();
234        mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2,
235              resources.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth));
236    }
237
238    /**
239     * {@inheritDoc}
240     */
241    public void setActivityChooserModel(ActivityChooserModel dataModel) {
242        mAdapter.setDataModel(dataModel);
243        if (isShowingPopup()) {
244            dismissPopup();
245            showPopup();
246        }
247    }
248
249    /**
250     * Sets the background for the button that expands the activity
251     * overflow list.
252     *
253     * <strong>Note:</strong> Clients would like to set this drawable
254     * as a clue about the action the chosen activity will perform. For
255     * example, if share activity is to be chosen the drawable should
256     * give a clue that sharing is to be performed.
257     *
258     * @param drawable The drawable.
259     */
260    public void setExpandActivityOverflowButtonDrawable(Drawable drawable) {
261        mExpandActivityOverflowButtonImage.setImageDrawable(drawable);
262    }
263
264    /**
265     * Shows the popup window with activities.
266     *
267     * @return True if the popup was shown, false if already showing.
268     */
269    public boolean showPopup() {
270        if (isShowingPopup() || !mIsAttachedToWindow) {
271            return false;
272        }
273        mIsSelectingDefaultActivity = false;
274        showPopupUnchecked(mInitialActivityCount);
275        return true;
276    }
277
278    /**
279     * Shows the popup no matter if it was already showing.
280     *
281     * @param maxActivityCount The max number of activities to display.
282     */
283    private void showPopupUnchecked(int maxActivityCount) {
284        if (mAdapter.getDataModel() == null) {
285            throw new IllegalStateException("No data model. Did you call #setDataModel?");
286        }
287
288        getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
289
290        mAdapter.setMaxActivityCount(maxActivityCount);
291
292        final int activityCount = mAdapter.getActivityCount();
293        if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED
294                && activityCount > maxActivityCount + 1) {
295            mAdapter.setShowFooterView(true);
296        } else {
297            mAdapter.setShowFooterView(false);
298        }
299
300        ListPopupWindow popupWindow = getListPopupWindow();
301        if (!popupWindow.isShowing()) {
302            if (mIsSelectingDefaultActivity) {
303                mAdapter.setShowDefaultActivity(true);
304            } else {
305                mAdapter.setShowDefaultActivity(false);
306            }
307            final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth);
308            popupWindow.setContentWidth(contentWidth);
309            popupWindow.show();
310        }
311    }
312
313    /**
314     * Dismisses the popup window with activities.
315     *
316     * @return True if dismissed, false if already dismissed.
317     */
318    public boolean dismissPopup() {
319        if (isShowingPopup()) {
320            getListPopupWindow().dismiss();
321            ViewTreeObserver viewTreeObserver = getViewTreeObserver();
322            if (viewTreeObserver.isAlive()) {
323                viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
324            }
325        }
326        return true;
327    }
328
329    /**
330     * Gets whether the popup window with activities is shown.
331     *
332     * @return True if the popup is shown.
333     */
334    public boolean isShowingPopup() {
335        return getListPopupWindow().isShowing();
336    }
337
338    @Override
339    protected void onAttachedToWindow() {
340        super.onAttachedToWindow();
341        ActivityChooserModel dataModel = mAdapter.getDataModel();
342        if (dataModel != null) {
343            dataModel.registerObserver(mModelDataSetOberver);
344        }
345        mIsAttachedToWindow = true;
346    }
347
348    @Override
349    protected void onDetachedFromWindow() {
350        super.onDetachedFromWindow();
351        ActivityChooserModel dataModel = mAdapter.getDataModel();
352        if (dataModel != null) {
353            dataModel.unregisterObserver(mModelDataSetOberver);
354        }
355        ViewTreeObserver viewTreeObserver = getViewTreeObserver();
356        if (viewTreeObserver.isAlive()) {
357            viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
358        }
359        mIsAttachedToWindow = false;
360    }
361
362    @Override
363    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
364        View child = mActivityChooserContent;
365        // If the default action is not visible we want to be as tall as the
366        // ActionBar so if this widget is used in the latter it will look as
367        // a normal action button.
368        if (mDefaultActivityButton.getVisibility() != VISIBLE) {
369            heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
370                    MeasureSpec.EXACTLY);
371        }
372        measureChild(child, widthMeasureSpec, heightMeasureSpec);
373        setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight());
374    }
375
376    @Override
377    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
378        mActivityChooserContent.layout(0, 0, right - left, bottom - top);
379        if (getListPopupWindow().isShowing()) {
380            showPopupUnchecked(mAdapter.getMaxActivityCount());
381        } else {
382            dismissPopup();
383        }
384    }
385
386    public ActivityChooserModel getDataModel() {
387        return mAdapter.getDataModel();
388    }
389
390    /**
391     * Sets a listener to receive a callback when the popup is dismissed.
392     *
393     * @param listener The listener to be notified.
394     */
395    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
396        mOnDismissListener = listener;
397    }
398
399    /**
400     * Sets the initial count of items shown in the activities popup
401     * i.e. the items before the popup is expanded. This is an upper
402     * bound since it is not guaranteed that such number of intent
403     * handlers exist.
404     *
405     * @param itemCount The initial popup item count.
406     */
407    public void setInitialActivityCount(int itemCount) {
408        mInitialActivityCount = itemCount;
409    }
410
411    /**
412     * Gets the list popup window which is lazily initialized.
413     *
414     * @return The popup.
415     */
416    private ListPopupWindow getListPopupWindow() {
417        if (mListPopupWindow == null) {
418            mListPopupWindow = new ListPopupWindow(getContext());
419            mListPopupWindow.setAdapter(mAdapter);
420            mListPopupWindow.setAnchorView(ActivityChooserView.this);
421            mListPopupWindow.setModal(true);
422            mListPopupWindow.setOnItemClickListener(mCallbacks);
423            mListPopupWindow.setOnDismissListener(mCallbacks);
424        }
425        return mListPopupWindow;
426    }
427
428    /**
429     * Updates the buttons state.
430     */
431    private void updateAppearance() {
432        // Expand overflow button.
433        if (mAdapter.getCount() > 0) {
434            mExpandActivityOverflowButton.setEnabled(true);
435        } else {
436            mExpandActivityOverflowButton.setEnabled(false);
437        }
438        // Default activity button.
439        final int activityCount = mAdapter.getActivityCount();
440        final int historySize = mAdapter.getHistorySize();
441        if (activityCount > 0 && historySize > 0) {
442            mDefaultActivityButton.setVisibility(VISIBLE);
443            ResolveInfo activity = mAdapter.getDefaultActivity();
444            PackageManager packageManager = mContext.getPackageManager();
445            mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager));
446        } else {
447            mDefaultActivityButton.setVisibility(View.GONE);
448        }
449        // Activity chooser content.
450        if (mDefaultActivityButton.getVisibility() == VISIBLE) {
451            mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground);
452        } else {
453            mActivityChooserContent.setBackgroundDrawable(null);
454        }
455    }
456
457    /**
458     * Interface implementation to avoid publishing them in the APIs.
459     */
460    private class Callbacks implements AdapterView.OnItemClickListener,
461            View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener {
462
463        // AdapterView#OnItemClickListener
464        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
465            ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter();
466            final int itemViewType = adapter.getItemViewType(position);
467            switch (itemViewType) {
468                case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: {
469                    showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED);
470                } break;
471                case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: {
472                    dismissPopup();
473                    if (mIsSelectingDefaultActivity) {
474                        // The item at position zero is the default already.
475                        if (position > 0) {
476                            mAdapter.getDataModel().setDefaultActivity(position);
477                        }
478                    } else {
479                        // The first item in the model is default action => adjust index
480                        Intent launchIntent  = mAdapter.getDataModel().chooseActivity(position + 1);
481                        if (launchIntent != null) {
482                            mContext.startActivity(launchIntent);
483                        }
484                    }
485                } break;
486                default:
487                    throw new IllegalArgumentException();
488            }
489        }
490
491        // View.OnClickListener
492        public void onClick(View view) {
493            if (view == mDefaultActivityButton) {
494                dismissPopup();
495                ResolveInfo defaultActivity = mAdapter.getDefaultActivity();
496                final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity);
497                Intent launchIntent = mAdapter.getDataModel().chooseActivity(index);
498                if (launchIntent != null) {
499                    mContext.startActivity(launchIntent);
500                }
501            } else if (view == mExpandActivityOverflowButton) {
502                mIsSelectingDefaultActivity = false;
503                showPopupUnchecked(mInitialActivityCount);
504            } else {
505                throw new IllegalArgumentException();
506            }
507        }
508
509        // OnLongClickListener#onLongClick
510        @Override
511        public boolean onLongClick(View view) {
512            if (view == mDefaultActivityButton) {
513                if (mAdapter.getCount() > 0) {
514                    mIsSelectingDefaultActivity = true;
515                    showPopupUnchecked(mInitialActivityCount);
516                }
517            } else {
518                throw new IllegalArgumentException();
519            }
520            return true;
521        }
522
523        // PopUpWindow.OnDismissListener#onDismiss
524        public void onDismiss() {
525            notifyOnDismissListener();
526        }
527
528        private void notifyOnDismissListener() {
529            if (mOnDismissListener != null) {
530                mOnDismissListener.onDismiss();
531            }
532        }
533    }
534
535    /**
536     * Adapter for backing the list of activities shown in the popup.
537     */
538    private class ActivityChooserViewAdapter extends BaseAdapter {
539
540        public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE;
541
542        public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4;
543
544        private static final int ITEM_VIEW_TYPE_ACTIVITY = 0;
545
546        private static final int ITEM_VIEW_TYPE_FOOTER = 1;
547
548        private static final int ITEM_VIEW_TYPE_COUNT = 3;
549
550        private ActivityChooserModel mDataModel;
551
552        private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT;
553
554        private boolean mShowDefaultActivity;
555
556        private boolean mShowFooterView;
557
558        public void setDataModel(ActivityChooserModel dataModel) {
559            ActivityChooserModel oldDataModel = mAdapter.getDataModel();
560            if (oldDataModel != null && isShown()) {
561                oldDataModel.unregisterObserver(mModelDataSetOberver);
562            }
563            mDataModel = dataModel;
564            if (dataModel != null && isShown()) {
565                dataModel.registerObserver(mModelDataSetOberver);
566            }
567            notifyDataSetChanged();
568        }
569
570        @Override
571        public int getItemViewType(int position) {
572            if (mShowFooterView && position == getCount() - 1) {
573                return ITEM_VIEW_TYPE_FOOTER;
574            } else {
575                return ITEM_VIEW_TYPE_ACTIVITY;
576            }
577        }
578
579        @Override
580        public int getViewTypeCount() {
581            return ITEM_VIEW_TYPE_COUNT;
582        }
583
584        public int getCount() {
585            int count = 0;
586            int activityCount = mDataModel.getActivityCount();
587            if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) {
588                activityCount--;
589            }
590            count = Math.min(activityCount, mMaxActivityCount);
591            if (mShowFooterView) {
592                count++;
593            }
594            return count;
595        }
596
597        public Object getItem(int position) {
598            final int itemViewType = getItemViewType(position);
599            switch (itemViewType) {
600                case ITEM_VIEW_TYPE_FOOTER:
601                    return null;
602                case ITEM_VIEW_TYPE_ACTIVITY:
603                    if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) {
604                        position++;
605                    }
606                    return mDataModel.getActivity(position);
607                default:
608                    throw new IllegalArgumentException();
609            }
610        }
611
612        public long getItemId(int position) {
613            return position;
614        }
615
616        public View getView(int position, View convertView, ViewGroup parent) {
617            final int itemViewType = getItemViewType(position);
618            switch (itemViewType) {
619                case ITEM_VIEW_TYPE_FOOTER:
620                    if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) {
621                        convertView = LayoutInflater.from(getContext()).inflate(
622                                R.layout.activity_chooser_view_list_item, parent, false);
623                        convertView.setId(ITEM_VIEW_TYPE_FOOTER);
624                        TextView titleView = (TextView) convertView.findViewById(R.id.title);
625                        titleView.setText(mContext.getString(
626                                R.string.activity_chooser_view_see_all));
627                    }
628                    return convertView;
629                case ITEM_VIEW_TYPE_ACTIVITY:
630                    if (convertView == null || convertView.getId() != R.id.list_item) {
631                        convertView = LayoutInflater.from(getContext()).inflate(
632                                R.layout.activity_chooser_view_list_item, parent, false);
633                    }
634                    PackageManager packageManager = mContext.getPackageManager();
635                    // Set the icon
636                    ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
637                    ResolveInfo activity = (ResolveInfo) getItem(position);
638                    iconView.setImageDrawable(activity.loadIcon(packageManager));
639                    // Set the title.
640                    TextView titleView = (TextView) convertView.findViewById(R.id.title);
641                    titleView.setText(activity.loadLabel(packageManager));
642                    // Highlight the default.
643                    if (mShowDefaultActivity && position == 0) {
644                        convertView.setActivated(true);
645                    } else {
646                        convertView.setActivated(false);
647                    }
648                    return convertView;
649                default:
650                    throw new IllegalArgumentException();
651            }
652        }
653
654        public int measureContentWidth() {
655            // The user may have specified some of the target not to be shown but we
656            // want to measure all of them since after expansion they should fit.
657            final int oldMaxActivityCount = mMaxActivityCount;
658            mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED;
659
660            int contentWidth = 0;
661            View itemView = null;
662
663            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
664            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
665            final int count = getCount();
666
667            for (int i = 0; i < count; i++) {
668                itemView = getView(i, itemView, null);
669                itemView.measure(widthMeasureSpec, heightMeasureSpec);
670                contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth());
671            }
672
673            mMaxActivityCount = oldMaxActivityCount;
674
675            return contentWidth;
676        }
677
678        public void setMaxActivityCount(int maxActivityCount) {
679            if (mMaxActivityCount != maxActivityCount) {
680                mMaxActivityCount = maxActivityCount;
681                notifyDataSetChanged();
682            }
683        }
684
685        public ResolveInfo getDefaultActivity() {
686            return mDataModel.getDefaultActivity();
687        }
688
689        public void setShowFooterView(boolean showFooterView) {
690            if (mShowFooterView != showFooterView) {
691                mShowFooterView = showFooterView;
692                notifyDataSetChanged();
693            }
694        }
695
696        public int getActivityCount() {
697            return mDataModel.getActivityCount();
698        }
699
700        public int getHistorySize() {
701            return mDataModel.getHistorySize();
702        }
703
704        public int getMaxActivityCount() {
705            return mMaxActivityCount;
706        }
707
708        public ActivityChooserModel getDataModel() {
709            return mDataModel;
710        }
711
712        public void setShowDefaultActivity(boolean showDefaultActivity) {
713            if (mShowDefaultActivity != showDefaultActivity) {
714                mShowDefaultActivity = showDefaultActivity;
715                notifyDataSetChanged();
716            }
717        }
718    }
719}
720