2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.actionbarsherlock
.internal
.widget
;
18 import android
.content
.Context
;
19 import android
.content
.res
.Configuration
;
20 import android
.content
.res
.TypedArray
;
21 import android
.os
.Build
;
22 import android
.util
.AttributeSet
;
23 import android
.view
.View
;
24 import android
.view
.animation
.DecelerateInterpolator
;
25 import android
.view
.animation
.Interpolator
;
27 import com
.actionbarsherlock
.R
;
28 import com
.actionbarsherlock
.internal
.nineoldandroids
.animation
.Animator
;
29 import com
.actionbarsherlock
.internal
.nineoldandroids
.animation
.AnimatorSet
;
30 import com
.actionbarsherlock
.internal
.nineoldandroids
.animation
.ObjectAnimator
;
31 import com
.actionbarsherlock
.internal
.nineoldandroids
.view
.NineViewGroup
;
32 import com
.actionbarsherlock
.internal
.view
.menu
.ActionMenuPresenter
;
33 import com
.actionbarsherlock
.internal
.view
.menu
.ActionMenuView
;
35 import static com
.actionbarsherlock
.internal
.ResourcesCompat
.getResources_getBoolean
;
37 public abstract class AbsActionBarView
extends NineViewGroup
{
38 protected ActionMenuView mMenuView
;
39 protected ActionMenuPresenter mActionMenuPresenter
;
40 protected ActionBarContainer mSplitView
;
41 protected boolean mSplitActionBar
;
42 protected boolean mSplitWhenNarrow
;
43 protected int mContentHeight
;
45 final Context mContext
;
47 protected Animator mVisibilityAnim
;
48 protected final VisibilityAnimListener mVisAnimListener
= new VisibilityAnimListener();
50 private static final /*Time*/Interpolator sAlphaInterpolator
= new DecelerateInterpolator();
52 private static final int FADE_DURATION
= 200;
54 public AbsActionBarView(Context context
) {
59 public AbsActionBarView(Context context
, AttributeSet attrs
) {
60 super(context
, attrs
);
64 public AbsActionBarView(Context context
, AttributeSet attrs
, int defStyle
) {
65 super(context
, attrs
, defStyle
);
70 * Must be public so we can dispatch pre-2.2 via ActionBarImpl.
73 public void onConfigurationChanged(Configuration newConfig
) {
74 if (Build
.VERSION
.SDK_INT
>= Build
.VERSION_CODES
.FROYO
) {
75 super.onConfigurationChanged(newConfig
);
76 } else if (mMenuView
!= null
) {
77 mMenuView
.onConfigurationChanged(newConfig
);
80 // Action bar can change size on configuration changes.
81 // Reread the desired height from the theme-specified style.
82 TypedArray a
= getContext().obtainStyledAttributes(null
, R
.styleable
.SherlockActionBar
,
83 R
.attr
.actionBarStyle
, 0);
84 setContentHeight(a
.getLayoutDimension(R
.styleable
.SherlockActionBar_height
, 0));
86 if (mSplitWhenNarrow
) {
87 setSplitActionBar(getResources_getBoolean(getContext(),
88 R
.bool
.abs__split_action_bar_is_narrow
));
90 if (mActionMenuPresenter
!= null
) {
91 mActionMenuPresenter
.onConfigurationChanged(newConfig
);
96 * Sets whether the bar should be split right now, no questions asked.
97 * @param split true if the bar should split
99 public void setSplitActionBar(boolean split
) {
100 mSplitActionBar
= split
;
104 * Sets whether the bar should split if we enter a narrow screen configuration.
105 * @param splitWhenNarrow true if the bar should check to split after a config change
107 public void setSplitWhenNarrow(boolean splitWhenNarrow
) {
108 mSplitWhenNarrow
= splitWhenNarrow
;
111 public void setContentHeight(int height
) {
112 mContentHeight
= height
;
116 public int getContentHeight() {
117 return mContentHeight
;
120 public void setSplitView(ActionBarContainer splitView
) {
121 mSplitView
= splitView
;
125 * @return Current visibility or if animating, the visibility being animated to.
127 public int getAnimatedVisibility() {
128 if (mVisibilityAnim
!= null
) {
129 return mVisAnimListener
.mFinalVisibility
;
131 return getVisibility();
134 public void animateToVisibility(int visibility
) {
135 if (mVisibilityAnim
!= null
) {
136 mVisibilityAnim
.cancel();
138 if (visibility
== VISIBLE
) {
139 if (getVisibility() != VISIBLE
) {
141 if (mSplitView
!= null
&& mMenuView
!= null
) {
142 mMenuView
.setAlpha(0);
145 ObjectAnimator anim
= ObjectAnimator
.ofFloat(this, "alpha", 1);
146 anim
.setDuration(FADE_DURATION
);
147 anim
.setInterpolator(sAlphaInterpolator
);
148 if (mSplitView
!= null
&& mMenuView
!= null
) {
149 AnimatorSet set
= new AnimatorSet();
150 ObjectAnimator splitAnim
= ObjectAnimator
.ofFloat(mMenuView
, "alpha", 1);
151 splitAnim
.setDuration(FADE_DURATION
);
152 set
.addListener(mVisAnimListener
.withFinalVisibility(visibility
));
153 set
.play(anim
).with(splitAnim
);
156 anim
.addListener(mVisAnimListener
.withFinalVisibility(visibility
));
160 ObjectAnimator anim
= ObjectAnimator
.ofFloat(this, "alpha", 0);
161 anim
.setDuration(FADE_DURATION
);
162 anim
.setInterpolator(sAlphaInterpolator
);
163 if (mSplitView
!= null
&& mMenuView
!= null
) {
164 AnimatorSet set
= new AnimatorSet();
165 ObjectAnimator splitAnim
= ObjectAnimator
.ofFloat(mMenuView
, "alpha", 0);
166 splitAnim
.setDuration(FADE_DURATION
);
167 set
.addListener(mVisAnimListener
.withFinalVisibility(visibility
));
168 set
.play(anim
).with(splitAnim
);
171 anim
.addListener(mVisAnimListener
.withFinalVisibility(visibility
));
178 public void setVisibility(int visibility
) {
179 if (mVisibilityAnim
!= null
) {
180 mVisibilityAnim
.end();
182 super.setVisibility(visibility
);
185 public boolean showOverflowMenu() {
186 if (mActionMenuPresenter
!= null
) {
187 return mActionMenuPresenter
.showOverflowMenu();
192 public void postShowOverflowMenu() {
193 post(new Runnable() {
200 public boolean hideOverflowMenu() {
201 if (mActionMenuPresenter
!= null
) {
202 return mActionMenuPresenter
.hideOverflowMenu();
207 public boolean isOverflowMenuShowing() {
208 if (mActionMenuPresenter
!= null
) {
209 return mActionMenuPresenter
.isOverflowMenuShowing();
214 public boolean isOverflowReserved() {
215 return mActionMenuPresenter
!= null
&& mActionMenuPresenter
.isOverflowReserved();
218 public void dismissPopupMenus() {
219 if (mActionMenuPresenter
!= null
) {
220 mActionMenuPresenter
.dismissPopupMenus();
224 protected int measureChildView(View child
, int availableWidth
, int childSpecHeight
,
226 child
.measure(MeasureSpec
.makeMeasureSpec(availableWidth
, MeasureSpec
.AT_MOST
),
229 availableWidth
-= child
.getMeasuredWidth();
230 availableWidth
-= spacing
;
232 return Math
.max(0, availableWidth
);
235 protected int positionChild(View child
, int x
, int y
, int contentHeight
) {
236 int childWidth
= child
.getMeasuredWidth();
237 int childHeight
= child
.getMeasuredHeight();
238 int childTop
= y
+ (contentHeight
- childHeight
) / 2;
240 child
.layout(x
, childTop
, x
+ childWidth
, childTop
+ childHeight
);
245 protected int positionChildInverse(View child
, int x
, int y
, int contentHeight
) {
246 int childWidth
= child
.getMeasuredWidth();
247 int childHeight
= child
.getMeasuredHeight();
248 int childTop
= y
+ (contentHeight
- childHeight
) / 2;
250 child
.layout(x
- childWidth
, childTop
, x
, childTop
+ childHeight
);
255 protected class VisibilityAnimListener
implements Animator
.AnimatorListener
{
256 private boolean mCanceled
= false
;
257 int mFinalVisibility
;
259 public VisibilityAnimListener
withFinalVisibility(int visibility
) {
260 mFinalVisibility
= visibility
;
265 public void onAnimationStart(Animator animation
) {
266 setVisibility(VISIBLE
);
267 mVisibilityAnim
= animation
;
272 public void onAnimationEnd(Animator animation
) {
273 if (mCanceled
) return;
275 mVisibilityAnim
= null
;
276 setVisibility(mFinalVisibility
);
277 if (mSplitView
!= null
&& mMenuView
!= null
) {
278 mMenuView
.setVisibility(mFinalVisibility
);
283 public void onAnimationCancel(Animator animation
) {
288 public void onAnimationRepeat(Animator animation
) {