Merge "Updated styles and metrics."

This commit is contained in:
Adam Powell
2010-10-11 11:26:57 -07:00
committed by Android (Google) Code Review
18 changed files with 628 additions and 203 deletions

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class ButtonGroup extends LinearLayout {
private Drawable mDivider;
private Drawable mButtonBackground;
public ButtonGroup(Context context) {
this(context, null);
}
public ButtonGroup(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.buttonGroupStyle);
}
public ButtonGroup(Context context, AttributeSet attrs, int defStyleRes) {
super(context, attrs, defStyleRes);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.ButtonGroup);
mDivider = a.getDrawable(com.android.internal.R.styleable.ButtonGroup_divider);
mButtonBackground = a.getDrawable(
com.android.internal.R.styleable.ButtonGroup_buttonBackground);
a.recycle();
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (getChildCount() > 0) {
super.addView(makeDividerView(), index, makeDividerLayoutParams());
if (index >= 0) {
index++;
}
}
child.setBackgroundDrawable(mButtonBackground);
super.addView(child, index, params);
}
private ImageView makeDividerView() {
ImageView result = new ImageView(mContext);
result.setImageDrawable(mDivider);
result.setScaleType(ImageView.ScaleType.FIT_XY);
return result;
}
private LayoutParams makeDividerLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
}
}

View File

@@ -589,7 +589,7 @@ public class Spinner extends AbsSpinner implements OnClickListener {
setAnchorView(Spinner.this);
setModal(true);
setPromptPosition(POSITION_PROMPT_BELOW);
setPromptPosition(POSITION_PROMPT_ABOVE);
setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
Spinner.this.setSelection(position);

View File

@@ -734,6 +734,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case com.android.internal.R.styleable.TextView_textSelectHandle:
mTextSelectHandleRes = a.getResourceId(attr, 0);
break;
case com.android.internal.R.styleable.TextView_textLineHeight:
int lineHeight = a.getDimensionPixelSize(attr, 0);
if (lineHeight != 0) {
setLineHeight(lineHeight);
}
}
}
a.recycle();
@@ -1063,6 +1069,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* or last-line padding.
*/
public int getLineHeight() {
if (mLineHeight != 0) {
return mLineHeight;
}
return FastMath.round(mTextPaint.getFontMetricsInt(null) * mSpacingMult
+ mSpacingAdd);
}
@@ -1655,9 +1664,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
TextAppearance_textStyle, -1);
setTypefaceByIndex(typefaceIndex, styleIndex);
int lineHeight = appearance.getDimensionPixelSize(
com.android.internal.R.styleable.TextAppearance_textLineHeight, 0);
if (lineHeight != 0) {
setLineHeight(lineHeight);
}
appearance.recycle();
}
/**
* Set the height of a line of text in pixels. This value will override line height
* values stored in the font modified by lineSpacingExtra and lineSpacingMultiplier.
*
* @param lineHeight Desired height of a single line of text in pixels
*/
public void setLineHeight(int lineHeight) {
mLineHeight = lineHeight;
}
/**
* @return the size (in pixels) of the default text size in this TextView.
*/
@@ -8449,6 +8475,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private float mSpacingMult = 1;
private float mSpacingAdd = 0;
private int mLineHeight = 0;
private static final int LINES = 1;
private static final int EMS = LINES;

View File

