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
.Bitmap
;
22 import android
.graphics
.Canvas
;
23 import android
.graphics
.drawable
.ColorDrawable
;
24 import android
.graphics
.drawable
.Drawable
;
25 import android
.os
.Build
;
26 import android
.util
.AttributeSet
;
27 import android
.view
.MotionEvent
;
28 import android
.view
.View
;
29 import android
.view
.ViewGroup
;
31 import com
.actionbarsherlock
.R
;
32 import com
.actionbarsherlock
.app
.ActionBar
;
33 import com
.actionbarsherlock
.internal
.nineoldandroids
.widget
.NineFrameLayout
;
36 * This class acts as a container for the action bar view and action mode context views.
37 * It applies special styles as needed to help handle animated transitions between them.
40 public class ActionBarContainer
extends NineFrameLayout
{
41 private boolean mIsTransitioning
;
42 private View mTabContainer
;
43 private ActionBarView mActionBarView
;
45 private Drawable mBackground
;
46 private Drawable mStackedBackground
;
47 private Drawable mSplitBackground
;
48 private boolean mIsSplit
;
49 private boolean mIsStacked
;
51 public ActionBarContainer(Context context
) {
55 public ActionBarContainer(Context context
, AttributeSet attrs
) {
56 super(context
, attrs
);
58 setBackgroundDrawable(null
);
60 TypedArray a
= context
.obtainStyledAttributes(attrs
,
61 R
.styleable
.SherlockActionBar
);
62 mBackground
= a
.getDrawable(R
.styleable
.SherlockActionBar_background
);
63 mStackedBackground
= a
.getDrawable(
64 R
.styleable
.SherlockActionBar_backgroundStacked
);
67 if (mStackedBackground
instanceof ColorDrawable
&& Build
.VERSION
.SDK_INT
< Build
.VERSION_CODES
.HONEYCOMB
) {
68 Bitmap bitmap
= Bitmap
.createBitmap(1, 1, Bitmap
.Config
.ARGB_8888
);
69 Canvas c
= new Canvas(bitmap
);
70 mStackedBackground
.draw(c
);
71 int color
= bitmap
.getPixel(0, 0);
73 mStackedBackground
= new IcsColorDrawable(color
);
76 if (getId() == R
.id
.abs__split_action_bar
) {
78 mSplitBackground
= a
.getDrawable(
79 R
.styleable
.SherlockActionBar_backgroundSplit
);
83 setWillNotDraw(mIsSplit ? mSplitBackground
== null
:
84 mBackground
== null
&& mStackedBackground
== null
);
88 public void onFinishInflate() {
89 super.onFinishInflate();
90 mActionBarView
= (ActionBarView
) findViewById(R
.id
.abs__action_bar
);
93 public void setPrimaryBackground(Drawable bg
) {
98 public void setStackedBackground(Drawable bg
) {
99 mStackedBackground
= bg
;
103 public void setSplitBackground(Drawable bg
) {
104 mSplitBackground
= bg
;
109 * Set the action bar into a "transitioning" state. While transitioning
110 * the bar will block focus and touch from all of its descendants. This
111 * prevents the user from interacting with the bar while it is animating
114 * @param isTransitioning true if the bar is currently transitioning, false otherwise.
116 public void setTransitioning(boolean isTransitioning
) {
117 mIsTransitioning
= isTransitioning
;
118 setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS
119 : FOCUS_AFTER_DESCENDANTS
);
123 public boolean onInterceptTouchEvent(MotionEvent ev
) {
124 return mIsTransitioning
|| super.onInterceptTouchEvent(ev
);
128 public boolean onTouchEvent(MotionEvent ev
) {
129 super.onTouchEvent(ev
);
131 // An action bar always eats touch events.
136 public boolean onHoverEvent(MotionEvent ev
) {
137 super.onHoverEvent(ev
);
139 // An action bar always eats hover events.
143 public void setTabContainer(ScrollingTabContainerView tabView
) {
144 if (mTabContainer
!= null
) {
145 removeView(mTabContainer
);
147 mTabContainer
= tabView
;
148 if (tabView
!= null
) {
150 final ViewGroup
.LayoutParams lp
= tabView
.getLayoutParams();
151 lp
.width
= LayoutParams
.MATCH_PARENT
;
152 lp
.height
= LayoutParams
.WRAP_CONTENT
;
153 tabView
.setAllowCollapse(false
);
157 public View
getTabContainer() {
158 return mTabContainer
;
162 public void onDraw(Canvas canvas
) {
163 if (getWidth() == 0 || getHeight() == 0) {
168 if (mSplitBackground
!= null
) mSplitBackground
.draw(canvas
);
170 if (mBackground
!= null
) {
171 mBackground
.draw(canvas
);
173 if (mStackedBackground
!= null
&& mIsStacked
) {
174 mStackedBackground
.draw(canvas
);
179 //This causes the animation reflection to fail on pre-HC platforms
181 //public android.view.ActionMode startActionModeForChild(View child, android.view.ActionMode.Callback callback) {
182 // // No starting an action mode for an action bar child! (Where would it go?)
187 public void onMeasure(int widthMeasureSpec
, int heightMeasureSpec
) {
188 super.onMeasure(widthMeasureSpec
, heightMeasureSpec
);
190 if (mActionBarView
== null
) return;
192 final LayoutParams lp
= (LayoutParams
) mActionBarView
.getLayoutParams();
193 final int actionBarViewHeight
= mActionBarView
.isCollapsed() ?
0 :
194 mActionBarView
.getMeasuredHeight() + lp
.topMargin
+ lp
.bottomMargin
;
196 if (mTabContainer
!= null
&& mTabContainer
.getVisibility() != GONE
) {
197 final int mode
= MeasureSpec
.getMode(heightMeasureSpec
);
198 if (mode
== MeasureSpec
.AT_MOST
) {
199 final int maxHeight
= MeasureSpec
.getSize(heightMeasureSpec
);
200 setMeasuredDimension(getMeasuredWidth(),
201 Math
.min(actionBarViewHeight
+ mTabContainer
.getMeasuredHeight(),
208 public void onLayout(boolean changed
, int l
, int t
, int r
, int b
) {
209 super.onLayout(changed
, l
, t
, r
, b
);
211 final boolean hasTabs
= mTabContainer
!= null
&& mTabContainer
.getVisibility() != GONE
;
213 if (mTabContainer
!= null
&& mTabContainer
.getVisibility() != GONE
) {
214 final int containerHeight
= getMeasuredHeight();
215 final int tabHeight
= mTabContainer
.getMeasuredHeight();
217 if ((mActionBarView
.getDisplayOptions() & ActionBar
.DISPLAY_SHOW_HOME
) == 0) {
218 // Not showing home, put tabs on top.
219 final int count
= getChildCount();
220 for (int i
= 0; i
< count
; i
++) {
221 final View child
= getChildAt(i
);
223 if (child
== mTabContainer
) continue;
225 if (!mActionBarView
.isCollapsed()) {
226 child
.offsetTopAndBottom(tabHeight
);
229 mTabContainer
.layout(l
, 0, r
, tabHeight
);
231 mTabContainer
.layout(l
, containerHeight
- tabHeight
, r
, containerHeight
);
235 boolean needsInvalidate
= false
;
237 if (mSplitBackground
!= null
) {
238 mSplitBackground
.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
239 needsInvalidate
= true
;
242 if (mBackground
!= null
) {
243 mBackground
.setBounds(mActionBarView
.getLeft(), mActionBarView
.getTop(),
244 mActionBarView
.getRight(), mActionBarView
.getBottom());
245 needsInvalidate
= true
;
247 if ((mIsStacked
= hasTabs
&& mStackedBackground
!= null
)) {
248 mStackedBackground
.setBounds(mTabContainer
.getLeft(), mTabContainer
.getTop(),
249 mTabContainer
.getRight(), mTabContainer
.getBottom());
250 needsInvalidate
= true
;
254 if (needsInvalidate
) {