ActionBarActivityDelegateBase.java revision 56fd50144df518461398a9b3397ee4842b346708
1/*
2 * Copyright (C) 2013 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.support.v7.app;
18
19import android.content.Context;
20import android.content.res.Configuration;
21import android.content.res.TypedArray;
22import android.graphics.drawable.Drawable;
23import android.os.Bundle;
24import android.support.v4.app.ActionBarDrawerToggle;
25import android.support.v4.view.WindowCompat;
26import android.support.v7.appcompat.R;
27import android.support.v7.internal.view.menu.ListMenuPresenter;
28import android.support.v7.internal.view.menu.MenuBuilder;
29import android.support.v7.internal.view.menu.MenuPresenter;
30import android.support.v7.internal.view.menu.MenuView;
31import android.support.v7.internal.view.menu.MenuWrapperFactory;
32import android.support.v7.internal.widget.ActionBarContainer;
33import android.support.v7.internal.widget.ActionBarContextView;
34import android.support.v7.internal.widget.ActionBarView;
35import android.support.v7.internal.widget.ProgressBarICS;
36import android.support.v7.view.ActionMode;
37import android.util.AttributeSet;
38import android.util.DisplayMetrics;
39import android.util.TypedValue;
40import android.view.Menu;
41import android.view.MenuItem;
42import android.view.View;
43import android.view.ViewGroup;
44import android.view.Window;
45import android.view.WindowManager;
46import android.widget.FrameLayout;
47
48class ActionBarActivityDelegateBase extends ActionBarActivityDelegate implements
49        MenuPresenter.Callback, MenuBuilder.Callback {
50    private static final String TAG = "ActionBarActivityDelegateBase";
51
52    private static final int[] ACTION_BAR_DRAWABLE_TOGGLE_ATTRS = new int[] {
53            R.attr.homeAsUpIndicator
54    };
55
56    private ActionBarView mActionBarView;
57    private ListMenuPresenter mListMenuPresenter;
58    private MenuBuilder mMenu;
59
60    private ActionMode mActionMode;
61
62    // true if we have installed a window sub-decor layout.
63    private boolean mSubDecorInstalled;
64
65    private CharSequence mTitleToSet;
66
67    // Used to keep track of Progress Bar Window features
68    private boolean mFeatureProgress, mFeatureIndeterminateProgress;
69
70    // Used for emulating PanelFeatureState
71    private boolean mClosingActionMenu;
72    private boolean mPanelIsPrepared;
73    private boolean mPanelRefreshContent;
74    private Bundle mPanelFrozenActionViewState;
75
76    ActionBarActivityDelegateBase(ActionBarActivity activity) {
77        super(activity);
78    }
79
80    @Override
81    public ActionBar createSupportActionBar() {
82        ensureSubDecor();
83        return new ActionBarImplBase(mActivity, mActivity);
84    }
85
86    @Override
87    public void onConfigurationChanged(Configuration newConfig) {
88        // If this is called before sub-decor is installed, ActionBar will not
89        // be properly initialized.
90        if (mHasActionBar && mSubDecorInstalled) {
91            // Note: The action bar will need to access
92            // view changes from superclass.
93            ActionBarImplBase actionBar = (ActionBarImplBase) getSupportActionBar();
94            actionBar.onConfigurationChanged(newConfig);
95        }
96    }
97
98    @Override
99    public void onStop() {
100        ActionBarImplBase ab = (ActionBarImplBase) getSupportActionBar();
101        if (ab != null) {
102            ab.setShowHideAnimationEnabled(false);
103        }
104    }
105
106    @Override
107    public void onPostResume() {
108        ActionBarImplBase ab = (ActionBarImplBase) getSupportActionBar();
109        if (ab != null) {
110            ab.setShowHideAnimationEnabled(true);
111        }
112    }
113
114    @Override
115    public void setContentView(View v) {
116        ensureSubDecor();
117        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
118        contentParent.removeAllViews();
119        contentParent.addView(v);
120        mActivity.onSupportContentChanged();
121    }
122
123    @Override
124    public void setContentView(int resId) {
125        ensureSubDecor();
126        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
127        contentParent.removeAllViews();
128        mActivity.getLayoutInflater().inflate(resId, contentParent);
129        mActivity.onSupportContentChanged();
130    }
131
132    @Override
133    public void setContentView(View v, ViewGroup.LayoutParams lp) {
134        ensureSubDecor();
135        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
136        contentParent.removeAllViews();
137        contentParent.addView(v, lp);
138        mActivity.onSupportContentChanged();
139    }
140
141    @Override
142    public void addContentView(View v, ViewGroup.LayoutParams lp) {
143        ensureSubDecor();
144        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
145        contentParent.addView(v, lp);
146        mActivity.onSupportContentChanged();
147    }
148
149    @Override
150    public void onContentChanged() {
151        // Ignore all calls to this method as we call onSupportContentChanged manually above
152    }
153
154    final void ensureSubDecor() {
155        if (!mSubDecorInstalled) {
156            if (mHasActionBar) {
157                if (mOverlayActionBar) {
158                    mActivity.superSetContentView(R.layout.abc_action_bar_decor_overlay);
159                } else {
160                    mActivity.superSetContentView(R.layout.abc_action_bar_decor);
161                }
162                mActionBarView = (ActionBarView) mActivity.findViewById(R.id.action_bar);
163                mActionBarView.setWindowCallback(mActivity);
164
165                /**
166                 * Progress Bars
167                 */
168                if (mFeatureProgress) {
169                    mActionBarView.initProgress();
170                }
171                if (mFeatureIndeterminateProgress) {
172                    mActionBarView.initIndeterminateProgress();
173                }
174
175                /**
176                 * Split Action Bar
177                 */
178                boolean splitWhenNarrow = UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW
179                        .equals(getUiOptionsFromMetadata());
180                boolean splitActionBar;
181
182                if (splitWhenNarrow) {
183                    splitActionBar = mActivity.getResources()
184                            .getBoolean(R.bool.abc_split_action_bar_is_narrow);
185                } else {
186                    TypedArray a = mActivity.obtainStyledAttributes(R.styleable.ActionBarWindow);
187                    splitActionBar = a
188                            .getBoolean(R.styleable.ActionBarWindow_windowSplitActionBar, false);
189                    a.recycle();
190                }
191
192                final ActionBarContainer splitView = (ActionBarContainer) mActivity.findViewById(
193                        R.id.split_action_bar);
194                if (splitView != null) {
195                    mActionBarView.setSplitView(splitView);
196                    mActionBarView.setSplitActionBar(splitActionBar);
197                    mActionBarView.setSplitWhenNarrow(splitWhenNarrow);
198
199                    final ActionBarContextView cab = (ActionBarContextView) mActivity.findViewById(
200                            R.id.action_context_bar);
201                    cab.setSplitView(splitView);
202                    cab.setSplitActionBar(splitActionBar);
203                    cab.setSplitWhenNarrow(splitWhenNarrow);
204                }
205            } else {
206                mActivity.superSetContentView(R.layout.abc_simple_decor);
207            }
208
209            // Change our content FrameLayout to use the android.R.id.content id.
210            // Useful for fragments.
211            View content = mActivity.findViewById(android.R.id.content);
212            content.setId(View.NO_ID);
213            View abcContent = mActivity.findViewById(R.id.action_bar_activity_content);
214            abcContent.setId(android.R.id.content);
215
216            // A title was set before we've install the decor so set it now.
217            if (mTitleToSet != null) {
218                mActionBarView.setWindowTitle(mTitleToSet);
219                mTitleToSet = null;
220            }
221
222            applyFixedSizeWindow();
223
224            mSubDecorInstalled = true;
225
226            // Post supportInvalidateOptionsMenu() so that the menu is invalidated post-onCreate()
227            mActivity.getWindow().getDecorView().post(new Runnable() {
228                @Override
229                public void run() {
230                    supportInvalidateOptionsMenu();
231                }
232            });
233        }
234    }
235
236    private void applyFixedSizeWindow() {
237        TypedArray a = mActivity.obtainStyledAttributes(R.styleable.ActionBarWindow);
238
239        TypedValue mFixedWidthMajor = null;
240        TypedValue mFixedWidthMinor = null;
241        TypedValue mFixedHeightMajor = null;
242        TypedValue mFixedHeightMinor = null;
243
244        if (a.hasValue(R.styleable.ActionBarWindow_windowFixedWidthMajor)) {
245            if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
246            a.getValue(R.styleable.ActionBarWindow_windowFixedWidthMajor, mFixedWidthMajor);
247        }
248        if (a.hasValue(R.styleable.ActionBarWindow_windowFixedWidthMinor)) {
249            if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
250            a.getValue(R.styleable.ActionBarWindow_windowFixedWidthMinor, mFixedWidthMinor);
251        }
252        if (a.hasValue(R.styleable.ActionBarWindow_windowFixedHeightMajor)) {
253            if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
254            a.getValue(R.styleable.ActionBarWindow_windowFixedHeightMajor, mFixedHeightMajor);
255        }
256        if (a.hasValue(R.styleable.ActionBarWindow_windowFixedHeightMinor)) {
257            if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
258            a.getValue(R.styleable.ActionBarWindow_windowFixedHeightMinor, mFixedHeightMinor);
259        }
260
261        final DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
262        final boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
263        int w = ViewGroup.LayoutParams.MATCH_PARENT;
264        int h = ViewGroup.LayoutParams.MATCH_PARENT;
265
266        final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
267        if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
268            if (tvw.type == TypedValue.TYPE_DIMENSION) {
269                w = (int) tvw.getDimension(metrics);
270            } else if (tvw.type == TypedValue.TYPE_FRACTION) {
271                w = (int) tvw.getFraction(metrics.widthPixels, metrics.widthPixels);
272            }
273        }
274
275        final TypedValue tvh = isPortrait ? mFixedHeightMajor : mFixedHeightMinor;
276        if (tvh != null && tvh.type != TypedValue.TYPE_NULL) {
277            if (tvh.type == TypedValue.TYPE_DIMENSION) {
278                h = (int) tvh.getDimension(metrics);
279            } else if (tvh.type == TypedValue.TYPE_FRACTION) {
280                h = (int) tvh.getFraction(metrics.heightPixels, metrics.heightPixels);
281            }
282        }
283
284        if (w != ViewGroup.LayoutParams.MATCH_PARENT || h != ViewGroup.LayoutParams.MATCH_PARENT) {
285            mActivity.getWindow().setLayout(w, h);
286        }
287
288        a.recycle();
289    }
290
291    @Override
292    public boolean supportRequestWindowFeature(int featureId) {
293        switch (featureId) {
294            case WindowCompat.FEATURE_ACTION_BAR:
295                mHasActionBar = true;
296                return true;
297            case WindowCompat.FEATURE_ACTION_BAR_OVERLAY:
298                mOverlayActionBar = true;
299                return true;
300            case Window.FEATURE_PROGRESS:
301                mFeatureProgress = true;
302                return true;
303            case Window.FEATURE_INDETERMINATE_PROGRESS:
304                mFeatureIndeterminateProgress = true;
305                return true;
306            default:
307                return mActivity.requestWindowFeature(featureId);
308        }
309    }
310
311    @Override
312    public void onTitleChanged(CharSequence title) {
313        if (mActionBarView != null) {
314            mActionBarView.setWindowTitle(title);
315        } else {
316            mTitleToSet = title;
317        }
318    }
319
320    @Override
321    public View onCreatePanelView(int featureId) {
322        View createdPanelView = null;
323
324        if (featureId == Window.FEATURE_OPTIONS_PANEL && preparePanel()) {
325            createdPanelView = (View) getListMenuView(mActivity, this);
326        }
327
328        return createdPanelView;
329    }
330
331    @Override
332    public boolean onCreatePanelMenu(int featureId, Menu menu) {
333        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
334            return mActivity.superOnCreatePanelMenu(featureId, menu);
335        }
336        return false;
337    }
338
339    @Override
340    public boolean onPreparePanel(int featureId, View view, Menu menu) {
341        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
342            return mActivity.superOnPreparePanel(featureId, view, menu);
343        }
344        return false;
345    }
346
347    @Override
348    public boolean onMenuItemSelected(int featureId, MenuItem item) {
349        if (featureId == Window.FEATURE_OPTIONS_PANEL) {
350            item = MenuWrapperFactory.createMenuItemWrapper(item);
351        }
352        return mActivity.superOnMenuItemSelected(featureId, item);
353    }
354
355    @Override
356    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
357        return mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
358    }
359
360    @Override
361    public void onMenuModeChange(MenuBuilder menu) {
362        reopenMenu(menu, true);
363    }
364
365    @Override
366    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
367        if (mClosingActionMenu) {
368            return;
369        }
370        mClosingActionMenu = true;
371        mActivity.closeOptionsMenu();
372        mActionBarView.dismissPopupMenus();
373        mClosingActionMenu = false;
374    }
375
376    @Override
377    public boolean onOpenSubMenu(MenuBuilder subMenu) {
378        return false;
379    }
380
381    @Override
382    public ActionMode startSupportActionMode(ActionMode.Callback callback) {
383        if (callback == null) {
384            throw new IllegalArgumentException("ActionMode callback can not be null.");
385        }
386
387        if (mActionMode != null) {
388            mActionMode.finish();
389        }
390
391        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
392
393        ActionBarImplBase ab = (ActionBarImplBase) getSupportActionBar();
394        if (ab != null) {
395            mActionMode = ab.startActionMode(wrappedCallback);
396        }
397
398        if (mActionMode != null) {
399            mActivity.onSupportActionModeStarted(mActionMode);
400        }
401        return mActionMode;
402    }
403
404    @Override
405    public void supportInvalidateOptionsMenu() {
406        if (mMenu != null) {
407            Bundle savedActionViewStates = new Bundle();
408            mMenu.saveActionViewStates(savedActionViewStates);
409            if (savedActionViewStates.size() > 0) {
410                mPanelFrozenActionViewState = savedActionViewStates;
411            }
412            // This will be started again when the panel is prepared.
413            mMenu.stopDispatchingItemsChanged();
414            mMenu.clear();
415        }
416        mPanelRefreshContent = true;
417
418        // Prepare the options panel if we have an action bar
419        if (mActionBarView != null) {
420            mPanelIsPrepared = false;
421            preparePanel();
422        }
423    }
424
425    private void reopenMenu(MenuBuilder menu, boolean toggleMenuMode) {
426        if (mActionBarView != null && mActionBarView.isOverflowReserved()) {
427            if (!mActionBarView.isOverflowMenuShowing() || !toggleMenuMode) {
428                if (mActionBarView.getVisibility() == View.VISIBLE) {
429                    mActionBarView.showOverflowMenu();
430                }
431            } else {
432                mActionBarView.hideOverflowMenu();
433            }
434            return;
435        }
436
437        menu.close();
438    }
439
440    private MenuView getListMenuView(Context context, MenuPresenter.Callback cb) {
441        if (mMenu == null) {
442            return null;
443        }
444
445        if (mListMenuPresenter == null) {
446            TypedArray a = context.obtainStyledAttributes(R.styleable.Theme);
447            final int listPresenterTheme = a.getResourceId(
448                    R.styleable.Theme_panelMenuListTheme,
449                    R.style.Theme_AppCompat_CompactMenu);
450            a.recycle();
451
452            mListMenuPresenter = new ListMenuPresenter(
453                    R.layout.abc_list_menu_item_layout, listPresenterTheme);
454            mListMenuPresenter.setCallback(cb);
455            mMenu.addMenuPresenter(mListMenuPresenter);
456        } else {
457            // Make sure we update the ListView
458            mListMenuPresenter.updateMenuView(false);
459        }
460
461        return mListMenuPresenter.getMenuView(new FrameLayout(context));
462    }
463
464    @Override
465    public boolean onBackPressed() {
466        // Back cancels action modes first.
467        if (mActionMode != null) {
468            mActionMode.finish();
469            return true;
470        }
471
472        // Next collapse any expanded action views.
473        if (mActionBarView != null && mActionBarView.hasExpandedActionView()) {
474            mActionBarView.collapseActionView();
475            return true;
476        }
477
478        return false;
479    }
480
481    @Override
482    void setSupportProgressBarVisibility(boolean visible) {
483        updateProgressBars(visible ? Window.PROGRESS_VISIBILITY_ON :
484                Window.PROGRESS_VISIBILITY_OFF);
485    }
486
487    @Override
488    void setSupportProgressBarIndeterminateVisibility(boolean visible) {
489        updateProgressBars(visible ? Window.PROGRESS_VISIBILITY_ON :
490                Window.PROGRESS_VISIBILITY_OFF);
491    }
492
493    @Override
494    void setSupportProgressBarIndeterminate(boolean indeterminate) {
495        updateProgressBars(indeterminate ? Window.PROGRESS_INDETERMINATE_ON
496                : Window.PROGRESS_INDETERMINATE_OFF);
497    }
498
499    @Override
500    void setSupportProgress(int progress) {
501        updateProgressBars(Window.PROGRESS_START + progress);
502    }
503
504    @Override
505    ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
506        return new ActionBarDrawableToggleImpl();
507    }
508
509    /**
510     * Progress Bar function. Mostly extracted from PhoneWindow.java
511     */
512    private void updateProgressBars(int value) {
513        ProgressBarICS circularProgressBar = getCircularProgressBar();
514        ProgressBarICS horizontalProgressBar = getHorizontalProgressBar();
515
516        if (value == Window.PROGRESS_VISIBILITY_ON) {
517            if (mFeatureProgress) {
518                int level = horizontalProgressBar.getProgress();
519                int visibility = (horizontalProgressBar.isIndeterminate() || level < 10000) ?
520                        View.VISIBLE : View.INVISIBLE;
521                horizontalProgressBar.setVisibility(visibility);
522            }
523            if (mFeatureIndeterminateProgress) {
524                circularProgressBar.setVisibility(View.VISIBLE);
525            }
526        } else if (value == Window.PROGRESS_VISIBILITY_OFF) {
527            if (mFeatureProgress) {
528                horizontalProgressBar.setVisibility(View.GONE);
529            }
530            if (mFeatureIndeterminateProgress) {
531                circularProgressBar.setVisibility(View.GONE);
532            }
533        } else if (value == Window.PROGRESS_INDETERMINATE_ON) {
534            horizontalProgressBar.setIndeterminate(true);
535        } else if (value == Window.PROGRESS_INDETERMINATE_OFF) {
536            horizontalProgressBar.setIndeterminate(false);
537        } else if (Window.PROGRESS_START <= value && value <= Window.PROGRESS_END) {
538            // We want to set the progress value before testing for visibility
539            // so that when the progress bar becomes visible again, it has the
540            // correct level.
541            horizontalProgressBar.setProgress(value - Window.PROGRESS_START);
542
543            if (value < Window.PROGRESS_END) {
544                showProgressBars(horizontalProgressBar, circularProgressBar);
545            } else {
546                hideProgressBars(horizontalProgressBar, circularProgressBar);
547            }
548        }
549    }
550
551    private void showProgressBars(ProgressBarICS horizontalProgressBar,
552            ProgressBarICS spinnyProgressBar) {
553        if (mFeatureIndeterminateProgress && spinnyProgressBar.getVisibility() == View.INVISIBLE) {
554            spinnyProgressBar.setVisibility(View.VISIBLE);
555        }
556        // Only show the progress bars if the primary progress is not complete
557        if (mFeatureProgress && horizontalProgressBar.getProgress() < 10000) {
558            horizontalProgressBar.setVisibility(View.VISIBLE);
559        }
560    }
561
562    private void hideProgressBars(ProgressBarICS horizontalProgressBar,
563            ProgressBarICS spinnyProgressBar) {
564        if (mFeatureIndeterminateProgress && spinnyProgressBar.getVisibility() == View.VISIBLE) {
565            spinnyProgressBar.setVisibility(View.INVISIBLE);
566        }
567        if (mFeatureProgress && horizontalProgressBar.getVisibility() == View.VISIBLE) {
568            horizontalProgressBar.setVisibility(View.INVISIBLE);
569        }
570    }
571
572    private ProgressBarICS getCircularProgressBar() {
573        ProgressBarICS pb = (ProgressBarICS) mActionBarView.findViewById(R.id.progress_circular);
574        if (pb != null) {
575            pb.setVisibility(View.INVISIBLE);
576        }
577        return pb;
578    }
579
580    private ProgressBarICS getHorizontalProgressBar() {
581        ProgressBarICS pb = (ProgressBarICS) mActionBarView.findViewById(R.id.progress_horizontal);
582        if (pb != null) {
583            pb.setVisibility(View.INVISIBLE);
584        }
585        return pb;
586    }
587
588    private boolean initializePanelMenu() {
589        mMenu = new MenuBuilder(getActionBarThemedContext());
590        mMenu.setCallback(this);
591        return true;
592    }
593
594    private boolean preparePanel() {
595        // Already prepared (isPrepared will be reset to false later)
596        if (mPanelIsPrepared) {
597            return true;
598        }
599
600        // Init the panel state's menu--return false if init failed
601        if (mMenu == null || mPanelRefreshContent) {
602            if (mMenu == null) {
603                if (!initializePanelMenu() || (mMenu == null)) {
604                    return false;
605                }
606            }
607
608            if (mActionBarView != null) {
609                mActionBarView.setMenu(mMenu, this);
610            }
611
612            // Creating the panel menu will involve a lot of manipulation;
613            // don't dispatch change events to presenters until we're done.
614            mMenu.stopDispatchingItemsChanged();
615
616            // Call callback, and return if it doesn't want to display menu.
617            if (!mActivity.superOnCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, mMenu)) {
618                // Ditch the menu created above
619                mMenu = null;
620
621                if (mActionBarView != null) {
622                    // Don't show it in the action bar either
623                    mActionBarView.setMenu(null, this);
624                }
625
626                return false;
627            }
628
629            mPanelRefreshContent = false;
630        }
631
632        // Preparing the panel menu can involve a lot of manipulation;
633        // don't dispatch change events to presenters until we're done.
634        mMenu.stopDispatchingItemsChanged();
635
636        // Restore action view state before we prepare. This gives apps
637        // an opportunity to override frozen/restored state in onPrepare.
638        if (mPanelFrozenActionViewState != null) {
639            mMenu.restoreActionViewStates(mPanelFrozenActionViewState);
640            mPanelFrozenActionViewState = null;
641        }
642
643        // Callback and return if the callback does not want to show the menu
644        if (!mActivity.superOnPreparePanel(Window.FEATURE_OPTIONS_PANEL, null, mMenu)) {
645            if (mActionBarView != null) {
646                // The app didn't want to show the menu for now but it still exists.
647                // Clear it out of the action bar.
648                mActionBarView.setMenu(null, this);
649            }
650            mMenu.startDispatchingItemsChanged();
651            return false;
652        }
653
654        mMenu.startDispatchingItemsChanged();
655
656        // Set other state
657        mPanelIsPrepared = true;
658
659        return true;
660    }
661
662    /**
663     * Clears out internal reference when the action mode is destroyed.
664     */
665    private class ActionModeCallbackWrapper implements ActionMode.Callback {
666        private ActionMode.Callback mWrapped;
667
668        public ActionModeCallbackWrapper(ActionMode.Callback wrapped) {
669            mWrapped = wrapped;
670        }
671
672        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
673            return mWrapped.onCreateActionMode(mode, menu);
674        }
675
676        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
677            return mWrapped.onPrepareActionMode(mode, menu);
678        }
679
680        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
681            return mWrapped.onActionItemClicked(mode, item);
682        }
683
684        public void onDestroyActionMode(ActionMode mode) {
685            mWrapped.onDestroyActionMode(mode);
686            mActivity.onSupportActionModeFinished(mode);
687            mActionMode = null;
688        }
689    }
690
691    private class ActionBarDrawableToggleImpl
692            implements ActionBarDrawerToggle.Delegate {
693
694        @Override
695        public Drawable getThemeUpIndicator() {
696            final TypedArray a = mActivity.obtainStyledAttributes(ACTION_BAR_DRAWABLE_TOGGLE_ATTRS);
697            final Drawable result = a.getDrawable(0);
698            a.recycle();
699            return result;
700        }
701
702        @Override
703        public void setActionBarUpIndicator(Drawable upDrawable, int contentDescRes) {
704            if (mActionBarView != null) {
705                mActionBarView.setHomeAsUpIndicator(upDrawable);
706            }
707        }
708
709        @Override
710        public void setActionBarDescription(int contentDescRes) {
711            // No support for setting Action Bar content description
712        }
713    }
714
715}
716