mirror of
https://github.com/material-components/material-components-android.git
synced 2026-01-16 18:01:42 +08:00
680 lines
21 KiB
Java
680 lines
21 KiB
Java
/*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.android.material.internal;
|
|
|
|
import com.google.android.material.R;
|
|
|
|
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.ColorStateList;
|
|
import android.content.res.Resources;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.os.Bundle;
|
|
import android.os.Parcelable;
|
|
import android.support.annotation.LayoutRes;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.annotation.RestrictTo;
|
|
import android.support.annotation.StyleRes;
|
|
import android.support.v4.view.ViewCompat;
|
|
import android.support.v4.view.WindowInsetsCompat;
|
|
import android.support.v7.view.menu.MenuBuilder;
|
|
import android.support.v7.view.menu.MenuItemImpl;
|
|
import android.support.v7.view.menu.MenuPresenter;
|
|
import android.support.v7.view.menu.MenuView;
|
|
import android.support.v7.view.menu.SubMenuBuilder;
|
|
import android.support.v7.widget.RecyclerView;
|
|
import android.util.SparseArray;
|
|
import android.view.LayoutInflater;
|
|
import android.view.SubMenu;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.LinearLayout;
|
|
import android.widget.TextView;
|
|
import java.util.ArrayList;
|
|
|
|
/** @hide */
|
|
@RestrictTo(LIBRARY_GROUP)
|
|
public class NavigationMenuPresenter implements MenuPresenter {
|
|
|
|
private static final String STATE_HIERARCHY = "android:menu:list";
|
|
private static final String STATE_ADAPTER = "android:menu:adapter";
|
|
private static final String STATE_HEADER = "android:menu:header";
|
|
|
|
private NavigationMenuView menuView;
|
|
LinearLayout headerLayout;
|
|
|
|
private Callback callback;
|
|
MenuBuilder menu;
|
|
private int id;
|
|
|
|
NavigationMenuAdapter adapter;
|
|
LayoutInflater layoutInflater;
|
|
|
|
int textAppearance;
|
|
boolean textAppearanceSet;
|
|
ColorStateList textColor;
|
|
ColorStateList iconTintList;
|
|
Drawable itemBackground;
|
|
int itemHorizontalPadding;
|
|
int itemIconPadding;
|
|
|
|
/**
|
|
* Padding to be inserted at the top of the list to avoid the first menu item from being placed
|
|
* underneath the status bar.
|
|
*/
|
|
private int paddingTopDefault;
|
|
|
|
/** Padding for separators between items */
|
|
int paddingSeparator;
|
|
|
|
@Override
|
|
public void initForMenu(Context context, MenuBuilder menu) {
|
|
layoutInflater = LayoutInflater.from(context);
|
|
this.menu = menu;
|
|
Resources res = context.getResources();
|
|
paddingSeparator =
|
|
res.getDimensionPixelOffset(R.dimen.design_navigation_separator_vertical_padding);
|
|
}
|
|
|
|
@Override
|
|
public MenuView getMenuView(ViewGroup root) {
|
|
if (menuView == null) {
|
|
menuView =
|
|
(NavigationMenuView) layoutInflater.inflate(R.layout.design_navigation_menu, root, false);
|
|
if (adapter == null) {
|
|
adapter = new NavigationMenuAdapter();
|
|
}
|
|
headerLayout =
|
|
(LinearLayout)
|
|
layoutInflater.inflate(R.layout.design_navigation_item_header, menuView, false);
|
|
menuView.setAdapter(adapter);
|
|
}
|
|
return menuView;
|
|
}
|
|
|
|
@Override
|
|
public void updateMenuView(boolean cleared) {
|
|
if (adapter != null) {
|
|
adapter.update();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void setCallback(Callback cb) {
|
|
callback = cb;
|
|
}
|
|
|
|
@Override
|
|
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
|
|
if (callback != null) {
|
|
callback.onCloseMenu(menu, allMenusAreClosing);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean flagActionItems() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int getId() {
|
|
return id;
|
|
}
|
|
|
|
public void setId(int id) {
|
|
this.id = id;
|
|
}
|
|
|
|
@Override
|
|
public Parcelable onSaveInstanceState() {
|
|
final Bundle state = new Bundle();
|
|
if (menuView != null) {
|
|
SparseArray<Parcelable> hierarchy = new SparseArray<>();
|
|
menuView.saveHierarchyState(hierarchy);
|
|
state.putSparseParcelableArray(STATE_HIERARCHY, hierarchy);
|
|
}
|
|
if (adapter != null) {
|
|
state.putBundle(STATE_ADAPTER, adapter.createInstanceState());
|
|
}
|
|
if (headerLayout != null) {
|
|
SparseArray<Parcelable> header = new SparseArray<>();
|
|
headerLayout.saveHierarchyState(header);
|
|
state.putSparseParcelableArray(STATE_HEADER, header);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public void onRestoreInstanceState(final Parcelable parcelable) {
|
|
if (parcelable instanceof Bundle) {
|
|
Bundle state = (Bundle) parcelable;
|
|
SparseArray<Parcelable> hierarchy = state.getSparseParcelableArray(STATE_HIERARCHY);
|
|
if (hierarchy != null) {
|
|
menuView.restoreHierarchyState(hierarchy);
|
|
}
|
|
Bundle adapterState = state.getBundle(STATE_ADAPTER);
|
|
if (adapterState != null) {
|
|
adapter.restoreInstanceState(adapterState);
|
|
}
|
|
SparseArray<Parcelable> header = state.getSparseParcelableArray(STATE_HEADER);
|
|
if (header != null) {
|
|
headerLayout.restoreHierarchyState(header);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setCheckedItem(MenuItemImpl item) {
|
|
adapter.setCheckedItem(item);
|
|
}
|
|
|
|
public View inflateHeaderView(@LayoutRes int res) {
|
|
View view = layoutInflater.inflate(res, headerLayout, false);
|
|
addHeaderView(view);
|
|
return view;
|
|
}
|
|
|
|
public void addHeaderView(@NonNull View view) {
|
|
headerLayout.addView(view);
|
|
// The padding on top should be cleared.
|
|
menuView.setPadding(0, 0, 0, menuView.getPaddingBottom());
|
|
}
|
|
|
|
public void removeHeaderView(@NonNull View view) {
|
|
headerLayout.removeView(view);
|
|
if (headerLayout.getChildCount() == 0) {
|
|
menuView.setPadding(0, paddingTopDefault, 0, menuView.getPaddingBottom());
|
|
}
|
|
}
|
|
|
|
public int getHeaderCount() {
|
|
return headerLayout.getChildCount();
|
|
}
|
|
|
|
public View getHeaderView(int index) {
|
|
return headerLayout.getChildAt(index);
|
|
}
|
|
|
|
@Nullable
|
|
public ColorStateList getItemTintList() {
|
|
return iconTintList;
|
|
}
|
|
|
|
public void setItemIconTintList(@Nullable ColorStateList tint) {
|
|
iconTintList = tint;
|
|
updateMenuView(false);
|
|
}
|
|
|
|
@Nullable
|
|
public ColorStateList getItemTextColor() {
|
|
return textColor;
|
|
}
|
|
|
|
public void setItemTextColor(@Nullable ColorStateList textColor) {
|
|
this.textColor = textColor;
|
|
updateMenuView(false);
|
|
}
|
|
|
|
public void setItemTextAppearance(@StyleRes int resId) {
|
|
textAppearance = resId;
|
|
textAppearanceSet = true;
|
|
updateMenuView(false);
|
|
}
|
|
|
|
@Nullable
|
|
public Drawable getItemBackground() {
|
|
return itemBackground;
|
|
}
|
|
|
|
public void setItemBackground(@Nullable Drawable itemBackground) {
|
|
this.itemBackground = itemBackground;
|
|
updateMenuView(false);
|
|
}
|
|
|
|
public int getItemHorizontalPadding() {
|
|
return itemHorizontalPadding;
|
|
}
|
|
|
|
public void setItemHorizontalPadding(int itemHorizontalPadding) {
|
|
this.itemHorizontalPadding = itemHorizontalPadding;
|
|
updateMenuView(false);
|
|
}
|
|
|
|
public int getItemIconPadding() {
|
|
return itemIconPadding;
|
|
}
|
|
|
|
public void setItemIconPadding(int itemIconPadding) {
|
|
this.itemIconPadding = itemIconPadding;
|
|
updateMenuView(false);
|
|
}
|
|
|
|
public void setUpdateSuspended(boolean updateSuspended) {
|
|
if (adapter != null) {
|
|
adapter.setUpdateSuspended(updateSuspended);
|
|
}
|
|
}
|
|
|
|
public void dispatchApplyWindowInsets(WindowInsetsCompat insets) {
|
|
int top = insets.getSystemWindowInsetTop();
|
|
if (paddingTopDefault != top) {
|
|
paddingTopDefault = top;
|
|
if (headerLayout.getChildCount() == 0) {
|
|
menuView.setPadding(0, paddingTopDefault, 0, menuView.getPaddingBottom());
|
|
}
|
|
}
|
|
ViewCompat.dispatchApplyWindowInsets(headerLayout, insets);
|
|
}
|
|
|
|
private abstract static class ViewHolder extends RecyclerView.ViewHolder {
|
|
|
|
public ViewHolder(View itemView) {
|
|
super(itemView);
|
|
}
|
|
}
|
|
|
|
private static class NormalViewHolder extends ViewHolder {
|
|
|
|
public NormalViewHolder(
|
|
LayoutInflater inflater, ViewGroup parent, View.OnClickListener listener) {
|
|
super(inflater.inflate(R.layout.design_navigation_item, parent, false));
|
|
itemView.setOnClickListener(listener);
|
|
}
|
|
}
|
|
|
|
private static class SubheaderViewHolder extends ViewHolder {
|
|
|
|
public SubheaderViewHolder(LayoutInflater inflater, ViewGroup parent) {
|
|
super(inflater.inflate(R.layout.design_navigation_item_subheader, parent, false));
|
|
}
|
|
}
|
|
|
|
private static class SeparatorViewHolder extends ViewHolder {
|
|
|
|
public SeparatorViewHolder(LayoutInflater inflater, ViewGroup parent) {
|
|
super(inflater.inflate(R.layout.design_navigation_item_separator, parent, false));
|
|
}
|
|
}
|
|
|
|
private static class HeaderViewHolder extends ViewHolder {
|
|
|
|
public HeaderViewHolder(View itemView) {
|
|
super(itemView);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles click events for the menu items. The items has to be {@link NavigationMenuItemView}.
|
|
*/
|
|
final View.OnClickListener onClickListener =
|
|
new View.OnClickListener() {
|
|
|
|
@Override
|
|
public void onClick(View v) {
|
|
NavigationMenuItemView itemView = (NavigationMenuItemView) v;
|
|
setUpdateSuspended(true);
|
|
MenuItemImpl item = itemView.getItemData();
|
|
boolean result = menu.performItemAction(item, NavigationMenuPresenter.this, 0);
|
|
if (item != null && item.isCheckable() && result) {
|
|
adapter.setCheckedItem(item);
|
|
}
|
|
setUpdateSuspended(false);
|
|
updateMenuView(false);
|
|
}
|
|
};
|
|
|
|
private class NavigationMenuAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|
|
|
private static final String STATE_CHECKED_ITEM = "android:menu:checked";
|
|
|
|
private static final String STATE_ACTION_VIEWS = "android:menu:action_views";
|
|
private static final int VIEW_TYPE_NORMAL = 0;
|
|
private static final int VIEW_TYPE_SUBHEADER = 1;
|
|
private static final int VIEW_TYPE_SEPARATOR = 2;
|
|
private static final int VIEW_TYPE_HEADER = 3;
|
|
|
|
private final ArrayList<NavigationMenuItem> items = new ArrayList<>();
|
|
private MenuItemImpl checkedItem;
|
|
private boolean updateSuspended;
|
|
|
|
NavigationMenuAdapter() {
|
|
prepareMenuItems();
|
|
}
|
|
|
|
@Override
|
|
public long getItemId(int position) {
|
|
return position;
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount() {
|
|
return items.size();
|
|
}
|
|
|
|
@Override
|
|
public int getItemViewType(int position) {
|
|
NavigationMenuItem item = items.get(position);
|
|
if (item instanceof NavigationMenuSeparatorItem) {
|
|
return VIEW_TYPE_SEPARATOR;
|
|
} else if (item instanceof NavigationMenuHeaderItem) {
|
|
return VIEW_TYPE_HEADER;
|
|
} else if (item instanceof NavigationMenuTextItem) {
|
|
NavigationMenuTextItem textItem = (NavigationMenuTextItem) item;
|
|
if (textItem.getMenuItem().hasSubMenu()) {
|
|
return VIEW_TYPE_SUBHEADER;
|
|
} else {
|
|
return VIEW_TYPE_NORMAL;
|
|
}
|
|
}
|
|
throw new RuntimeException("Unknown item type.");
|
|
}
|
|
|
|
@Override
|
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
switch (viewType) {
|
|
case VIEW_TYPE_NORMAL:
|
|
return new NormalViewHolder(layoutInflater, parent, onClickListener);
|
|
case VIEW_TYPE_SUBHEADER:
|
|
return new SubheaderViewHolder(layoutInflater, parent);
|
|
case VIEW_TYPE_SEPARATOR:
|
|
return new SeparatorViewHolder(layoutInflater, parent);
|
|
case VIEW_TYPE_HEADER:
|
|
return new HeaderViewHolder(headerLayout);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
|
switch (getItemViewType(position)) {
|
|
case VIEW_TYPE_NORMAL:
|
|
{
|
|
NavigationMenuItemView itemView = (NavigationMenuItemView) holder.itemView;
|
|
itemView.setIconTintList(iconTintList);
|
|
if (textAppearanceSet) {
|
|
itemView.setTextAppearance(textAppearance);
|
|
}
|
|
if (textColor != null) {
|
|
itemView.setTextColor(textColor);
|
|
}
|
|
ViewCompat.setBackground(
|
|
itemView,
|
|
itemBackground != null ? itemBackground.getConstantState().newDrawable() : null);
|
|
NavigationMenuTextItem item = (NavigationMenuTextItem) items.get(position);
|
|
itemView.setNeedsEmptyIcon(item.needsEmptyIcon);
|
|
itemView.setHorizontalPadding(itemHorizontalPadding);
|
|
itemView.setIconPadding(itemIconPadding);
|
|
itemView.initialize(item.getMenuItem(), 0);
|
|
break;
|
|
}
|
|
case VIEW_TYPE_SUBHEADER:
|
|
{
|
|
TextView subHeader = (TextView) holder.itemView;
|
|
NavigationMenuTextItem item = (NavigationMenuTextItem) items.get(position);
|
|
subHeader.setText(item.getMenuItem().getTitle());
|
|
break;
|
|
}
|
|
case VIEW_TYPE_SEPARATOR:
|
|
{
|
|
NavigationMenuSeparatorItem item = (NavigationMenuSeparatorItem) items.get(position);
|
|
holder.itemView.setPadding(0, item.getPaddingTop(), 0, item.getPaddingBottom());
|
|
break;
|
|
}
|
|
case VIEW_TYPE_HEADER:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onViewRecycled(ViewHolder holder) {
|
|
if (holder instanceof NormalViewHolder) {
|
|
((NavigationMenuItemView) holder.itemView).recycle();
|
|
}
|
|
}
|
|
|
|
public void update() {
|
|
prepareMenuItems();
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
/**
|
|
* Flattens the visible menu items of {@link #menu} into {@link #items}, while inserting
|
|
* separators between items when necessary.
|
|
*/
|
|
private void prepareMenuItems() {
|
|
if (updateSuspended) {
|
|
return;
|
|
}
|
|
updateSuspended = true;
|
|
items.clear();
|
|
items.add(new NavigationMenuHeaderItem());
|
|
|
|
int currentGroupId = -1;
|
|
int currentGroupStart = 0;
|
|
boolean currentGroupHasIcon = false;
|
|
for (int i = 0, totalSize = menu.getVisibleItems().size(); i < totalSize; i++) {
|
|
MenuItemImpl item = menu.getVisibleItems().get(i);
|
|
if (item.isChecked()) {
|
|
setCheckedItem(item);
|
|
}
|
|
if (item.isCheckable()) {
|
|
item.setExclusiveCheckable(false);
|
|
}
|
|
if (item.hasSubMenu()) {
|
|
SubMenu subMenu = item.getSubMenu();
|
|
if (subMenu.hasVisibleItems()) {
|
|
if (i != 0) {
|
|
items.add(new NavigationMenuSeparatorItem(paddingSeparator, 0));
|
|
}
|
|
items.add(new NavigationMenuTextItem(item));
|
|
boolean subMenuHasIcon = false;
|
|
int subMenuStart = items.size();
|
|
for (int j = 0, size = subMenu.size(); j < size; j++) {
|
|
MenuItemImpl subMenuItem = (MenuItemImpl) subMenu.getItem(j);
|
|
if (subMenuItem.isVisible()) {
|
|
if (!subMenuHasIcon && subMenuItem.getIcon() != null) {
|
|
subMenuHasIcon = true;
|
|
}
|
|
if (subMenuItem.isCheckable()) {
|
|
subMenuItem.setExclusiveCheckable(false);
|
|
}
|
|
if (item.isChecked()) {
|
|
setCheckedItem(item);
|
|
}
|
|
items.add(new NavigationMenuTextItem(subMenuItem));
|
|
}
|
|
}
|
|
if (subMenuHasIcon) {
|
|
appendTransparentIconIfMissing(subMenuStart, items.size());
|
|
}
|
|
}
|
|
} else {
|
|
int groupId = item.getGroupId();
|
|
if (groupId != currentGroupId) { // first item in group
|
|
currentGroupStart = items.size();
|
|
currentGroupHasIcon = item.getIcon() != null;
|
|
if (i != 0) {
|
|
currentGroupStart++;
|
|
items.add(new NavigationMenuSeparatorItem(paddingSeparator, paddingSeparator));
|
|
}
|
|
} else if (!currentGroupHasIcon && item.getIcon() != null) {
|
|
currentGroupHasIcon = true;
|
|
appendTransparentIconIfMissing(currentGroupStart, items.size());
|
|
}
|
|
NavigationMenuTextItem textItem = new NavigationMenuTextItem(item);
|
|
textItem.needsEmptyIcon = currentGroupHasIcon;
|
|
items.add(textItem);
|
|
currentGroupId = groupId;
|
|
}
|
|
}
|
|
updateSuspended = false;
|
|
}
|
|
|
|
private void appendTransparentIconIfMissing(int startIndex, int endIndex) {
|
|
for (int i = startIndex; i < endIndex; i++) {
|
|
NavigationMenuTextItem textItem = (NavigationMenuTextItem) items.get(i);
|
|
textItem.needsEmptyIcon = true;
|
|
}
|
|
}
|
|
|
|
public void setCheckedItem(MenuItemImpl checkedItem) {
|
|
if (this.checkedItem == checkedItem || !checkedItem.isCheckable()) {
|
|
return;
|
|
}
|
|
if (this.checkedItem != null) {
|
|
this.checkedItem.setChecked(false);
|
|
}
|
|
this.checkedItem = checkedItem;
|
|
checkedItem.setChecked(true);
|
|
}
|
|
|
|
public Bundle createInstanceState() {
|
|
Bundle state = new Bundle();
|
|
if (checkedItem != null) {
|
|
state.putInt(STATE_CHECKED_ITEM, checkedItem.getItemId());
|
|
}
|
|
// Store the states of the action views.
|
|
SparseArray<ParcelableSparseArray> actionViewStates = new SparseArray<>();
|
|
for (int i = 0, size = items.size(); i < size; i++) {
|
|
NavigationMenuItem navigationMenuItem = items.get(i);
|
|
if (navigationMenuItem instanceof NavigationMenuTextItem) {
|
|
MenuItemImpl item = ((NavigationMenuTextItem) navigationMenuItem).getMenuItem();
|
|
View actionView = item != null ? item.getActionView() : null;
|
|
if (actionView != null) {
|
|
ParcelableSparseArray container = new ParcelableSparseArray();
|
|
actionView.saveHierarchyState(container);
|
|
actionViewStates.put(item.getItemId(), container);
|
|
}
|
|
}
|
|
}
|
|
state.putSparseParcelableArray(STATE_ACTION_VIEWS, actionViewStates);
|
|
return state;
|
|
}
|
|
|
|
public void restoreInstanceState(Bundle state) {
|
|
int checkedItem = state.getInt(STATE_CHECKED_ITEM, 0);
|
|
if (checkedItem != 0) {
|
|
updateSuspended = true;
|
|
for (int i = 0, size = items.size(); i < size; i++) {
|
|
NavigationMenuItem item = items.get(i);
|
|
if (item instanceof NavigationMenuTextItem) {
|
|
MenuItemImpl menuItem = ((NavigationMenuTextItem) item).getMenuItem();
|
|
if (menuItem != null && menuItem.getItemId() == checkedItem) {
|
|
setCheckedItem(menuItem);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
updateSuspended = false;
|
|
prepareMenuItems();
|
|
}
|
|
// Restore the states of the action views.
|
|
SparseArray<ParcelableSparseArray> actionViewStates =
|
|
state.getSparseParcelableArray(STATE_ACTION_VIEWS);
|
|
if (actionViewStates != null) {
|
|
for (int i = 0, size = items.size(); i < size; i++) {
|
|
NavigationMenuItem navigationMenuItem = items.get(i);
|
|
if (!(navigationMenuItem instanceof NavigationMenuTextItem)) {
|
|
continue;
|
|
}
|
|
MenuItemImpl item = ((NavigationMenuTextItem) navigationMenuItem).getMenuItem();
|
|
if (item == null) {
|
|
continue;
|
|
}
|
|
View actionView = item.getActionView();
|
|
if (actionView == null) {
|
|
continue;
|
|
}
|
|
ParcelableSparseArray container = actionViewStates.get(item.getItemId());
|
|
if (container == null) {
|
|
continue;
|
|
}
|
|
actionView.restoreHierarchyState(container);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setUpdateSuspended(boolean updateSuspended) {
|
|
this.updateSuspended = updateSuspended;
|
|
}
|
|
}
|
|
|
|
/** Unified data model for all sorts of navigation menu items. */
|
|
private interface NavigationMenuItem {}
|
|
|
|
/** Normal or subheader items. */
|
|
private static class NavigationMenuTextItem implements NavigationMenuItem {
|
|
|
|
private final MenuItemImpl menuItem;
|
|
|
|
boolean needsEmptyIcon;
|
|
|
|
NavigationMenuTextItem(MenuItemImpl item) {
|
|
menuItem = item;
|
|
}
|
|
|
|
public MenuItemImpl getMenuItem() {
|
|
return menuItem;
|
|
}
|
|
}
|
|
|
|
/** Separator items. */
|
|
private static class NavigationMenuSeparatorItem implements NavigationMenuItem {
|
|
|
|
private final int paddingTop;
|
|
|
|
private final int paddingBottom;
|
|
|
|
public NavigationMenuSeparatorItem(int paddingTop, int paddingBottom) {
|
|
this.paddingTop = paddingTop;
|
|
this.paddingBottom = paddingBottom;
|
|
}
|
|
|
|
public int getPaddingTop() {
|
|
return paddingTop;
|
|
}
|
|
|
|
public int getPaddingBottom() {
|
|
return paddingBottom;
|
|
}
|
|
}
|
|
|
|
/** Header (not subheader) items. */
|
|
private static class NavigationMenuHeaderItem implements NavigationMenuItem {
|
|
NavigationMenuHeaderItem() {}
|
|
// The actual content is hold by NavigationMenuPresenter#mHeaderLayout.
|
|
}
|
|
}
|