ActionBarContextView.java revision a7db03705f53c59e63e63c2e67e2db78f8226dcc
189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell/*
289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * Copyright (C) 2010 The Android Open Source Project
389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell *
489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * you may not use this file except in compliance with the License.
689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * You may obtain a copy of the License at
789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell *
889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell *
1089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * Unless required by applicable law or agreed to in writing, software
1189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
1289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * See the License for the specific language governing permissions and
1489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * limitations under the License.
1589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell */
1689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellpackage com.android.internal.widget;
1789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
1889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport com.android.internal.R;
1989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport com.android.internal.app.ActionBarImpl;
2089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
2189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.app.ActionBar;
2289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.content.Context;
2389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.content.res.TypedArray;
2489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.graphics.drawable.Drawable;
2589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.util.AttributeSet;
2689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.view.LayoutInflater;
2789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.view.Menu;
2889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.view.MenuItem;
2989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.view.View;
3089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.view.ViewGroup;
31a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powellimport android.view.View.MeasureSpec;
32a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powellimport android.view.ViewGroup.LayoutParams;
3389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.widget.ImageButton;
340e94b5151d817e600a888448a662208b29b5ef46Adam Powellimport android.widget.LinearLayout;
3589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellimport android.widget.TextView;
3689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
3789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell/**
3889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell * @hide
3989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell */
4089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powellpublic class ActionBarContextView extends ViewGroup {
4189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    // TODO: This must be defined in the default theme
4289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private static final int CONTENT_HEIGHT_DIP = 50;
4389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
4489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private int mItemPadding;
4589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private int mItemMargin;
4689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private int mContentHeight;
4789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
4889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private CharSequence mTitle;
4989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private CharSequence mSubtitle;
5089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
5189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private ImageButton mCloseButton;
5289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private View mCustomView;
530e94b5151d817e600a888448a662208b29b5ef46Adam Powell    private LinearLayout mTitleLayout;
5489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private TextView mTitleView;
550e94b5151d817e600a888448a662208b29b5ef46Adam Powell    private TextView mSubtitleView;
5689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private Drawable mCloseDrawable;
5789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
5889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public ActionBarContextView(Context context) {
5989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        this(context, null, 0);
6089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
6189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
6289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public ActionBarContextView(Context context, AttributeSet attrs) {
6389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        this(context, attrs, 0);
6489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
6589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
6689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) {
6789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        super(context, attrs, defStyle);
6889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
6989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        TypedArray a = context.obtainStyledAttributes(attrs,
7089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                com.android.internal.R.styleable.Theme);
7189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mItemPadding = a.getDimensionPixelOffset(
7289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                com.android.internal.R.styleable.Theme_actionButtonPadding, 0);
7389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        setBackgroundDrawable(a.getDrawable(
7489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                com.android.internal.R.styleable.Theme_actionBarContextBackground));
7589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mCloseDrawable = a.getDrawable(
7689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                com.android.internal.R.styleable.Theme_actionBarCloseContextDrawable);
7789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mItemMargin = mItemPadding / 2;
7889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
7989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mContentHeight = CONTENT_HEIGHT_DIP;
8089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        a.recycle();
8189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
8289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
8389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public void setCustomView(View view) {
8489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (mCustomView != null) {
8589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            removeView(mCustomView);
8689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
8789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mCustomView = view;
880e94b5151d817e600a888448a662208b29b5ef46Adam Powell        if (mTitleLayout != null) {
890e94b5151d817e600a888448a662208b29b5ef46Adam Powell            removeView(mTitleLayout);
900e94b5151d817e600a888448a662208b29b5ef46Adam Powell            mTitleLayout = null;
9189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
9289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (view != null) {
9389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            addView(view);
9489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
9589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        requestLayout();
9689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
970e94b5151d817e600a888448a662208b29b5ef46Adam Powell
9889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public void setTitle(CharSequence title) {
9989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mTitle = title;
1000e94b5151d817e600a888448a662208b29b5ef46Adam Powell        initTitle();
1010e94b5151d817e600a888448a662208b29b5ef46Adam Powell    }
1020e94b5151d817e600a888448a662208b29b5ef46Adam Powell
1030e94b5151d817e600a888448a662208b29b5ef46Adam Powell    public void setSubtitle(CharSequence subtitle) {
1040e94b5151d817e600a888448a662208b29b5ef46Adam Powell        mSubtitle = subtitle;
1050e94b5151d817e600a888448a662208b29b5ef46Adam Powell        initTitle();
1060e94b5151d817e600a888448a662208b29b5ef46Adam Powell    }
1070e94b5151d817e600a888448a662208b29b5ef46Adam Powell
1080e94b5151d817e600a888448a662208b29b5ef46Adam Powell    private void initTitle() {
1090e94b5151d817e600a888448a662208b29b5ef46Adam Powell        if (mTitleLayout == null) {
11089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            LayoutInflater inflater = LayoutInflater.from(getContext());
1110e94b5151d817e600a888448a662208b29b5ef46Adam Powell            mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item, null);
1120e94b5151d817e600a888448a662208b29b5ef46Adam Powell            mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
1130e94b5151d817e600a888448a662208b29b5ef46Adam Powell            mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
1140e94b5151d817e600a888448a662208b29b5ef46Adam Powell            if (mTitle != null) {
1150e94b5151d817e600a888448a662208b29b5ef46Adam Powell                mTitleView.setText(mTitle);
1160e94b5151d817e600a888448a662208b29b5ef46Adam Powell            }
1170e94b5151d817e600a888448a662208b29b5ef46Adam Powell            if (mSubtitle != null) {
1180e94b5151d817e600a888448a662208b29b5ef46Adam Powell                mSubtitleView.setText(mSubtitle);
11989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            }
1200e94b5151d817e600a888448a662208b29b5ef46Adam Powell            addView(mTitleLayout);
12189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        } else {
1220e94b5151d817e600a888448a662208b29b5ef46Adam Powell            mTitleView.setText(mTitle);
1230e94b5151d817e600a888448a662208b29b5ef46Adam Powell            mSubtitleView.setText(mSubtitle);
1240e94b5151d817e600a888448a662208b29b5ef46Adam Powell            if (mTitleLayout.getParent() == null) {
1250e94b5151d817e600a888448a662208b29b5ef46Adam Powell                addView(mTitleLayout);
12689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            }
12789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
12889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
1290e94b5151d817e600a888448a662208b29b5ef46Adam Powell
13089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public void initForMode(final ActionBar.ContextMode mode) {
13189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final ActionBarImpl.ContextMode implMode = (ActionBarImpl.ContextMode) mode;
13289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
13389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (mCloseButton == null) {
13489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            mCloseButton = new ImageButton(getContext());
13589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            mCloseButton.setImageDrawable(mCloseDrawable);
13689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            mCloseButton.setBackgroundDrawable(null);
13789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            mCloseButton.setOnClickListener(new OnClickListener() {
13889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                public void onClick(View v) {
13989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    mode.finish();
14089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                }
14189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            });
14289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
14389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        addView(mCloseButton);
14489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
14589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final Context context = getContext();
14689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final Menu menu = mode.getMenu();
14789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int itemCount = menu.size();
14889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        for (int i = 0; i < itemCount; i++) {
14989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            final MenuItem item = menu.getItem(i);
15089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            final ImageButton button = new ImageButton(context, null,
15189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    com.android.internal.R.attr.actionButtonStyle);
15289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setClickable(true);
15389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setFocusable(true);
15489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setImageDrawable(item.getIcon());
15589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setId(item.getItemId());
15689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setVisibility(item.isVisible() ? VISIBLE : GONE);
15789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setEnabled(item.isEnabled());
15889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
15989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            button.setOnClickListener(new OnClickListener() {
16089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                public void onClick(View v) {
16189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    implMode.dispatchOnContextItemClicked(item);
16289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                }
16389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            });
1640e94b5151d817e600a888448a662208b29b5ef46Adam Powell
16589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            addView(button);
16689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
16789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        requestLayout();
16889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
1690e94b5151d817e600a888448a662208b29b5ef46Adam Powell
17089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    public void closeMode() {
17189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        removeAllViews();
17289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        mCustomView = null;
17389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
1740e94b5151d817e600a888448a662208b29b5ef46Adam Powell
17589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    @Override
176a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell    protected LayoutParams generateDefaultLayoutParams() {
177a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell        // Used by custom views if they don't supply layout params. Everything else
178a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell        // added to an ActionBarContextView should have them already.
179a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
180a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell    }
181a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell
182a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell    @Override
18389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
18489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
18589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (widthMode != MeasureSpec.EXACTLY) {
18689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
18789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    "with android:layout_width=\"match_parent\" (or fill_parent)");
18889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
18989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
19089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
19189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (heightMode != MeasureSpec.AT_MOST) {
19289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
19389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    "with android:layout_height=\"wrap_content\"");
19489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
19589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
19689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
19789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int itemMargin = mItemPadding;
19889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
19989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
20089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int height = mContentHeight - getPaddingTop() - getPaddingBottom();
20189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
20289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
20389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (mCloseButton != null) {
20489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            availableWidth = measureChildView(mCloseButton, availableWidth,
20589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    childSpecHeight, itemMargin);
20689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
20789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
2080e94b5151d817e600a888448a662208b29b5ef46Adam Powell        if (mTitleLayout != null && mCustomView == null) {
2090e94b5151d817e600a888448a662208b29b5ef46Adam Powell            availableWidth = measureChildView(mTitleLayout, availableWidth,
21089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                    childSpecHeight, itemMargin);
21189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
21289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
21389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int childCount = getChildCount();
21489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        for (int i = 0; i < childCount; i++) {
21589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            final View child = getChildAt(i);
2160e94b5151d817e600a888448a662208b29b5ef46Adam Powell            if (child == mCloseButton || child == mTitleLayout || child == mCustomView) {
21789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                continue;
21889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            }
21989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
22089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            availableWidth = measureChildView(child, availableWidth, childSpecHeight, itemMargin);
22189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
22289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
22389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (mCustomView != null) {
224a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell            LayoutParams lp = mCustomView.getLayoutParams();
225a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell            final int customWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
226a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell                    MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
227a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell            final int customWidth = lp.width >= 0 ?
228a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell                    Math.min(lp.width, availableWidth) : availableWidth;
229a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell            final int customHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
230a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell                    MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
231a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell            final int customHeight = lp.height >= 0 ?
232a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell                    Math.min(lp.height, height) : height;
233a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell            mCustomView.measure(MeasureSpec.makeMeasureSpec(customWidth, customWidthMode),
234a7db03705f53c59e63e63c2e67e2db78f8226dccAdam Powell                    MeasureSpec.makeMeasureSpec(customHeight, customHeightMode));
23589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
23689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
23789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        setMeasuredDimension(contentWidth, mContentHeight);
23889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
23989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
24089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    @Override
24189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    protected void onLayout(boolean changed, int l, int t, int r, int b) {
24289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int x = getPaddingLeft();
24389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int y = getPaddingTop();
24489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
24589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int itemMargin = mItemPadding;
24689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
24789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (mCloseButton != null && mCloseButton.getVisibility() != GONE) {
24889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            x += positionChild(mCloseButton, x, y, contentHeight);
24989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
25089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
2510e94b5151d817e600a888448a662208b29b5ef46Adam Powell        if (mTitleLayout != null && mCustomView == null) {
2520e94b5151d817e600a888448a662208b29b5ef46Adam Powell            x += positionChild(mTitleLayout, x, y, contentHeight) + itemMargin;
25389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
25489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
25589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        if (mCustomView != null) {
25689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            x += positionChild(mCustomView, x, y, contentHeight) + itemMargin;
25789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
25889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
25989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        x = r - l - getPaddingRight();
26089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
26189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        final int childCount = getChildCount();
26289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        for (int i = 0; i < childCount; i++) {
26389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            final View child = getChildAt(i);
2640e94b5151d817e600a888448a662208b29b5ef46Adam Powell            if (child == mCloseButton || child == mTitleLayout || child == mCustomView) {
26589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                continue;
26689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            }
26789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
26889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell            x -= positionChildInverse(child, x, y, contentHeight) + itemMargin;
26989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        }
27089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
27189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
27289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private int measureChildView(View child, int availableWidth, int childSpecHeight, int spacing) {
27389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
27489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell                childSpecHeight);
27589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
27689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        availableWidth -= child.getMeasuredWidth();
27789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        availableWidth -= spacing;
27889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
27989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        return availableWidth;
28089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
28189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
28289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private int positionChild(View child, int x, int y, int contentHeight) {
28389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int childWidth = child.getMeasuredWidth();
28489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int childHeight = child.getMeasuredHeight();
28589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int childTop = y + (contentHeight - childHeight) / 2;
28689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
28789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        child.layout(x, childTop, x + childWidth, childTop + childHeight);
28889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
28989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        return childWidth;
29089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
29189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
29289e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    private int positionChildInverse(View child, int x, int y, int contentHeight) {
29389e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int childWidth = child.getMeasuredWidth();
29489e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int childHeight = child.getMeasuredHeight();
29589e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        int childTop = y + (contentHeight - childHeight) / 2;
29689e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
29789e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        child.layout(x - childWidth, childTop, x, childTop + childHeight);
29889e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell
29989e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell        return childWidth;
30089e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell    }
30189e0645b4157961e8c465eb9c819f965fdb453d8Adam Powell}
302