AbsActionBarView.java revision 34b5c9580dd01b4428ab2c5990add571eaab6b13
1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/*
2bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Copyright (C) 2011 The Android Open Source Project
3bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * you may not use this file except in compliance with the License.
6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * You may obtain a copy of the License at
7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
8bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
10bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Unless required by applicable law or agreed to in writing, software
11bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * See the License for the specific language governing permissions and
14bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * limitations under the License.
15bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */
16bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpackage android.support.appcompat.widget;
17bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context;
19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Configuration;
20bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.TypedArray;
2134b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johnsimport android.os.Build;
22bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.support.appcompat.R;
23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.support.appcompat.view.menu.ActionMenuPresenter;
24bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.support.appcompat.view.menu.ActionMenuView;
2534b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johnsimport android.text.AndroidCharacter;
26bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.AttributeSet;
27bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View;
28bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup;
29bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
30bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpublic abstract class AbsActionBarView extends ViewGroup {
31bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected ActionMenuView mMenuView;
32bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected ActionMenuPresenter mActionMenuPresenter;
33bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected ActionBarContainer mSplitView;
34bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected boolean mSplitActionBar;
35bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected boolean mSplitWhenNarrow;
36bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected int mContentHeight;
37bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
38bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  private static final int FADE_DURATION = 200;
39bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
40bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public AbsActionBarView(Context context) {
41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    super(context);
42bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
43bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
44bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public AbsActionBarView(Context context, AttributeSet attrs) {
45bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    super(context, attrs);
46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
48bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
49bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    super(context, attrs, defStyle);
50bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
51bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
52bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
53bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected void onConfigurationChanged(Configuration newConfig) {
5434b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johns    if (Build.VERSION.SDK_INT >= 8) {
5534b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johns      super.onConfigurationChanged(newConfig);
5634b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johns    }
57bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
58bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Action bar can change size on configuration changes.
59bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    // Reread the desired height from the theme-specified style.
60bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar,
61bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        R.attr.actionBarStyle, 0);
62bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
63bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    a.recycle();
64bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mSplitWhenNarrow) {
65bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      setSplitActionBar(getContext().getResources().getBoolean(
66bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell          R.bool.split_action_bar_is_narrow));
67bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
68bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mActionMenuPresenter != null) {
69bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mActionMenuPresenter.onConfigurationChanged(newConfig);
70bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
71bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
72bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
73bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  /**
74bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * Sets whether the bar should be split right now, no questions asked.
75bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param split true if the bar should split
76bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   */
77bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setSplitActionBar(boolean split) {
78bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mSplitActionBar = split;
79bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
80bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
81bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  /**
82bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * Sets whether the bar should split if we enter a narrow screen configuration.
83bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @param splitWhenNarrow true if the bar should check to split after a config change
84bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   */
85bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setSplitWhenNarrow(boolean splitWhenNarrow) {
86bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mSplitWhenNarrow = splitWhenNarrow;
87bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
88bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
89bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setContentHeight(int height) {
90bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mContentHeight = height;
91bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    requestLayout();
92bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
93bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
94bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public int getContentHeight() {
95bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return mContentHeight;
96bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
97bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
98bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setSplitView(ActionBarContainer splitView) {
99bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    mSplitView = splitView;
100bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
101bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
102bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  /**
103bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   * @return Current visibility or if animating, the visibility being animated to.
104bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell   */
105bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public int getAnimatedVisibility() {
106bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return getVisibility();
107bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
108bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
109bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void animateToVisibility(int visibility) {
11034b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johns    setVisibility(visibility);
111bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
112bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
113bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  @Override
114bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void setVisibility(int visibility) {
115bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (visibility != getVisibility()) {
116bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      super.setVisibility(visibility);
117bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
118bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
119bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
120bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean showOverflowMenu() {
121bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mActionMenuPresenter != null) {
122bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return mActionMenuPresenter.showOverflowMenu();
123bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
124bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return false;
125bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
126bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
127bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void postShowOverflowMenu() {
128bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    post(new Runnable() {
129bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      public void run() {
130bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        showOverflowMenu();
131bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      }
132bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    });
133bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
134bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
135bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean hideOverflowMenu() {
136bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mActionMenuPresenter != null) {
137bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return mActionMenuPresenter.hideOverflowMenu();
138bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
139bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return false;
140bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
141bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
142bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean isOverflowMenuShowing() {
143bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mActionMenuPresenter != null) {
144bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      return mActionMenuPresenter.isOverflowMenuShowing();
145bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
146bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return false;
147bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
148bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
149bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public boolean isOverflowReserved() {
150bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
151bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
152bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
153bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  public void dismissPopupMenus() {
154bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    if (mActionMenuPresenter != null) {
155bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      mActionMenuPresenter.dismissPopupMenus();
156bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
157bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
158bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
159bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected int measureChildView(View child, int availableWidth, int childSpecHeight,
160bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell      int spacing) {
161bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
162bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        childSpecHeight);
163bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
164bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    availableWidth -= child.getMeasuredWidth();
165bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    availableWidth -= spacing;
166bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
167bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return Math.max(0, availableWidth);
168bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
169bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
170bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected int positionChild(View child, int x, int y, int contentHeight) {
171bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int childWidth = child.getMeasuredWidth();
172bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int childHeight = child.getMeasuredHeight();
173bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int childTop = y + (contentHeight - childHeight) / 2;
174bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
175bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    child.layout(x, childTop, x + childWidth, childTop + childHeight);
176bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
177bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return childWidth;
178bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
179bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
180bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  protected int positionChildInverse(View child, int x, int y, int contentHeight) {
181bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int childWidth = child.getMeasuredWidth();
182bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int childHeight = child.getMeasuredHeight();
183bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    int childTop = y + (contentHeight - childHeight) / 2;
184bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
185bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    child.layout(x - childWidth, childTop, x, childTop + childHeight);
186bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
187bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    return childWidth;
188bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell  }
189bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
190bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell}
191