Example #1
0
  /**
   * Closes the visible menu.
   *
   * @param allMenusAreClosing Whether the menus are completely closing (true), or whether there is
   *     another menu coming in this menu's place (false). For example, if the menu is closing
   *     because a sub menu is about to be shown, <var>allMenusAreClosing</var> is false.
   */
  final void close(boolean allMenusAreClosing) {
    if (mIsClosing) return;

    mIsClosing = true;
    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else {
        presenter.onCloseMenu(this, allMenusAreClosing);
      }
    }
    mIsClosing = false;
  }
Example #2
0
  private void dispatchPresenterUpdate(boolean cleared) {
    if (mPresenters.isEmpty()) return;

    stopDispatchingItemsChanged();
    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else {
        presenter.updateMenuView(cleared);
      }
    }
    startDispatchingItemsChanged();
  }
Example #3
0
  private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) {
    if (mPresenters.isEmpty()) return false;

    boolean result = false;

    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else if (!result) {
        result = presenter.onSubMenuSelected(subMenu);
      }
    }
    return result;
  }
Example #4
0
  private void dispatchRestoreInstanceState(Bundle state) {
    SparseArray<Parcelable> presenterStates = state.getSparseParcelableArray(PRESENTER_KEY);

    if (presenterStates == null || mPresenters.isEmpty()) return;

    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else {
        final int id = presenter.getId();
        if (id > 0) {
          Parcelable parcel = presenterStates.get(id);
          if (parcel != null) {
            presenter.onRestoreInstanceState(parcel);
          }
        }
      }
    }
  }
  /**
   * This method determines which menu items get to be 'action items' that will appear in an action
   * bar and which items should be 'overflow items' in a secondary menu. The rules are as follows:
   *
   * <p>Items are considered for inclusion in the order specified within the menu. There is a limit
   * of mMaxActionItems as a total count, optionally including the overflow menu button itself. This
   * is a soft limit; if an item shares a group ID with an item previously included as an action
   * item, the new item will stay with its group and become an action item itself even if it breaks
   * the max item count limit. This is done to limit the conceptual complexity of the items
   * presented within an action bar. Only a few unrelated concepts should be presented to the user
   * in this space, and groups are treated as a single concept.
   *
   * <p>There is also a hard limit of consumed measurable space: mActionWidthLimit. This limit may
   * be broken by a single item that exceeds the remaining space, but no further items may be added.
   * If an item that is part of a group cannot fit within the remaining measured width, the entire
   * group will be demoted to overflow. This is done to ensure room for navigation and other
   * affordances in the action bar as well as reduce general UI clutter.
   *
   * <p>The space freed by demoting a full group cannot be consumed by future menu items. Once items
   * begin to overflow, all future items become overflow items as well. This is to avoid inadvertent
   * reordering that may break the app's intended design.
   */
  public void flagActionItems() {
    // Important side effect: if getVisibleItems is stale it may refresh,
    // which can affect action items staleness.
    final ArrayList<MenuItemImpl> visibleItems = getVisibleItems();

    if (!mIsActionItemsStale) {
      return;
    }

    // Presenters flag action items as needed.
    boolean flagged = false;
    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else {
        flagged |= presenter.flagActionItems();
      }
    }

    if (flagged) {
      mActionItems.clear();
      mNonActionItems.clear();
      final int itemsSize = visibleItems.size();
      for (int i = 0; i < itemsSize; i++) {
        MenuItemImpl item = visibleItems.get(i);
        if (item.isActionButton()) {
          mActionItems.add(item);
        } else {
          mNonActionItems.add(item);
        }
      }
    } else {
      // Nobody flagged anything, everything is a non-action item.
      // (This happens during a first pass with no action-item presenters.)
      mActionItems.clear();
      mNonActionItems.clear();
      mNonActionItems.addAll(getVisibleItems());
    }
    mIsActionItemsStale = false;
  }
Example #6
0
  public boolean collapseItemActionView(MenuItemImpl item) {
    if (mPresenters.isEmpty() || mExpandedItem != item) return false;

    boolean collapsed = false;

    stopDispatchingItemsChanged();
    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else if ((collapsed = presenter.collapseItemActionView(this, item))) {
        break;
      }
    }
    startDispatchingItemsChanged();

    if (collapsed) {
      mExpandedItem = null;
    }
    return collapsed;
  }
Example #7
0
  private void dispatchSaveInstanceState(Bundle outState) {
    if (mPresenters.isEmpty()) return;

    SparseArray<Parcelable> presenterStates = new SparseArray<Parcelable>();

    for (WeakReference<MenuPresenter> ref : mPresenters) {
      final MenuPresenter presenter = ref.get();
      if (presenter == null) {
        mPresenters.remove(ref);
      } else {
        final int id = presenter.getId();
        if (id > 0) {
          final Parcelable state = presenter.onSaveInstanceState();
          if (state != null) {
            presenterStates.put(id, state);
          }
        }
      }
    }

    outState.putSparseParcelableArray(PRESENTER_KEY, presenterStates);
  }
Example #8
0
 /**
  * Add a presenter to this menu. This will only hold a WeakReference; you do not need to
  * explicitly remove a presenter, but you can using {@link #removeMenuPresenter(MenuPresenter)}.
  *
  * @param presenter The presenter to add
  */
 public void addMenuPresenter(MenuPresenter presenter) {
   mPresenters.add(new WeakReference<MenuPresenter>(presenter));
   presenter.initForMenu(mContext, this);
   mIsActionItemsStale = true;
 }