ActionBarContainer.java revision af6b97ebe0e6a67d1691c4d7789c7bc312c1e13e
1/* 2 * Copyright (C) 2010 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 17package com.android.internal.widget; 18 19import android.app.ActionBar; 20import android.content.Context; 21import android.content.res.TypedArray; 22import android.graphics.Canvas; 23import android.graphics.drawable.Drawable; 24import android.util.AttributeSet; 25import android.view.ActionMode; 26import android.view.MotionEvent; 27import android.view.View; 28import android.view.ViewGroup; 29import android.widget.FrameLayout; 30 31/** 32 * This class acts as a container for the action bar view and action mode context views. 33 * It applies special styles as needed to help handle animated transitions between them. 34 * @hide 35 */ 36public class ActionBarContainer extends FrameLayout { 37 private boolean mIsTransitioning; 38 private View mTabContainer; 39 private ActionBarView mActionBarView; 40 41 private Drawable mBackground; 42 private Drawable mStackedBackground; 43 private Drawable mSplitBackground; 44 private boolean mIsSplit; 45 private boolean mIsStacked; 46 47 public ActionBarContainer(Context context) { 48 this(context, null); 49 } 50 51 public ActionBarContainer(Context context, AttributeSet attrs) { 52 super(context, attrs); 53 54 setBackgroundDrawable(null); 55 56 TypedArray a = context.obtainStyledAttributes(attrs, 57 com.android.internal.R.styleable.ActionBar); 58 mBackground = a.getDrawable(com.android.internal.R.styleable.ActionBar_background); 59 mStackedBackground = a.getDrawable( 60 com.android.internal.R.styleable.ActionBar_backgroundStacked); 61 62 if (getId() == com.android.internal.R.id.split_action_bar) { 63 mIsSplit = true; 64 mSplitBackground = a.getDrawable( 65 com.android.internal.R.styleable.ActionBar_backgroundSplit); 66 } 67 a.recycle(); 68 69 setWillNotDraw(mIsSplit ? mSplitBackground == null : 70 mBackground == null && mStackedBackground == null); 71 } 72 73 @Override 74 public void onFinishInflate() { 75 super.onFinishInflate(); 76 mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar); 77 } 78 79 /** 80 * Set the action bar into a "transitioning" state. While transitioning 81 * the bar will block focus and touch from all of its descendants. This 82 * prevents the user from interacting with the bar while it is animating 83 * in or out. 84 * 85 * @param isTransitioning true if the bar is currently transitioning, false otherwise. 86 */ 87 public void setTransitioning(boolean isTransitioning) { 88 mIsTransitioning = isTransitioning; 89 setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS 90 : FOCUS_AFTER_DESCENDANTS); 91 } 92 93 @Override 94 public boolean onInterceptTouchEvent(MotionEvent ev) { 95 return mIsTransitioning || super.onInterceptTouchEvent(ev); 96 } 97 98 @Override 99 public boolean onTouchEvent(MotionEvent ev) { 100 super.onTouchEvent(ev); 101 102 // An action bar always eats touch events. 103 return true; 104 } 105 106 public void setTabContainer(ScrollingTabContainerView tabView) { 107 if (mTabContainer != null) { 108 removeView(mTabContainer); 109 } 110 mTabContainer = tabView; 111 if (tabView != null) { 112 addView(tabView); 113 final ViewGroup.LayoutParams lp = tabView.getLayoutParams(); 114 lp.width = LayoutParams.MATCH_PARENT; 115 lp.height = LayoutParams.WRAP_CONTENT; 116 tabView.setAllowCollapse(false); 117 } 118 } 119 120 public View getTabContainer() { 121 return mTabContainer; 122 } 123 124 @Override 125 public void onDraw(Canvas canvas) { 126 if (getWidth() == 0 || getHeight() == 0) { 127 return; 128 } 129 130 if (mIsSplit) { 131 if (mSplitBackground != null) mSplitBackground.draw(canvas); 132 } else { 133 if (mBackground != null) { 134 mBackground.draw(canvas); 135 } 136 if (mStackedBackground != null && mIsStacked) { 137 mStackedBackground.draw(canvas); 138 } 139 } 140 } 141 142 @Override 143 public ActionMode startActionModeForChild(View child, ActionMode.Callback callback) { 144 // No starting an action mode for an action bar child! (Where would it go?) 145 return null; 146 } 147 148 @Override 149 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 150 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 151 152 if (mActionBarView == null) return; 153 154 final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams(); 155 final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 : 156 mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; 157 158 if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { 159 final int mode = MeasureSpec.getMode(heightMeasureSpec); 160 if (mode == MeasureSpec.AT_MOST) { 161 final int maxHeight = MeasureSpec.getSize(heightMeasureSpec); 162 setMeasuredDimension(getMeasuredWidth(), 163 Math.min(actionBarViewHeight + mTabContainer.getMeasuredHeight(), 164 maxHeight)); 165 } 166 } 167 } 168 169 @Override 170 public void onLayout(boolean changed, int l, int t, int r, int b) { 171 super.onLayout(changed, l, t, r, b); 172 173 final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE; 174 175 if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { 176 final int containerHeight = getMeasuredHeight(); 177 final int tabHeight = mTabContainer.getMeasuredHeight(); 178 179 if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) { 180 // Not showing home, put tabs on top. 181 final int count = getChildCount(); 182 for (int i = 0; i < count; i++) { 183 final View child = getChildAt(i); 184 185 if (child == mTabContainer) continue; 186 187 if (!mActionBarView.isCollapsed()) { 188 child.offsetTopAndBottom(tabHeight); 189 } 190 } 191 mTabContainer.layout(l, 0, r, tabHeight); 192 } else { 193 mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight); 194 } 195 } 196 197 boolean needsInvalidate = false; 198 if (mIsSplit) { 199 if (mSplitBackground != null) { 200 mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); 201 needsInvalidate = true; 202 } 203 } else { 204 if (mBackground != null) { 205 mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(), 206 mActionBarView.getRight(), mActionBarView.getBottom()); 207 needsInvalidate = true; 208 } 209 if ((mIsStacked = hasTabs && mStackedBackground != null)) { 210 mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(), 211 mTabContainer.getRight(), mTabContainer.getBottom()); 212 needsInvalidate = true; 213 } 214 } 215 216 if (needsInvalidate) { 217 invalidate(); 218 } 219 } 220} 221