18262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns/*
28262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Copyright (C) 2013 The Android Open Source Project
38262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns *
48262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Licensed under the Apache License, Version 2.0 (the "License");
58262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * you may not use this file except in compliance with the License.
68262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * You may obtain a copy of the License at
78262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns *
88262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns *      http://www.apache.org/licenses/LICENSE-2.0
98262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns *
108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * Unless required by applicable law or agreed to in writing, software
118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * distributed under the License is distributed on an "AS IS" BASIS,
128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * See the License for the specific language governing permissions and
148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * limitations under the License.
158262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */
168262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
17da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.view.menu;
188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
198262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.content.Context;
208262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.database.DataSetObserver;
218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.os.Bundle;
228262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.os.Parcelable;
23da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R;
248262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.util.SparseArray;
258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.view.ContextThemeWrapper;
268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.view.LayoutInflater;
278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.view.View;
288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.view.ViewGroup;
298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.widget.AdapterView;
308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.widget.BaseAdapter;
318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport android.widget.ListAdapter;
328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
338262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnsimport java.util.ArrayList;
348262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
358262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns/**
368262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns * MenuPresenter for list-style menus.
3789208232f3b5d1451408d787872504a190bc7ee0Chris Banes *
3889208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide
398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns */
408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johnspublic class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClickListener {
418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    private static final String TAG = "ListMenuPresenter";
428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    Context mContext;
448262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    LayoutInflater mInflater;
458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    MenuBuilder mMenu;
468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    ExpandedMenuView mMenuView;
488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    private int mItemIndexOffset;
508262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    int mThemeRes;
518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    int mItemLayoutRes;
528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    private Callback mCallback;
548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    MenuAdapter mAdapter;
558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    private int mId;
578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public static final String VIEWS_TAG = "android:menu:list";
598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    /**
618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * Construct a new ListMenuPresenter.
628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * @param context Context to use for theming. This will supersede the context provided
638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     *                to initForMenu when this presenter is added.
648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * @param itemLayoutRes Layout resource for individual item views.
658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     */
668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public ListMenuPresenter(Context context, int itemLayoutRes) {
678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        this(itemLayoutRes, 0);
688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mContext = context;
698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mInflater = LayoutInflater.from(mContext);
708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    /**
738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * Construct a new ListMenuPresenter.
748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * @param itemLayoutRes Layout resource for individual item views.
758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * @param themeRes Resource ID of a theme to use for views.
768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     */
778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public ListMenuPresenter(int itemLayoutRes, int themeRes) {
788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mItemLayoutRes = itemLayoutRes;
798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mThemeRes = themeRes;
808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
828262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void initForMenu(Context context, MenuBuilder menu) {
848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mThemeRes != 0) {
858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mContext = new ContextThemeWrapper(context, mThemeRes);
868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mInflater = LayoutInflater.from(mContext);
878262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        } else if (mContext != null) {
888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mContext = context;
898262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            if (mInflater == null) {
908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                mInflater = LayoutInflater.from(mContext);
918262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            }
928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mMenu = menu;
948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mAdapter != null) {
958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mAdapter.notifyDataSetChanged();
968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
988262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
998262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1008262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public MenuView getMenuView(ViewGroup root) {
101edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes        if (mAdapter == null) {
102edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes            mAdapter = new MenuAdapter();
103edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes        }
104edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes
105edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes        if (!mAdapter.isEmpty()) {
106edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes            if (mMenuView == null) {
107edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes                mMenuView = (ExpandedMenuView) mInflater.inflate(
108ee7c9fb199e9b9af8d40a1f9e27d85465acf8301Chris Banes                        R.layout.abc_expanded_menu_layout, root, false);
109edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes                mMenuView.setAdapter(mAdapter);
110edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes                mMenuView.setOnItemClickListener(this);
1118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            }
112edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes            return mMenuView;
1138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
114edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes
115edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes        // If we reach here, the Menu is empty so we have nothing to display
116edfecc2a3aacac9a945a40c430a62f04c18d8f42Chris Banes        return null;
1178262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1198262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    /**
1208262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * Call this instead of getMenuView if you want to manage your own ListView.
1218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * For proper operation, the ListView hosting this adapter should add
1228262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * this presenter as an OnItemClickListener.
1238262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     *
1248262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     * @return A ListAdapter containing the items in the menu.
1258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns     */
1268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public ListAdapter getAdapter() {
1278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mAdapter == null) {
1288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mAdapter = new MenuAdapter();
1298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
1308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return mAdapter;
1318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1338262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1348262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void updateMenuView(boolean cleared) {
1358262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mAdapter != null) mAdapter.notifyDataSetChanged();
1368262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1378262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1388262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void setCallback(Callback cb) {
1408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mCallback = cb;
1418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1448262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
1458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (!subMenu.hasVisibleItems()) return false;
1468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        // The window manager will give us a token.
1488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        new MenuDialogHelper(subMenu).show(null);
1498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mCallback != null) {
1508262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mCallback.onOpenSubMenu(subMenu);
1518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
1528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return true;
1538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mCallback != null) {
1588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mCallback.onCloseMenu(menu, allMenusAreClosing);
1598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
1608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    int getItemIndexOffset() {
1638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return mItemIndexOffset;
1648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void setItemIndexOffset(int offset) {
1678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mItemIndexOffset = offset;
1688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mMenuView != null) {
1698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            updateMenuView(false);
1708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
1718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
1758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mMenu.performItemAction(mAdapter.getItem(position), 0);
1768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
1798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public boolean flagActionItems() {
1808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return false;
1818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1828262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
1848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return false;
1858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1878262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
1888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return false;
1898262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1918262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void saveHierarchyState(Bundle outState) {
1928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        SparseArray<Parcelable> viewStates = new SparseArray<Parcelable>();
1938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mMenuView != null) {
1948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            ((View) mMenuView).saveHierarchyState(viewStates);
1958262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
1968262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        outState.putSparseParcelableArray(VIEWS_TAG, viewStates);
1978262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
1988262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
1998262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void restoreHierarchyState(Bundle inState) {
2008262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG);
2018262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (viewStates != null) {
2028262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            ((View) mMenuView).restoreHierarchyState(viewStates);
2038262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2048262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
2058262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2068262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void setId(int id) {
2078262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        mId = id;
2088262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
2098262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2108262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
2118262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public int getId() {
2128262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return mId;
2138262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
2148262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2158262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
2168262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public Parcelable onSaveInstanceState() {
2178262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        if (mMenuView == null) {
2188262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            return null;
2198262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2208262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2218262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        Bundle state = new Bundle();
2228262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        saveHierarchyState(state);
2238262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        return state;
2248262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
2258262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2268262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    @Override
2278262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    public void onRestoreInstanceState(Parcelable state) {
2288262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        restoreHierarchyState((Bundle) state);
2298262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
2308262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2318262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    private class MenuAdapter extends BaseAdapter {
2328262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        private int mExpandedIndex = -1;
2338262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2348262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        public MenuAdapter() {
2358262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            findExpandedIndex();
2368262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2378262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2388262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        public int getCount() {
2398262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
2408262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            int count = items.size() - mItemIndexOffset;
2418262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            if (mExpandedIndex < 0) {
2428262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                return count;
2438262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            }
2448262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            return count - 1;
2458262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2468262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2478262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        public MenuItemImpl getItem(int position) {
2488262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
2498262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            position += mItemIndexOffset;
2508262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
2518262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                position++;
2528262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            }
2538262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            return items.get(position);
2548262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2558262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2568262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        public long getItemId(int position) {
2578262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            // Since a menu item's ID is optional, we'll use the position as an
2588262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            // ID for the item in the AdapterView
2598262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            return position;
2608262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2618262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2628262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        public View getView(int position, View convertView, ViewGroup parent) {
2638262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            if (convertView == null) {
2648262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                convertView = mInflater.inflate(mItemLayoutRes, parent, false);
2658262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            }
2668262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2678262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            MenuView.ItemView itemView = (MenuView.ItemView) convertView;
2688262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            itemView.initialize(getItem(position), 0);
2698262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            return convertView;
2708262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2718262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2728262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        void findExpandedIndex() {
2738262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            final MenuItemImpl expandedItem = mMenu.getExpandedItem();
2748262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            if (expandedItem != null) {
2758262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
2768262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                final int count = items.size();
2778262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                for (int i = 0; i < count; i++) {
2788262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                    final MenuItemImpl item = items.get(i);
2798262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                    if (item == expandedItem) {
2808262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                        mExpandedIndex = i;
2818262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                        return;
2828262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                    }
2838262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns                }
2848262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            }
2858262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            mExpandedIndex = -1;
2868262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2878262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns
2888262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        @Override
2898262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        public void notifyDataSetChanged() {
2908262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            findExpandedIndex();
2918262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns            super.notifyDataSetChanged();
2928262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns        }
2938262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns    }
2948262949c1a6b7e191020b31fc914972bb0b58ab0Trevor Johns}
295