3a4a446756c1f8369081aa3edbcc24b18c34b9de
[pub/Android/ownCloud.git] / actionbarsherlock / src / com / actionbarsherlock / internal / widget / AbsActionBarView.java
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 package com.actionbarsherlock.internal.widget;
17
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;
26
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;
34
35 import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean;
36
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;
44
45 final Context mContext;
46
47 protected Animator mVisibilityAnim;
48 protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener();
49
50 private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator();
51
52 private static final int FADE_DURATION = 200;
53
54 public AbsActionBarView(Context context) {
55 super(context);
56 mContext = context;
57 }
58
59 public AbsActionBarView(Context context, AttributeSet attrs) {
60 super(context, attrs);
61 mContext = context;
62 }
63
64 public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
65 super(context, attrs, defStyle);
66 mContext = context;
67 }
68
69 /*
70 * Must be public so we can dispatch pre-2.2 via ActionBarImpl.
71 */
72 @Override
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);
78 }
79
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));
85 a.recycle();
86 if (mSplitWhenNarrow) {
87 setSplitActionBar(getResources_getBoolean(getContext(),
88 R.bool.abs__split_action_bar_is_narrow));
89 }
90 if (mActionMenuPresenter != null) {
91 mActionMenuPresenter.onConfigurationChanged(newConfig);
92 }
93 }
94
95 /**
96 * Sets whether the bar should be split right now, no questions asked.
97 * @param split true if the bar should split
98 */
99 public void setSplitActionBar(boolean split) {
100 mSplitActionBar = split;
101 }
102
103 /**
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
106 */
107 public void setSplitWhenNarrow(boolean splitWhenNarrow) {
108 mSplitWhenNarrow = splitWhenNarrow;
109 }
110
111 public void setContentHeight(int height) {
112 mContentHeight = height;
113 requestLayout();
114 }
115
116 public int getContentHeight() {
117 return mContentHeight;
118 }
119
120 public void setSplitView(ActionBarContainer splitView) {
121 mSplitView = splitView;
122 }
123
124 /**
125 * @return Current visibility or if animating, the visibility being animated to.
126 */
127 public int getAnimatedVisibility() {
128 if (mVisibilityAnim != null) {
129 return mVisAnimListener.mFinalVisibility;
130 }
131 return getVisibility();
132 }
133
134 public void animateToVisibility(int visibility) {
135 if (mVisibilityAnim != null) {
136 mVisibilityAnim.cancel();
137 }
138 if (visibility == VISIBLE) {
139 if (getVisibility() != VISIBLE) {
140 setAlpha(0);
141 if (mSplitView != null && mMenuView != null) {
142 mMenuView.setAlpha(0);
143 }
144 }
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);
154 set.start();
155 } else {
156 anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
157 anim.start();
158 }
159 } else {
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);
169 set.start();
170 } else {
171 anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
172 anim.start();
173 }
174 }
175 }
176
177 @Override
178 public void setVisibility(int visibility) {
179 if (mVisibilityAnim != null) {
180 mVisibilityAnim.end();
181 }
182 super.setVisibility(visibility);
183 }
184
185 public boolean showOverflowMenu() {
186 if (mActionMenuPresenter != null) {
187 return mActionMenuPresenter.showOverflowMenu();
188 }
189 return false;
190 }
191
192 public void postShowOverflowMenu() {
193 post(new Runnable() {
194 public void run() {
195 showOverflowMenu();
196 }
197 });
198 }
199
200 public boolean hideOverflowMenu() {
201 if (mActionMenuPresenter != null) {
202 return mActionMenuPresenter.hideOverflowMenu();
203 }
204 return false;
205 }
206
207 public boolean isOverflowMenuShowing() {
208 if (mActionMenuPresenter != null) {
209 return mActionMenuPresenter.isOverflowMenuShowing();
210 }
211 return false;
212 }
213
214 public boolean isOverflowReserved() {
215 return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
216 }
217
218 public void dismissPopupMenus() {
219 if (mActionMenuPresenter != null) {
220 mActionMenuPresenter.dismissPopupMenus();
221 }
222 }
223
224 protected int measureChildView(View child, int availableWidth, int childSpecHeight,
225 int spacing) {
226 child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
227 childSpecHeight);
228
229 availableWidth -= child.getMeasuredWidth();
230 availableWidth -= spacing;
231
232 return Math.max(0, availableWidth);
233 }
234
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;
239
240 child.layout(x, childTop, x + childWidth, childTop + childHeight);
241
242 return childWidth;
243 }
244
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;
249
250 child.layout(x - childWidth, childTop, x, childTop + childHeight);
251
252 return childWidth;
253 }
254
255 protected class VisibilityAnimListener implements Animator.AnimatorListener {
256 private boolean mCanceled = false;
257 int mFinalVisibility;
258
259 public VisibilityAnimListener withFinalVisibility(int visibility) {
260 mFinalVisibility = visibility;
261 return this;
262 }
263
264 @Override
265 public void onAnimationStart(Animator animation) {
266 setVisibility(VISIBLE);
267 mVisibilityAnim = animation;
268 mCanceled = false;
269 }
270
271 @Override
272 public void onAnimationEnd(Animator animation) {
273 if (mCanceled) return;
274
275 mVisibilityAnim = null;
276 setVisibility(mFinalVisibility);
277 if (mSplitView != null && mMenuView != null) {
278 mMenuView.setVisibility(mFinalVisibility);
279 }
280 }
281
282 @Override
283 public void onAnimationCancel(Animator animation) {
284 mCanceled = true;
285 }
286
287 @Override
288 public void onAnimationRepeat(Animator animation) {
289 }
290 }
291 }