2 * Copyright (C) 2010 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.
17 package com.actionbarsherlock.internal.widget;
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.Canvas;
22 import android.graphics.drawable.Drawable;
23 import android.util.AttributeSet;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.view.ViewGroup;
28 import com.actionbarsherlock.R;
29 import com.actionbarsherlock.app.ActionBar;
30 import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout;
33 * This class acts as a container for the action bar view and action mode context views.
34 * It applies special styles as needed to help handle animated transitions between them.
37 public class ActionBarContainer extends NineFrameLayout {
38 private boolean mIsTransitioning;
39 private View mTabContainer;
40 private ActionBarView mActionBarView;
42 private Drawable mBackground;
43 private Drawable mStackedBackground;
44 private Drawable mSplitBackground;
45 private boolean mIsSplit;
46 private boolean mIsStacked;
48 public ActionBarContainer(Context context) {
52 public ActionBarContainer(Context context, AttributeSet attrs) {
53 super(context, attrs);
55 setBackgroundDrawable(null);
57 TypedArray a = context.obtainStyledAttributes(attrs,
58 R.styleable.SherlockActionBar);
59 mBackground = a.getDrawable(R.styleable.SherlockActionBar_background);
60 mStackedBackground = a.getDrawable(
61 R.styleable.SherlockActionBar_backgroundStacked);
63 if (getId() == R.id.abs__split_action_bar) {
65 mSplitBackground = a.getDrawable(
66 R.styleable.SherlockActionBar_backgroundSplit);
70 setWillNotDraw(mIsSplit ? mSplitBackground == null :
71 mBackground == null && mStackedBackground == null);
75 public void onFinishInflate() {
76 super.onFinishInflate();
77 mActionBarView = (ActionBarView) findViewById(R.id.abs__action_bar);
80 public void setPrimaryBackground(Drawable bg) {
85 public void setStackedBackground(Drawable bg) {
86 mStackedBackground = bg;
90 public void setSplitBackground(Drawable bg) {
91 mSplitBackground = bg;
96 * Set the action bar into a "transitioning" state. While transitioning
97 * the bar will block focus and touch from all of its descendants. This
98 * prevents the user from interacting with the bar while it is animating
101 * @param isTransitioning true if the bar is currently transitioning, false otherwise.
103 public void setTransitioning(boolean isTransitioning) {
104 mIsTransitioning = isTransitioning;
105 setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS
106 : FOCUS_AFTER_DESCENDANTS);
110 public boolean onInterceptTouchEvent(MotionEvent ev) {
111 return mIsTransitioning || super.onInterceptTouchEvent(ev);
115 public boolean onTouchEvent(MotionEvent ev) {
116 super.onTouchEvent(ev);
118 // An action bar always eats touch events.
123 public boolean onHoverEvent(MotionEvent ev) {
124 super.onHoverEvent(ev);
126 // An action bar always eats hover events.
130 public void setTabContainer(ScrollingTabContainerView tabView) {
131 if (mTabContainer != null) {
132 removeView(mTabContainer);
134 mTabContainer = tabView;
135 if (tabView != null) {
137 final ViewGroup.LayoutParams lp = tabView.getLayoutParams();
138 lp.width = LayoutParams.MATCH_PARENT;
139 lp.height = LayoutParams.WRAP_CONTENT;
140 tabView.setAllowCollapse(false);
144 public View getTabContainer() {
145 return mTabContainer;
149 public void onDraw(Canvas canvas) {
150 if (getWidth() == 0 || getHeight() == 0) {
155 if (mSplitBackground != null) mSplitBackground.draw(canvas);
157 if (mBackground != null) {
158 mBackground.draw(canvas);
160 if (mStackedBackground != null && mIsStacked) {
161 mStackedBackground.draw(canvas);
166 //This causes the animation reflection to fail on pre-HC platforms
168 //public android.view.ActionMode startActionModeForChild(View child, android.view.ActionMode.Callback callback) {
169 // // No starting an action mode for an action bar child! (Where would it go?)
174 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
175 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
177 if (mActionBarView == null) return;
179 final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams();
180 final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 :
181 mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
183 if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
184 final int mode = MeasureSpec.getMode(heightMeasureSpec);
185 if (mode == MeasureSpec.AT_MOST) {
186 final int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
187 setMeasuredDimension(getMeasuredWidth(),
188 Math.min(actionBarViewHeight + mTabContainer.getMeasuredHeight(),
195 public void onLayout(boolean changed, int l, int t, int r, int b) {
196 super.onLayout(changed, l, t, r, b);
198 final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE;
200 if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
201 final int containerHeight = getMeasuredHeight();
202 final int tabHeight = mTabContainer.getMeasuredHeight();
204 if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) {
205 // Not showing home, put tabs on top.
206 final int count = getChildCount();
207 for (int i = 0; i < count; i++) {
208 final View child = getChildAt(i);
210 if (child == mTabContainer) continue;
212 if (!mActionBarView.isCollapsed()) {
213 child.offsetTopAndBottom(tabHeight);
216 mTabContainer.layout(l, 0, r, tabHeight);
218 mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
222 boolean needsInvalidate = false;
224 if (mSplitBackground != null) {
225 mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
226 needsInvalidate = true;
229 if (mBackground != null) {
230 mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
231 mActionBarView.getRight(), mActionBarView.getBottom());
232 needsInvalidate = true;
234 if ((mIsStacked = hasTabs && mStackedBackground != null)) {
235 mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(),
236 mTabContainer.getRight(), mTabContainer.getBottom());
237 needsInvalidate = true;
241 if (needsInvalidate) {