ActionBarView.java revision c29f4e52c3377924df26910cce3ff26278d1f484
1/* 2 * Copyright (C) 2010 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 com.android.internal.widget; 18 19import com.android.internal.R; 20import com.android.internal.view.menu.ActionMenuItem; 21import com.android.internal.view.menu.ActionMenuPresenter; 22import com.android.internal.view.menu.ActionMenuView; 23import com.android.internal.view.menu.MenuBuilder; 24import com.android.internal.view.menu.MenuItemImpl; 25import com.android.internal.view.menu.MenuPresenter; 26import com.android.internal.view.menu.MenuView; 27import com.android.internal.view.menu.SubMenuBuilder; 28 29import android.app.ActionBar; 30import android.app.ActionBar.OnNavigationListener; 31import android.app.Activity; 32import android.content.Context; 33import android.content.pm.ApplicationInfo; 34import android.content.pm.PackageManager; 35import android.content.pm.PackageManager.NameNotFoundException; 36import android.content.res.Resources; 37import android.content.res.TypedArray; 38import android.graphics.drawable.Drawable; 39import android.os.Parcel; 40import android.os.Parcelable; 41import android.text.TextUtils; 42import android.util.AttributeSet; 43import android.util.DisplayMetrics; 44import android.util.Log; 45import android.view.Gravity; 46import android.view.LayoutInflater; 47import android.view.Menu; 48import android.view.MenuItem; 49import android.view.View; 50import android.view.ViewGroup; 51import android.view.ViewParent; 52import android.view.Window; 53import android.widget.AdapterView; 54import android.widget.FrameLayout; 55import android.widget.ImageView; 56import android.widget.LinearLayout; 57import android.widget.ProgressBar; 58import android.widget.Spinner; 59import android.widget.SpinnerAdapter; 60import android.widget.TextView; 61 62/** 63 * @hide 64 */ 65public class ActionBarView extends AbsActionBarView { 66 private static final String TAG = "ActionBarView"; 67 68 /** 69 * Display options applied by default 70 */ 71 public static final int DISPLAY_DEFAULT = 0; 72 73 /** 74 * Display options that require re-layout as opposed to a simple invalidate 75 */ 76 private static final int DISPLAY_RELAYOUT_MASK = 77 ActionBar.DISPLAY_SHOW_HOME | 78 ActionBar.DISPLAY_USE_LOGO | 79 ActionBar.DISPLAY_HOME_AS_UP | 80 ActionBar.DISPLAY_SHOW_CUSTOM | 81 ActionBar.DISPLAY_SHOW_TITLE; 82 83 private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL; 84 85 private int mContentHeight; 86 87 private int mNavigationMode; 88 private int mDisplayOptions = ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP; 89 private CharSequence mTitle; 90 private CharSequence mSubtitle; 91 private Drawable mIcon; 92 private Drawable mLogo; 93 94 private HomeView mHomeLayout; 95 private HomeView mExpandedHomeLayout; 96 private LinearLayout mTitleLayout; 97 private TextView mTitleView; 98 private TextView mSubtitleView; 99 private View mTitleUpView; 100 101 private Spinner mSpinner; 102 private LinearLayout mListNavLayout; 103 private ScrollingTabContainerView mTabScrollView; 104 private View mCustomNavView; 105 private ProgressBar mProgressView; 106 private ProgressBar mIndeterminateProgressView; 107 108 private int mProgressBarPadding; 109 private int mItemPadding; 110 111 private int mTitleStyleRes; 112 private int mSubtitleStyleRes; 113 private int mProgressStyle; 114 private int mIndeterminateProgressStyle; 115 116 private boolean mSplitActionBar; 117 private boolean mUserTitle; 118 private boolean mIncludeTabs; 119 private boolean mIsCollapsable; 120 private boolean mIsCollapsed; 121 122 private MenuBuilder mOptionsMenu; 123 124 private ActionBarContextView mContextView; 125 126 private ActionMenuItem mLogoNavItem; 127 128 private SpinnerAdapter mSpinnerAdapter; 129 private OnNavigationListener mCallback; 130 131 private Runnable mTabSelector; 132 133 private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; 134 View mExpandedActionView; 135 136 private final AdapterView.OnItemSelectedListener mNavItemSelectedListener = 137 new AdapterView.OnItemSelectedListener() { 138 public void onItemSelected(AdapterView parent, View view, int position, long id) { 139 if (mCallback != null) { 140 mCallback.onNavigationItemSelected(position, id); 141 } 142 } 143 public void onNothingSelected(AdapterView parent) { 144 // Do nothing 145 } 146 }; 147 148 private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() { 149 @Override 150 public void onClick(View v) { 151 final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem; 152 if (item != null) { 153 item.collapseActionView(); 154 } 155 } 156 }; 157 158 private final OnClickListener mUpClickListener = new OnClickListener() { 159 public void onClick(View v) { 160 Context context = getContext(); 161 if (context instanceof Activity) { 162 Activity activity = (Activity) context; 163 activity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem); 164 } 165 } 166 }; 167 168 public ActionBarView(Context context, AttributeSet attrs) { 169 super(context, attrs); 170 171 // Background is always provided by the container. 172 setBackgroundResource(0); 173 174 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar); 175 176 ApplicationInfo appInfo = context.getApplicationInfo(); 177 PackageManager pm = context.getPackageManager(); 178 mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode, 179 ActionBar.NAVIGATION_MODE_STANDARD); 180 mTitle = a.getText(R.styleable.ActionBar_title); 181 mSubtitle = a.getText(R.styleable.ActionBar_subtitle); 182 183 mLogo = a.getDrawable(R.styleable.ActionBar_logo); 184 if (mLogo == null) { 185 if (context instanceof Activity) { 186 try { 187 mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); 188 } catch (NameNotFoundException e) { 189 Log.e(TAG, "Activity component name not found!", e); 190 } 191 } 192 if (mLogo == null) { 193 mLogo = appInfo.loadLogo(pm); 194 } 195 } 196 197 mIcon = a.getDrawable(R.styleable.ActionBar_icon); 198 if (mIcon == null) { 199 if (context instanceof Activity) { 200 try { 201 mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); 202 } catch (NameNotFoundException e) { 203 Log.e(TAG, "Activity component name not found!", e); 204 } 205 } 206 if (mIcon == null) { 207 mIcon = appInfo.loadIcon(pm); 208 } 209 } 210 211 final LayoutInflater inflater = LayoutInflater.from(context); 212 213 final int homeResId = a.getResourceId( 214 com.android.internal.R.styleable.ActionBar_homeLayout, 215 com.android.internal.R.layout.action_bar_home); 216 217 mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); 218 219 mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); 220 mExpandedHomeLayout.setUp(true); 221 mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); 222 223 mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0); 224 mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0); 225 mProgressStyle = a.getResourceId(R.styleable.ActionBar_progressBarStyle, 0); 226 mIndeterminateProgressStyle = a.getResourceId( 227 R.styleable.ActionBar_indeterminateProgressStyle, 0); 228 229 mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_progressBarPadding, 0); 230 mItemPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_itemPadding, 0); 231 232 setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT)); 233 234 final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0); 235 if (customNavId != 0) { 236 mCustomNavView = (View) inflater.inflate(customNavId, this, false); 237 mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; 238 setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM); 239 } 240 241 mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0); 242 243 a.recycle(); 244 245 mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle); 246 mHomeLayout.setOnClickListener(mUpClickListener); 247 mHomeLayout.setClickable(true); 248 mHomeLayout.setFocusable(true); 249 } 250 251 @Override 252 public void onDetachedFromWindow() { 253 super.onDetachedFromWindow(); 254 removeCallbacks(mTabSelector); 255 } 256 257 @Override 258 public boolean shouldDelayChildPressedState() { 259 return false; 260 } 261 262 public void initProgress() { 263 mProgressView = new ProgressBar(mContext, null, 0, mProgressStyle); 264 mProgressView.setId(R.id.progress_horizontal); 265 mProgressView.setMax(10000); 266 addView(mProgressView); 267 } 268 269 public void initIndeterminateProgress() { 270 mIndeterminateProgressView = new ProgressBar(mContext, null, 0, 271 mIndeterminateProgressStyle); 272 mIndeterminateProgressView.setId(R.id.progress_circular); 273 addView(mIndeterminateProgressView); 274 } 275 276 public void setContentHeight(int height) { 277 mContentHeight = height; 278 requestLayout(); 279 } 280 281 public int getContentHeight() { 282 return mContentHeight; 283 } 284 285 public void setSplitActionBar(boolean splitActionBar) { 286 if (mSplitActionBar != splitActionBar) { 287 if (mMenuView != null) { 288 if (splitActionBar) { 289 removeView(mMenuView); 290 if (mSplitView != null) { 291 mSplitView.addView(mMenuView); 292 } 293 } else { 294 addView(mMenuView); 295 } 296 } 297 mSplitActionBar = splitActionBar; 298 } 299 } 300 301 public boolean isSplitActionBar() { 302 return mSplitActionBar; 303 } 304 305 public boolean hasEmbeddedTabs() { 306 return mIncludeTabs; 307 } 308 309 public void setEmbeddedTabView(ScrollingTabContainerView tabs) { 310 if (mTabScrollView != null) { 311 removeView(mTabScrollView); 312 } 313 mTabScrollView = tabs; 314 mIncludeTabs = tabs != null; 315 if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { 316 addView(mTabScrollView); 317 } 318 } 319 320 public void setCallback(OnNavigationListener callback) { 321 mCallback = callback; 322 } 323 324 public void setMenu(Menu menu, MenuPresenter.Callback cb) { 325 if (menu == mOptionsMenu) return; 326 327 if (mOptionsMenu != null) { 328 mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); 329 mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); 330 } 331 332 MenuBuilder builder = (MenuBuilder) menu; 333 mOptionsMenu = builder; 334 if (mMenuView != null) { 335 removeView(mMenuView); 336 } 337 if (mActionMenuPresenter == null) { 338 mActionMenuPresenter = new ActionMenuPresenter(); 339 mActionMenuPresenter.setCallback(cb); 340 mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter); 341 mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); 342 } 343 344 ActionMenuView menuView; 345 final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, 346 LayoutParams.MATCH_PARENT); 347 if (!mSplitActionBar) { 348 builder.addMenuPresenter(mActionMenuPresenter); 349 builder.addMenuPresenter(mExpandedMenuPresenter); 350 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); 351 addView(menuView, layoutParams); 352 } else { 353 // Allow full screen width in split mode. 354 mActionMenuPresenter.setWidthLimit( 355 getContext().getResources().getDisplayMetrics().widthPixels, true); 356 // No limit to the item count; use whatever will fit. 357 mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); 358 // Span the whole width 359 layoutParams.width = LayoutParams.MATCH_PARENT; 360 builder.addMenuPresenter(mActionMenuPresenter); 361 builder.addMenuPresenter(mExpandedMenuPresenter); 362 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); 363 if (mSplitView != null) { 364 mSplitView.addView(menuView, layoutParams); 365 } else { 366 // We'll add this later if we missed it this time. 367 menuView.setLayoutParams(layoutParams); 368 } 369 } 370 mMenuView = menuView; 371 } 372 373 public void setCustomNavigationView(View view) { 374 final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0; 375 if (mCustomNavView != null && showCustom) { 376 removeView(mCustomNavView); 377 } 378 mCustomNavView = view; 379 if (mCustomNavView != null && showCustom) { 380 addView(mCustomNavView); 381 } 382 } 383 384 public CharSequence getTitle() { 385 return mTitle; 386 } 387 388 /** 389 * Set the action bar title. This will always replace or override window titles. 390 * @param title Title to set 391 * 392 * @see #setWindowTitle(CharSequence) 393 */ 394 public void setTitle(CharSequence title) { 395 mUserTitle = true; 396 setTitleImpl(title); 397 } 398 399 /** 400 * Set the window title. A window title will always be replaced or overridden by a user title. 401 * @param title Title to set 402 * 403 * @see #setTitle(CharSequence) 404 */ 405 public void setWindowTitle(CharSequence title) { 406 if (!mUserTitle) { 407 setTitleImpl(title); 408 } 409 } 410 411 private void setTitleImpl(CharSequence title) { 412 mTitle = title; 413 if (mTitleView != null) { 414 mTitleView.setText(title); 415 mTitleLayout.setVisibility(TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle) ? 416 GONE : VISIBLE); 417 } 418 if (mLogoNavItem != null) { 419 mLogoNavItem.setTitle(title); 420 } 421 } 422 423 public CharSequence getSubtitle() { 424 return mSubtitle; 425 } 426 427 public void setSubtitle(CharSequence subtitle) { 428 mSubtitle = subtitle; 429 if (mSubtitleView != null) { 430 mSubtitleView.setText(subtitle); 431 mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE); 432 mTitleLayout.setVisibility(TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle) ? 433 GONE : VISIBLE); 434 } 435 } 436 437 public void setHomeButtonEnabled(boolean enable) { 438 mHomeLayout.setEnabled(enable); 439 // Make sure the home button has an accurate content description for accessibility. 440 if (!enable) { 441 mHomeLayout.setContentDescription(null); 442 } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 443 mHomeLayout.setContentDescription(mContext.getResources().getText( 444 R.string.action_bar_up_description)); 445 } else { 446 mHomeLayout.setContentDescription(mContext.getResources().getText( 447 R.string.action_bar_home_description)); 448 } 449 } 450 451 public void setDisplayOptions(int options) { 452 final int flagsChanged = options ^ mDisplayOptions; 453 mDisplayOptions = options; 454 455 if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) { 456 final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0; 457 final int vis = showHome ? VISIBLE : GONE; 458 mHomeLayout.setVisibility(vis); 459 460 if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 461 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; 462 mHomeLayout.setUp(setUp); 463 464 // Showing home as up implicitly enables interaction with it. 465 // In honeycomb it was always enabled, so make this transition 466 // a bit easier for developers in the common case. 467 // (It would be silly to show it as up without responding to it.) 468 if (setUp) { 469 setHomeButtonEnabled(true); 470 } 471 } 472 473 if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { 474 final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0; 475 mHomeLayout.setIcon(logoVis ? mLogo : mIcon); 476 } 477 478 if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 479 if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 480 initTitle(); 481 } else { 482 removeView(mTitleLayout); 483 } 484 } 485 486 if (mTitleLayout != null && (flagsChanged & 487 (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) { 488 final boolean homeAsUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; 489 final boolean titleUp = homeAsUp && !showHome; 490 mTitleUpView.setVisibility(titleUp ? VISIBLE : GONE); 491 mTitleLayout.setEnabled(titleUp); 492 } 493 494 if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { 495 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { 496 addView(mCustomNavView); 497 } else { 498 removeView(mCustomNavView); 499 } 500 } 501 502 requestLayout(); 503 } else { 504 invalidate(); 505 } 506 507 // Make sure the home button has an accurate content description for accessibility. 508 if (!mHomeLayout.isEnabled()) { 509 mHomeLayout.setContentDescription(null); 510 } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 511 mHomeLayout.setContentDescription(mContext.getResources().getText( 512 R.string.action_bar_up_description)); 513 } else { 514 mHomeLayout.setContentDescription(mContext.getResources().getText( 515 R.string.action_bar_home_description)); 516 } 517 } 518 519 public void setIcon(Drawable icon) { 520 mIcon = icon; 521 if (icon != null && 522 ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) { 523 mHomeLayout.setIcon(icon); 524 } 525 } 526 527 public void setIcon(int resId) { 528 setIcon(mContext.getResources().getDrawableForDensity(resId, getPreferredIconDensity())); 529 } 530 531 public void setLogo(Drawable logo) { 532 mLogo = logo; 533 if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { 534 mHomeLayout.setIcon(logo); 535 } 536 } 537 538 public void setLogo(int resId) { 539 mContext.getResources().getDrawable(resId); 540 } 541 542 /** 543 * @return Drawable density to load that will best fit the available height. 544 */ 545 private int getPreferredIconDensity() { 546 final Resources res = mContext.getResources(); 547 final int availableHeight = getLayoutParams().height - 548 mHomeLayout.getVerticalIconPadding(); 549 int iconSize = res.getDimensionPixelSize(android.R.dimen.app_icon_size); 550 551 if (iconSize * DisplayMetrics.DENSITY_LOW >= availableHeight) { 552 return DisplayMetrics.DENSITY_LOW; 553 } else if (iconSize * DisplayMetrics.DENSITY_MEDIUM >= availableHeight) { 554 return DisplayMetrics.DENSITY_MEDIUM; 555 } else if (iconSize * DisplayMetrics.DENSITY_HIGH >= availableHeight) { 556 return DisplayMetrics.DENSITY_HIGH; 557 } 558 return DisplayMetrics.DENSITY_XHIGH; 559 } 560 561 public void setNavigationMode(int mode) { 562 final int oldMode = mNavigationMode; 563 if (mode != oldMode) { 564 switch (oldMode) { 565 case ActionBar.NAVIGATION_MODE_LIST: 566 if (mListNavLayout != null) { 567 removeView(mListNavLayout); 568 } 569 break; 570 case ActionBar.NAVIGATION_MODE_TABS: 571 if (mTabScrollView != null && mIncludeTabs) { 572 removeView(mTabScrollView); 573 } 574 } 575 576 switch (mode) { 577 case ActionBar.NAVIGATION_MODE_LIST: 578 if (mSpinner == null) { 579 mSpinner = new Spinner(mContext, null, 580 com.android.internal.R.attr.actionDropDownStyle); 581 mListNavLayout = new LinearLayout(mContext, null, 582 com.android.internal.R.attr.actionBarTabBarStyle); 583 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 584 LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 585 params.gravity = Gravity.CENTER; 586 mListNavLayout.addView(mSpinner, params); 587 } 588 if (mSpinner.getAdapter() != mSpinnerAdapter) { 589 mSpinner.setAdapter(mSpinnerAdapter); 590 } 591 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener); 592 addView(mListNavLayout); 593 break; 594 case ActionBar.NAVIGATION_MODE_TABS: 595 if (mTabScrollView != null && mIncludeTabs) { 596 addView(mTabScrollView); 597 } 598 break; 599 } 600 mNavigationMode = mode; 601 requestLayout(); 602 } 603 } 604 605 public ScrollingTabContainerView createTabContainer() { 606 final LinearLayout tabLayout = new LinearLayout(getContext(), null, 607 com.android.internal.R.attr.actionBarTabBarStyle); 608 tabLayout.setMeasureWithLargestChildEnabled(true); 609 tabLayout.setLayoutParams(new LinearLayout.LayoutParams( 610 LinearLayout.LayoutParams.WRAP_CONTENT, mContentHeight)); 611 612 final ScrollingTabContainerView scroller = new ScrollingTabContainerView(mContext); 613 scroller.setTabLayout(tabLayout); 614 return scroller; 615 } 616 617 public void setDropdownAdapter(SpinnerAdapter adapter) { 618 mSpinnerAdapter = adapter; 619 if (mSpinner != null) { 620 mSpinner.setAdapter(adapter); 621 } 622 } 623 624 public SpinnerAdapter getDropdownAdapter() { 625 return mSpinnerAdapter; 626 } 627 628 public void setDropdownSelectedPosition(int position) { 629 mSpinner.setSelection(position); 630 } 631 632 public int getDropdownSelectedPosition() { 633 return mSpinner.getSelectedItemPosition(); 634 } 635 636 public View getCustomNavigationView() { 637 return mCustomNavView; 638 } 639 640 public int getNavigationMode() { 641 return mNavigationMode; 642 } 643 644 public int getDisplayOptions() { 645 return mDisplayOptions; 646 } 647 648 @Override 649 protected LayoutParams generateDefaultLayoutParams() { 650 // Used by custom nav views if they don't supply layout params. Everything else 651 // added to an ActionBarView should have them already. 652 return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY); 653 } 654 655 @Override 656 protected void onFinishInflate() { 657 super.onFinishInflate(); 658 659 addView(mHomeLayout); 660 661 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { 662 final ViewParent parent = mCustomNavView.getParent(); 663 if (parent != this) { 664 if (parent instanceof ViewGroup) { 665 ((ViewGroup) parent).removeView(mCustomNavView); 666 } 667 addView(mCustomNavView); 668 } 669 } 670 } 671 672 private void initTitle() { 673 if (mTitleLayout == null) { 674 LayoutInflater inflater = LayoutInflater.from(getContext()); 675 mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item, null); 676 mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title); 677 mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle); 678 mTitleUpView = (View) mTitleLayout.findViewById(R.id.up); 679 680 mTitleLayout.setOnClickListener(mUpClickListener); 681 682 if (mTitleStyleRes != 0) { 683 mTitleView.setTextAppearance(mContext, mTitleStyleRes); 684 } 685 if (mTitle != null) { 686 mTitleView.setText(mTitle); 687 } 688 689 if (mSubtitleStyleRes != 0) { 690 mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); 691 } 692 if (mSubtitle != null) { 693 mSubtitleView.setText(mSubtitle); 694 mSubtitleView.setVisibility(VISIBLE); 695 } 696 697 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; 698 final boolean titleUp = homeAsUp && 699 (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) == 0; 700 mTitleUpView.setVisibility(titleUp ? VISIBLE : GONE); 701 mTitleLayout.setEnabled(titleUp); 702 } 703 704 addView(mTitleLayout); 705 } 706 707 public void setContextView(ActionBarContextView view) { 708 mContextView = view; 709 } 710 711 public void setCollapsable(boolean collapsable) { 712 mIsCollapsable = collapsable; 713 } 714 715 public boolean isCollapsed() { 716 return mIsCollapsed; 717 } 718 719 @Override 720 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 721 final int childCount = getChildCount(); 722 if (mIsCollapsable) { 723 int visibleChildren = 0; 724 for (int i = 0; i < childCount; i++) { 725 final View child = getChildAt(i); 726 if (child.getVisibility() != GONE && 727 !(child == mMenuView && mMenuView.getChildCount() == 0)) { 728 visibleChildren++; 729 } 730 } 731 732 if (visibleChildren == 0) { 733 // No size for an empty action bar when collapsable. 734 setMeasuredDimension(0, 0); 735 mIsCollapsed = true; 736 return; 737 } 738 } 739 mIsCollapsed = false; 740 741 int widthMode = MeasureSpec.getMode(widthMeasureSpec); 742 if (widthMode != MeasureSpec.EXACTLY) { 743 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + 744 "with android:layout_width=\"match_parent\" (or fill_parent)"); 745 } 746 747 int heightMode = MeasureSpec.getMode(heightMeasureSpec); 748 if (heightMode != MeasureSpec.AT_MOST) { 749 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + 750 "with android:layout_height=\"wrap_content\""); 751 } 752 753 int contentWidth = MeasureSpec.getSize(widthMeasureSpec); 754 755 int maxHeight = mContentHeight > 0 ? 756 mContentHeight : MeasureSpec.getSize(heightMeasureSpec); 757 758 final int verticalPadding = getPaddingTop() + getPaddingBottom(); 759 final int paddingLeft = getPaddingLeft(); 760 final int paddingRight = getPaddingRight(); 761 final int height = maxHeight - verticalPadding; 762 final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); 763 764 int availableWidth = contentWidth - paddingLeft - paddingRight; 765 int leftOfCenter = availableWidth / 2; 766 int rightOfCenter = leftOfCenter; 767 768 View homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; 769 770 if (homeLayout.getVisibility() != GONE) { 771 final LayoutParams lp = homeLayout.getLayoutParams(); 772 int homeWidthSpec; 773 if (lp.width < 0) { 774 homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); 775 } else { 776 homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); 777 } 778 homeLayout.measure(homeWidthSpec, 779 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 780 final int homeWidth = homeLayout.getMeasuredWidth(); 781 availableWidth = Math.max(0, availableWidth - homeWidth); 782 leftOfCenter = Math.max(0, availableWidth - homeWidth); 783 } 784 785 if (mMenuView != null && mMenuView.getParent() == this) { 786 availableWidth = measureChildView(mMenuView, availableWidth, 787 childSpecHeight, 0); 788 rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); 789 } 790 791 if (mExpandedActionView == null) { 792 boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && 793 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; 794 if (showTitle) { 795 availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); 796 leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); 797 } 798 799 switch (mNavigationMode) { 800 case ActionBar.NAVIGATION_MODE_LIST: 801 if (mListNavLayout != null) { 802 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; 803 availableWidth = Math.max(0, availableWidth - itemPaddingSize); 804 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); 805 mListNavLayout.measure( 806 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), 807 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 808 final int listNavWidth = mListNavLayout.getMeasuredWidth(); 809 availableWidth = Math.max(0, availableWidth - listNavWidth); 810 leftOfCenter = Math.max(0, leftOfCenter - listNavWidth); 811 } 812 break; 813 case ActionBar.NAVIGATION_MODE_TABS: 814 if (mTabScrollView != null) { 815 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; 816 availableWidth = Math.max(0, availableWidth - itemPaddingSize); 817 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); 818 mTabScrollView.measure( 819 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), 820 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 821 final int tabWidth = mTabScrollView.getMeasuredWidth(); 822 availableWidth = Math.max(0, availableWidth - tabWidth); 823 leftOfCenter = Math.max(0, leftOfCenter - tabWidth); 824 } 825 break; 826 } 827 } 828 829 if (mIndeterminateProgressView != null && 830 mIndeterminateProgressView.getVisibility() != GONE) { 831 availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, 832 childSpecHeight, 0); 833 rightOfCenter = Math.max(0, 834 rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); 835 } 836 837 View customView = null; 838 if (mExpandedActionView != null) { 839 customView = mExpandedActionView; 840 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && 841 mCustomNavView != null) { 842 customView = mCustomNavView; 843 } 844 845 if (customView != null) { 846 final LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); 847 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? 848 (ActionBar.LayoutParams) lp : null; 849 850 int horizontalMargin = 0; 851 int verticalMargin = 0; 852 if (ablp != null) { 853 horizontalMargin = ablp.leftMargin + ablp.rightMargin; 854 verticalMargin = ablp.topMargin + ablp.bottomMargin; 855 } 856 857 // If the action bar is wrapping to its content height, don't allow a custom 858 // view to MATCH_PARENT. 859 int customNavHeightMode; 860 if (mContentHeight <= 0) { 861 customNavHeightMode = MeasureSpec.AT_MOST; 862 } else { 863 customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? 864 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; 865 } 866 final int customNavHeight = Math.max(0, 867 (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); 868 869 final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? 870 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; 871 int customNavWidth = Math.max(0, 872 (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) 873 - horizontalMargin); 874 final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & 875 Gravity.HORIZONTAL_GRAVITY_MASK; 876 877 // Centering a custom view is treated specially; we try to center within the whole 878 // action bar rather than in the available space. 879 if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { 880 customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; 881 } 882 883 customView.measure( 884 MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), 885 MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); 886 } 887 888 if (mContentHeight <= 0) { 889 int measuredHeight = 0; 890 for (int i = 0; i < childCount; i++) { 891 View v = getChildAt(i); 892 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; 893 if (paddedViewHeight > measuredHeight) { 894 measuredHeight = paddedViewHeight; 895 } 896 } 897 setMeasuredDimension(contentWidth, measuredHeight); 898 } else { 899 setMeasuredDimension(contentWidth, maxHeight); 900 } 901 902 if (mContextView != null) { 903 mContextView.setHeight(getMeasuredHeight()); 904 } 905 906 if (mProgressView != null && mProgressView.getVisibility() != GONE) { 907 mProgressView.measure(MeasureSpec.makeMeasureSpec( 908 contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY), 909 MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST)); 910 } 911 } 912 913 @Override 914 protected void onLayout(boolean changed, int l, int t, int r, int b) { 915 int x = getPaddingLeft(); 916 final int y = getPaddingTop(); 917 final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); 918 919 if (contentHeight <= 0) { 920 // Nothing to do if we can't see anything. 921 return; 922 } 923 924 View homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; 925 if (homeLayout.getVisibility() != GONE) { 926 x += positionChild(homeLayout, x, y, contentHeight); 927 } 928 929 if (mExpandedActionView == null) { 930 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && 931 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; 932 if (showTitle) { 933 x += positionChild(mTitleLayout, x, y, contentHeight); 934 } 935 936 switch (mNavigationMode) { 937 case ActionBar.NAVIGATION_MODE_STANDARD: 938 break; 939 case ActionBar.NAVIGATION_MODE_LIST: 940 if (mListNavLayout != null) { 941 if (showTitle) x += mItemPadding; 942 x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding; 943 } 944 break; 945 case ActionBar.NAVIGATION_MODE_TABS: 946 if (mTabScrollView != null) { 947 if (showTitle) x += mItemPadding; 948 x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; 949 } 950 break; 951 } 952 } 953 954 int menuLeft = r - l - getPaddingRight(); 955 if (mMenuView != null && mMenuView.getParent() == this) { 956 positionChildInverse(mMenuView, menuLeft, y, contentHeight); 957 menuLeft -= mMenuView.getMeasuredWidth(); 958 } 959 960 if (mIndeterminateProgressView != null && 961 mIndeterminateProgressView.getVisibility() != GONE) { 962 positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight); 963 menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); 964 } 965 966 View customView = null; 967 if (mExpandedActionView != null) { 968 customView = mExpandedActionView; 969 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && 970 mCustomNavView != null) { 971 customView = mCustomNavView; 972 } 973 if (customView != null) { 974 LayoutParams lp = customView.getLayoutParams(); 975 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? 976 (ActionBar.LayoutParams) lp : null; 977 978 final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; 979 final int navWidth = customView.getMeasuredWidth(); 980 981 int topMargin = 0; 982 int bottomMargin = 0; 983 if (ablp != null) { 984 x += ablp.leftMargin; 985 menuLeft -= ablp.rightMargin; 986 topMargin = ablp.topMargin; 987 bottomMargin = ablp.bottomMargin; 988 } 989 990 int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; 991 // See if we actually have room to truly center; if not push against left or right. 992 if (hgravity == Gravity.CENTER_HORIZONTAL) { 993 final int centeredLeft = ((mRight - mLeft) - navWidth) / 2; 994 if (centeredLeft < x) { 995 hgravity = Gravity.LEFT; 996 } else if (centeredLeft + navWidth > menuLeft) { 997 hgravity = Gravity.RIGHT; 998 } 999 } 1000 1001 int xpos = 0; 1002 switch (hgravity) { 1003 case Gravity.CENTER_HORIZONTAL: 1004 xpos = ((mRight - mLeft) - navWidth) / 2; 1005 break; 1006 case Gravity.LEFT: 1007 xpos = x; 1008 break; 1009 case Gravity.RIGHT: 1010 xpos = menuLeft - navWidth; 1011 break; 1012 } 1013 1014 int ypos = 0; 1015 switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) { 1016 case Gravity.CENTER_VERTICAL: 1017 final int paddedTop = getPaddingTop(); 1018 final int paddedBottom = mBottom - mTop - getPaddingBottom(); 1019 ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2; 1020 break; 1021 case Gravity.TOP: 1022 ypos = getPaddingTop() + topMargin; 1023 break; 1024 case Gravity.BOTTOM: 1025 ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() 1026 - bottomMargin; 1027 break; 1028 } 1029 final int customWidth = customView.getMeasuredWidth(); 1030 customView.layout(xpos, ypos, xpos + customWidth, 1031 ypos + customView.getMeasuredHeight()); 1032 x += customWidth; 1033 } 1034 1035 if (mProgressView != null) { 1036 mProgressView.bringToFront(); 1037 final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2; 1038 mProgressView.layout(mProgressBarPadding, -halfProgressHeight, 1039 mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight); 1040 } 1041 } 1042 1043 @Override 1044 public LayoutParams generateLayoutParams(LayoutParams lp) { 1045 if (lp == null) { 1046 lp = generateDefaultLayoutParams(); 1047 } 1048 return lp; 1049 } 1050 1051 @Override 1052 public Parcelable onSaveInstanceState() { 1053 Parcelable superState = super.onSaveInstanceState(); 1054 SavedState state = new SavedState(superState); 1055 1056 if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) { 1057 state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId(); 1058 } 1059 1060 state.isOverflowOpen = isOverflowMenuShowing(); 1061 1062 return state; 1063 } 1064 1065 @Override 1066 public void onRestoreInstanceState(Parcelable p) { 1067 SavedState state = (SavedState) p; 1068 1069 super.onRestoreInstanceState(state.getSuperState()); 1070 1071 if (state.expandedMenuItemId != 0 && 1072 mExpandedMenuPresenter != null && mOptionsMenu != null) { 1073 final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId); 1074 if (item != null) { 1075 item.expandActionView(); 1076 } 1077 } 1078 1079 if (state.isOverflowOpen) { 1080 postShowOverflowMenu(); 1081 } 1082 } 1083 1084 static class SavedState extends BaseSavedState { 1085 int expandedMenuItemId; 1086 boolean isOverflowOpen; 1087 1088 SavedState(Parcelable superState) { 1089 super(superState); 1090 } 1091 1092 private SavedState(Parcel in) { 1093 super(in); 1094 expandedMenuItemId = in.readInt(); 1095 isOverflowOpen = in.readInt() != 0; 1096 } 1097 1098 @Override 1099 public void writeToParcel(Parcel out, int flags) { 1100 super.writeToParcel(out, flags); 1101 out.writeInt(expandedMenuItemId); 1102 out.writeInt(isOverflowOpen ? 1 : 0); 1103 } 1104 1105 public static final Parcelable.Creator<SavedState> CREATOR = 1106 new Parcelable.Creator<SavedState>() { 1107 public SavedState createFromParcel(Parcel in) { 1108 return new SavedState(in); 1109 } 1110 1111 public SavedState[] newArray(int size) { 1112 return new SavedState[size]; 1113 } 1114 }; 1115 } 1116 1117 private static class HomeView extends FrameLayout { 1118 private View mUpView; 1119 private ImageView mIconView; 1120 1121 public HomeView(Context context) { 1122 this(context, null); 1123 } 1124 1125 public HomeView(Context context, AttributeSet attrs) { 1126 super(context, attrs); 1127 } 1128 1129 public void setUp(boolean isUp) { 1130 mUpView.setVisibility(isUp ? VISIBLE : GONE); 1131 } 1132 1133 public void setIcon(Drawable icon) { 1134 mIconView.setImageDrawable(icon); 1135 } 1136 1137 @Override 1138 protected void onFinishInflate() { 1139 mUpView = findViewById(com.android.internal.R.id.up); 1140 mIconView = (ImageView) findViewById(com.android.internal.R.id.home); 1141 } 1142 1143 public int getVerticalIconPadding() { 1144 return mIconView.getPaddingTop() + mIconView.getPaddingBottom(); 1145 } 1146 1147 @Override 1148 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 1149 measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0); 1150 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); 1151 int width = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin; 1152 int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin; 1153 measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0); 1154 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); 1155 width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin; 1156 height = Math.max(height, 1157 iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin); 1158 1159 final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 1160 final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 1161 final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 1162 final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 1163 1164 switch (widthMode) { 1165 case MeasureSpec.AT_MOST: 1166 width = Math.min(width, widthSize); 1167 break; 1168 case MeasureSpec.EXACTLY: 1169 width = widthSize; 1170 break; 1171 case MeasureSpec.UNSPECIFIED: 1172 default: 1173 break; 1174 } 1175 switch (heightMode) { 1176 case MeasureSpec.AT_MOST: 1177 height = Math.min(height, heightSize); 1178 break; 1179 case MeasureSpec.EXACTLY: 1180 height = heightSize; 1181 break; 1182 case MeasureSpec.UNSPECIFIED: 1183 default: 1184 break; 1185 } 1186 setMeasuredDimension(width, height); 1187 } 1188 1189 @Override 1190 protected void onLayout(boolean changed, int l, int t, int r, int b) { 1191 final int vCenter = (b - t) / 2; 1192 int width = r - l; 1193 int upOffset = 0; 1194 if (mUpView.getVisibility() != GONE) { 1195 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); 1196 final int upHeight = mUpView.getMeasuredHeight(); 1197 final int upWidth = mUpView.getMeasuredWidth(); 1198 final int upTop = vCenter - upHeight / 2; 1199 mUpView.layout(0, upTop, upWidth, upTop + upHeight); 1200 upOffset = upLp.leftMargin + upWidth + upLp.rightMargin; 1201 width -= upOffset; 1202 l += upOffset; 1203 } 1204 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); 1205 final int iconHeight = mIconView.getMeasuredHeight(); 1206 final int iconWidth = mIconView.getMeasuredWidth(); 1207 final int hCenter = (r - l) / 2; 1208 final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2); 1209 final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2); 1210 mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); 1211 } 1212 } 1213 1214 private class ExpandedActionViewMenuPresenter implements MenuPresenter { 1215 MenuBuilder mMenu; 1216 MenuItemImpl mCurrentExpandedItem; 1217 1218 @Override 1219 public void initForMenu(Context context, MenuBuilder menu) { 1220 // Clear the expanded action view when menus change. 1221 mExpandedActionView = null; 1222 if (mCurrentExpandedItem != null) { 1223 mCurrentExpandedItem.collapseActionView(); 1224 } 1225 mMenu = menu; 1226 } 1227 1228 @Override 1229 public MenuView getMenuView(ViewGroup root) { 1230 return null; 1231 } 1232 1233 @Override 1234 public void updateMenuView(boolean cleared) { 1235 // Make sure the expanded item we have is still there. 1236 if (mCurrentExpandedItem != null) { 1237 boolean found = false; 1238 final int count = mMenu.size(); 1239 for (int i = 0; i < count; i++) { 1240 final MenuItem item = mMenu.getItem(i); 1241 if (item == mCurrentExpandedItem) { 1242 found = true; 1243 break; 1244 } 1245 } 1246 1247 if (!found) { 1248 // The item we had expanded disappeared. Collapse. 1249 collapseItemActionView(mMenu, mCurrentExpandedItem); 1250 } 1251 } 1252 } 1253 1254 @Override 1255 public void setCallback(Callback cb) { 1256 } 1257 1258 @Override 1259 public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 1260 return false; 1261 } 1262 1263 @Override 1264 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 1265 } 1266 1267 @Override 1268 public boolean flagActionItems() { 1269 return false; 1270 } 1271 1272 @Override 1273 public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { 1274 mExpandedActionView = item.getActionView(); 1275 mExpandedHomeLayout.setIcon(item.getIcon()); 1276 mCurrentExpandedItem = item; 1277 if (mExpandedActionView.getParent() != ActionBarView.this) { 1278 addView(mExpandedActionView); 1279 } 1280 if (mExpandedHomeLayout.getParent() != ActionBarView.this) { 1281 addView(mExpandedHomeLayout); 1282 } 1283 mHomeLayout.setVisibility(GONE); 1284 if (mTitleLayout != null) mTitleLayout.setVisibility(GONE); 1285 if (mTabScrollView != null) mTabScrollView.setVisibility(GONE); 1286 if (mSpinner != null) mSpinner.setVisibility(GONE); 1287 if (mCustomNavView != null) mCustomNavView.setVisibility(GONE); 1288 requestLayout(); 1289 item.setActionViewExpanded(true); 1290 return true; 1291 } 1292 1293 @Override 1294 public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { 1295 removeView(mExpandedActionView); 1296 removeView(mExpandedHomeLayout); 1297 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) { 1298 mHomeLayout.setVisibility(VISIBLE); 1299 } 1300 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 1301 if (mTitleLayout == null) { 1302 initTitle(); 1303 } else { 1304 mTitleLayout.setVisibility(VISIBLE); 1305 } 1306 } 1307 if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { 1308 mTabScrollView.setVisibility(VISIBLE); 1309 } 1310 if (mSpinner != null && mNavigationMode == ActionBar.NAVIGATION_MODE_LIST) { 1311 mSpinner.setVisibility(VISIBLE); 1312 } 1313 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { 1314 mCustomNavView.setVisibility(VISIBLE); 1315 } 1316 mExpandedActionView = null; 1317 mExpandedHomeLayout.setIcon(null); 1318 mCurrentExpandedItem = null; 1319 requestLayout(); 1320 item.setActionViewExpanded(false); 1321 return true; 1322 } 1323 1324 @Override 1325 public int getId() { 1326 return 0; 1327 } 1328 1329 @Override 1330 public Parcelable onSaveInstanceState() { 1331 return null; 1332 } 1333 1334 @Override 1335 public void onRestoreInstanceState(Parcelable state) { 1336 } 1337 } 1338} 1339