@@ -43,7 +43,7 @@ public class ActionMenuItemView extends FrameLayout
}
public ActionMenuItemView(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.actionButtonStyle);
super(context, attrs);
}
public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
@@ -113,6 +113,10 @@ public class ActionMenuItemView extends FrameLayout
mImageButton.setVisibility(GONE);
}
}
public boolean hasText() {
return mTextButton.getVisibility() != GONE;
}
public void setShortcut(boolean showShortcut, char shortcutKey) {
// Action buttons don't show text for shortcut keys.

View File

@@ -19,12 +19,15 @@ import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import java.util.ArrayList;
@@ -33,15 +36,22 @@ import java.util.ArrayList;
*/
public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView {
private static final String TAG = "ActionMenuView";
// TODO Theme/style this.
private static final int DIVIDER_PADDING = 12; // dips
private MenuBuilder mMenu;
private int mItemPadding;
private int mItemMargin;
private int mMaxItems;
private boolean mReserveOverflow;
private OverflowMenuButton mOverflowButton;
private MenuPopupHelper mOverflowPopup;
private float mButtonPaddingLeft;
private float mButtonPaddingRight;
private float mDividerPadding;
private Drawable mDivider;
private Runnable mShowOverflow = new Runnable() {
public void run() {
@@ -56,20 +66,34 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
public ActionMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.Theme);
mItemPadding = a.getDimensionPixelOffset(
com.android.internal.R.styleable.Theme_actionButtonPadding, 0);
mItemMargin = mItemPadding / 2;
a.recycle();
final Resources res = getResources();
// Measure for initial configuration
mMaxItems = measureMaxActionButtons();
mMaxItems = getMaxActionButtons();
// TODO There has to be a better way to indicate that we don't have a hard menu key.
final int screen = getResources().getConfiguration().screenLayout;
final int screen = res.getConfiguration().screenLayout;
mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE;
TypedArray a = context.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
final int buttonStyle = a.getResourceId(
com.android.internal.R.styleable.Theme_actionButtonStyle, 0);
final int groupStyle = a.getResourceId(
com.android.internal.R.styleable.Theme_buttonGroupStyle, 0);
a.recycle();
a = context.obtainStyledAttributes(buttonStyle, com.android.internal.R.styleable.View);
mButtonPaddingLeft = a.getDimension(com.android.internal.R.styleable.View_paddingLeft, 0);
mButtonPaddingRight = a.getDimension(com.android.internal.R.styleable.View_paddingRight, 0);
a.recycle();
a = context.obtainStyledAttributes(groupStyle,
com.android.internal.R.styleable.ButtonGroup);
mDivider = a.getDrawable(com.android.internal.R.styleable.ButtonGroup_divider);
a.recycle();
mDividerPadding = DIVIDER_PADDING * res.getDisplayMetrics().density;
}
@Override
@@ -77,7 +101,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
final int screen = newConfig.screenLayout;
mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE;
mMaxItems = measureMaxActionButtons();
mMaxItems = getMaxActionButtons();
if (mMenu != null) {
mMenu.setMaxActionItems(mMaxItems);
updateChildren(false);
@@ -89,13 +113,8 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
}
}
private int measureMaxActionButtons() {
final Resources res = getResources();
final int size = res.getDimensionPixelSize(com.android.internal.R.dimen.action_icon_size);
final int spaceAvailable = res.getDisplayMetrics().widthPixels / 2;
final int itemSpace = size + mItemPadding;
return spaceAvailable / (itemSpace > 0 ? itemSpace : 1);
private int getMaxActionButtons() {
return getResources().getInteger(com.android.internal.R.integer.max_action_buttons);
}
public boolean isOverflowReserved() {
@@ -105,24 +124,11 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
public void setOverflowReserved(boolean reserveOverflow) {
mReserveOverflow = reserveOverflow;
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
if (p instanceof LayoutParams) {
LayoutParams lp = (LayoutParams) p;
return lp.leftMargin == mItemMargin && lp.rightMargin == mItemMargin &&
lp.gravity == Gravity.CENTER_VERTICAL &&
lp.width == LayoutParams.WRAP_CONTENT && lp.height == LayoutParams.WRAP_CONTENT;
}
return false;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.leftMargin = mItemMargin;
params.rightMargin = mItemMargin;
params.gravity = Gravity.CENTER_VERTICAL;
return params;
}
@@ -131,10 +137,6 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return generateDefaultLayoutParams();
}
public int getItemMargin() {
return mItemMargin;
}
public boolean invokeItem(MenuItemImpl item) {
return mMenu.performItemAction(item, 0);
@@ -157,14 +159,19 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
final ArrayList<MenuItemImpl> itemsToShow = mMenu.getActionItems(reserveOverflow);
final int itemCount = itemsToShow.size();
boolean needsDivider = false;
for (int i = 0; i < itemCount; i++) {
if (needsDivider) {
addView(makeDividerView(), makeDividerLayoutParams());
}
final MenuItemImpl itemData = itemsToShow.get(i);
final View actionView = itemData.getActionView();
if (actionView != null) {
addView(actionView);
addView(actionView, makeActionViewLayoutParams());
} else {
addItemView((ActionMenuItemView) itemData.getItemView(
MenuBuilder.TYPE_ACTION_BUTTON, this));
needsDivider = addItemView(i == 0 || !needsDivider,
(ActionMenuItemView) itemData.getItemView(
MenuBuilder.TYPE_ACTION_BUTTON, this));
}
}
@@ -212,16 +219,43 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
return false;
}
private void addItemView(ActionMenuItemView view) {
private boolean addItemView(boolean needsDivider, ActionMenuItemView view) {
view.setItemInvoker(this);
boolean hasText = view.hasText();
if (hasText && needsDivider) {
addView(makeDividerView(), makeDividerLayoutParams());
}
addView(view);
return hasText;
}
private ImageView makeDividerView() {
ImageView result = new ImageView(mContext);
result.setImageDrawable(mDivider);
result.setScaleType(ImageView.ScaleType.FIT_XY);
return result;
}
private LayoutParams makeDividerLayoutParams() {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT);
params.topMargin = (int) mDividerPadding;
params.bottomMargin = (int) mDividerPadding;
return params;
}
private LayoutParams makeActionViewLayoutParams() {
LayoutParams params = generateDefaultLayoutParams();
params.leftMargin = (int) mButtonPaddingLeft;
params.rightMargin = (int) mButtonPaddingRight;
return params;
}
private class OverflowMenuButton extends ImageButton {
public OverflowMenuButton(Context context) {
super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle);
final Resources res = context.getResources();
setClickable(true);
setFocusable(true);
setVisibility(VISIBLE);

View File

@@ -236,14 +236,14 @@ public class MenuBuilder implements Menu {
int themeResForType = THEME_RES_FOR_TYPE[mMenuType];
switch (themeResForType) {
case THEME_APPLICATION:
wrappedContext = new ContextThemeWrapper(mContext, themeResForType);
wrappedContext = mContext;
break;
case THEME_ALERT_DIALOG:
wrappedContext = new ContextThemeWrapper(mContext,
getAlertDialogTheme(mContext));
break;
default:
wrappedContext = mContext;
wrappedContext = new ContextThemeWrapper(mContext, themeResForType);
break;
}
mInflater = (LayoutInflater) wrappedContext

View File

@@ -36,8 +36,6 @@ import android.widget.TextView;
* @hide
*/
public class ActionBarContextView extends ViewGroup {
private int mItemPadding;
private int mActionSpacing;
private int mContentHeight;
private CharSequence mTitle;
@@ -64,8 +62,6 @@ public class ActionBarContextView extends ViewGroup {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionMode, defStyle, 0);
mItemPadding = a.getDimensionPixelOffset(
com.android.internal.R.styleable.ActionMode_itemPadding, 0);
setBackgroundDrawable(a.getDrawable(
com.android.internal.R.styleable.ActionMode_background));
mTitleStyleRes = a.getResourceId(
@@ -219,7 +215,6 @@ public class ActionBarContextView extends ViewGroup {
}
final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
final int itemMargin = mItemPadding;
int maxHeight = mContentHeight > 0 ?
mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
@@ -230,13 +225,11 @@ public class ActionBarContextView extends ViewGroup {
final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
if (mCloseButton != null) {
availableWidth = measureChildView(mCloseButton, availableWidth,
childSpecHeight, itemMargin);
availableWidth = measureChildView(mCloseButton, availableWidth, childSpecHeight, 0);
}
if (mTitleLayout != null && mCustomView == null) {
availableWidth = measureChildView(mTitleLayout, availableWidth,
childSpecHeight, itemMargin);
availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0);
}
final int childCount = getChildCount();
@@ -246,7 +239,7 @@ public class ActionBarContextView extends ViewGroup {
continue;
}
availableWidth = measureChildView(child, availableWidth, childSpecHeight, itemMargin);
availableWidth = measureChildView(child, availableWidth, childSpecHeight, 0);
}
if (mCustomView != null) {
@@ -284,25 +277,23 @@ public class ActionBarContextView extends ViewGroup {
int x = getPaddingLeft();
final int y = getPaddingTop();
final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
final int itemMargin = mItemPadding;
if (mCloseButton != null && mCloseButton.getVisibility() != GONE) {
x += positionChild(mCloseButton, x, y, contentHeight);
}
if (mTitleLayout != null && mCustomView == null) {
x += positionChild(mTitleLayout, x, y, contentHeight) + itemMargin;
x += positionChild(mTitleLayout, x, y, contentHeight);
}
if (mCustomView != null) {
x += positionChild(mCustomView, x, y, contentHeight) + itemMargin;
x += positionChild(mCustomView, x, y, contentHeight);
}
x = r - l - getPaddingRight();
if (mMenuView != null) {
x -= positionChildInverse(mMenuView, x + mActionSpacing, y, contentHeight)
- mActionSpacing;
x -= positionChildInverse(mMenuView, x, y, contentHeight);
}
}

View File

@@ -53,12 +53,7 @@ import android.widget.TextView;
*/
public class ActionBarView extends ViewGroup {
private static final String TAG = "ActionBarView";
// TODO: This must be defined in the default theme
private static final int CONTENT_PADDING_DIP = 3;
private static final int CONTENT_SPACING_DIP = 6;
private static final int CONTENT_ACTION_SPACING_DIP = 12;
/**
* Display options applied by default
*/
@@ -75,12 +70,11 @@ public class ActionBarView extends ViewGroup {
private int mNavigationMode;
private int mDisplayOptions;
private int mSpacing;
private int mActionSpacing;
private CharSequence mTitle;
private CharSequence mSubtitle;
private Drawable mIcon;
private Drawable mLogo;
private Drawable mDivider;
private ImageView mIconView;
private ImageView mLogoView;
@@ -126,8 +120,6 @@ public class ActionBarView extends ViewGroup {
public ActionBarView(Context context, AttributeSet attrs) {
super(context, attrs);
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar);
final int colorFilter = a.getColor(R.styleable.ActionBar_colorFilter, 0);
@@ -171,12 +163,10 @@ public class ActionBarView extends ViewGroup {
}
mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
mDivider = a.getDrawable(R.styleable.ActionBar_divider);
a.recycle();
// TODO: Set this in the theme
mSpacing = (int) (CONTENT_SPACING_DIP * metrics.density + 0.5f);
mActionSpacing = (int) (CONTENT_ACTION_SPACING_DIP * metrics.density + 0.5f);
if (mLogo != null || mIcon != null || mTitle != null) {
mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
@@ -210,7 +200,6 @@ public class ActionBarView extends ViewGroup {
}
final ActionMenuView menuView = (ActionMenuView) builder.getMenuView(
MenuBuilder.TYPE_ACTION_BUTTON, null);
mActionSpacing = menuView.getItemMargin();
final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT);
menuView.setLayoutParams(layoutParams);
@@ -452,7 +441,8 @@ public class ActionBarView extends ViewGroup {
if ((mDisplayOptions & ActionBar.DISPLAY_HIDE_HOME) == 0) {
if (mLogo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
mLogoView = new ImageView(getContext());
mLogoView = new ImageView(getContext(), null,
com.android.internal.R.attr.actionButtonStyle);
mLogoView.setAdjustViewBounds(true);
mLogoView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT));
@@ -462,7 +452,8 @@ public class ActionBarView extends ViewGroup {
mLogoView.setOnClickListener(mHomeClickListener);
addView(mLogoView);
} else if (mIcon != null) {
mIconView = new ImageView(getContext());
mIconView = new ImageView(getContext(), null,
com.android.internal.R.attr.actionButtonStyle);
mIconView.setAdjustViewBounds(true);
mIconView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT));
@@ -558,10 +549,10 @@ public class ActionBarView extends ViewGroup {
final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
if (mLogoView != null && mLogoView.getVisibility() != GONE) {
availableWidth = measureChildView(mLogoView, availableWidth, childSpecHeight, mSpacing);
availableWidth = measureChildView(mLogoView, availableWidth, childSpecHeight, 0);
}
if (mIconView != null && mIconView.getVisibility() != GONE) {
availableWidth = measureChildView(mIconView, availableWidth, childSpecHeight, mSpacing);
availableWidth = measureChildView(mIconView, availableWidth, childSpecHeight, 0);
}
if (mMenuView != null) {
@@ -572,7 +563,7 @@ public class ActionBarView extends ViewGroup {
switch (mNavigationMode) {
case ActionBar.NAVIGATION_MODE_STANDARD:
if (mTitleLayout != null) {
measureChildView(mTitleLayout, availableWidth, childSpecHeight, mSpacing);
measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0);
}
break;
case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST:
@@ -652,39 +643,38 @@ public class ActionBarView extends ViewGroup {
final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
if (mLogoView != null && mLogoView.getVisibility() != GONE) {
x += positionChild(mLogoView, x, y, contentHeight) + mSpacing;
x += positionChild(mLogoView, x, y, contentHeight);
}
if (mIconView != null && mIconView.getVisibility() != GONE) {
x += positionChild(mIconView, x, y, contentHeight) + mSpacing;
x += positionChild(mIconView, x, y, contentHeight);
}
switch (mNavigationMode) {
case ActionBar.NAVIGATION_MODE_STANDARD:
if (mTitleLayout != null) {
x += positionChild(mTitleLayout, x, y, contentHeight) + mSpacing;
x += positionChild(mTitleLayout, x, y, contentHeight);
}
break;
case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST:
if (mSpinner != null) {
x += positionChild(mSpinner, x, y, contentHeight) + mSpacing;
x += positionChild(mSpinner, x, y, contentHeight);
}
break;
case ActionBar.NAVIGATION_MODE_CUSTOM:
if (mCustomNavView != null) {
x += positionChild(mCustomNavView, x, y, contentHeight) + mSpacing;
x += positionChild(mCustomNavView, x, y, contentHeight);
}
break;
case ActionBar.NAVIGATION_MODE_TABS:
if (mTabScrollView != null) {
x += positionChild(mTabScrollView, x, y, contentHeight) + mSpacing;
x += positionChild(mTabScrollView, x, y, contentHeight);
}
}
x = r - l - getPaddingRight();
if (mMenuView != null) {
x -= positionChildInverse(mMenuView, x + mActionSpacing, y, contentHeight)
- mActionSpacing;
x -= positionChildInverse(mMenuView, x, y, contentHeight);
}
}