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