Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bce6ab8 authored by Alan Viverette's avatar Alan Viverette
Browse files

Optimize width measurement and cache result in MenuPopupHelper

BUG: 9591217
Change-Id: I0cc2fad39f967e92b2c954f6417430a42dce8e43
parent 066bdcfe
Loading
Loading
Loading
Loading
+43 −22
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.internal.view.menu;

import android.content.Context;
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.os.Parcelable;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -47,23 +46,28 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On

    static final int ITEM_LAYOUT = com.android.internal.R.layout.popup_menu_item_layout;

    private Context mContext;
    private LayoutInflater mInflater;
    private ListPopupWindow mPopup;
    private MenuBuilder mMenu;
    private int mPopupMaxWidth;
    private final Context mContext;
    private final LayoutInflater mInflater;
    private final MenuBuilder mMenu;
    private final MenuAdapter mAdapter;
    private final boolean mOverflowOnly;
    private final int mPopupMaxWidth;

    private View mAnchorView;
    private boolean mOverflowOnly;
    private ListPopupWindow mPopup;
    private ViewTreeObserver mTreeObserver;

    private MenuAdapter mAdapter;

    private Callback mPresenterCallback;

    boolean mForceShowIcon;

    private ViewGroup mMeasureParent;

    /** Whether the cached content width value is valid. */
    private boolean mHasContentWidth;

    /** Cached content width from {@link #measureContentWidth}. */
    private int mContentWidth;

    public MenuPopupHelper(Context context, MenuBuilder menu) {
        this(context, menu, null, false);
    }
@@ -77,6 +81,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mMenu = menu;
        mAdapter = new MenuAdapter(mMenu);
        mOverflowOnly = overflowOnly;

        final Resources res = context.getResources();
@@ -106,8 +111,6 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
        mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle);
        mPopup.setOnDismissListener(this);
        mPopup.setOnItemClickListener(this);

        mAdapter = new MenuAdapter(mMenu);
        mPopup.setAdapter(mAdapter);
        mPopup.setModal(true);

@@ -122,7 +125,12 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
            return false;
        }

        mPopup.setContentWidth(Math.min(measureContentWidth(mAdapter), mPopupMaxWidth));
        if (!mHasContentWidth) {
            mContentWidth = measureContentWidth();
            mHasContentWidth = true;
        }

        mPopup.setContentWidth(mContentWidth);
        mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
        mPopup.show();
        mPopup.getListView().setOnKeyListener(this);
@@ -164,15 +172,15 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
        return false;
    }

    private int measureContentWidth(ListAdapter adapter) {
    private int measureContentWidth() {
        // Menus don't tend to be long, so this is more sane than it looks.
        int width = 0;
        int maxWidth = 0;
        View itemView = null;
        int itemType = 0;
        final int widthMeasureSpec =
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        final int heightMeasureSpec =
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

        final ListAdapter adapter = mAdapter;
        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        final int count = adapter.getCount();
        for (int i = 0; i < count; i++) {
            final int positionType = adapter.getItemViewType(i);
@@ -180,14 +188,23 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
                itemType = positionType;
                itemView = null;
            }

            if (mMeasureParent == null) {
                mMeasureParent = new FrameLayout(mContext);
            }

            itemView = adapter.getView(i, itemView, mMeasureParent);
            itemView.measure(widthMeasureSpec, heightMeasureSpec);
            width = Math.max(width, itemView.getMeasuredWidth());

            final int itemWidth = itemView.getMeasuredWidth();
            if (itemWidth >= mPopupMaxWidth) {
                return mPopupMaxWidth;
            } else if (itemWidth > maxWidth) {
                maxWidth = itemWidth;
            }
        }
        return width;

        return maxWidth;
    }

    @Override
@@ -228,7 +245,11 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On

    @Override
    public void updateMenuView(boolean cleared) {
        if (mAdapter != null) mAdapter.notifyDataSetChanged();
        mHasContentWidth = false;

        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override