blob: 6af1c7e08a4c37ecb7319390ad5b38fb760c3c7f [file] [log] [blame]
/*
* 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.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
/**
* @hide
*/
public class ButtonGroup extends LinearLayout {
private static final String LOG = "ButtonGroup";
private Drawable mDivider;
private int mDividerWidth;
private int mDividerHeight;
private int mButtonBackgroundRes;
private int mShowDividers;
/**
* Don't show any dividers.
*/
public static final int SHOW_DIVIDER_NONE = 0;
/**
* Show a divider at the beginning of the group.
*/
public static final int SHOW_DIVIDER_BEGINNING = 1;
/**
* Show dividers between each item in the group.
*/
public static final int SHOW_DIVIDER_MIDDLE = 2;
/**
* Show a divider at the end of the group.
*/
public static final int SHOW_DIVIDER_END = 4;
private final Rect mTempRect = new Rect();
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, defStyleRes, 0);
setDividerDrawable(a.getDrawable(com.android.internal.R.styleable.ButtonGroup_divider));
mButtonBackgroundRes = a.getResourceId(
com.android.internal.R.styleable.ButtonGroup_buttonBackground, 0);
setShowDividers(a.getInt(com.android.internal.R.styleable.ButtonGroup_showDividers,
SHOW_DIVIDER_MIDDLE));
a.recycle();
}
/**
* Set how dividers should be shown between items in this button group.
*
* @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING},
* {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END},
* or {@link #SHOW_DIVIDER_NONE} to show no dividers.
*/
public void setShowDividers(int showDividers) {
if (showDividers != mShowDividers) {
requestLayout();
}
mShowDividers = showDividers;
}
/**
* @return A flag set indicating how dividers should be shown around items.
* @see #setShowDividers(int)
*/
public int getShowDividers() {
return mShowDividers;
}
/**
* Set a drawable to be used as a divider between items.
* @param divider Drawable that will divide each item.
*/
public void setDividerDrawable(Drawable divider) {
if (divider == mDivider) {
return;
}
mDivider = divider;
if (divider != null) {
mDividerWidth = divider.getIntrinsicWidth();
mDividerHeight = divider.getIntrinsicHeight();
} else {
mDividerWidth = 0;
mDividerHeight = 0;
}
requestLayout();
}
/**
* Retrieve the drawable used to draw dividers between items.
* @return The divider drawable
*/
public Drawable getDividerDrawable() {
return mDivider;
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (child instanceof Button && mButtonBackgroundRes != 0) {
// Preserve original padding as we change the background
final int paddingLeft = child.getPaddingLeft();
final int paddingRight = child.getPaddingRight();
final int paddingTop = child.getPaddingTop();
final int paddingBottom = child.getPaddingBottom();
child.setBackgroundResource(mButtonBackgroundRes);
child.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
super.addView(child, index, params);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Add the extra size that dividers contribute.
int dividerCount = 0;
if ((mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE) {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
if (getChildAt(i).getVisibility() != GONE) {
dividerCount++;
}
}
dividerCount = Math.max(0, dividerCount);
}
if ((mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING) {
dividerCount++;
}
if ((mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END) {
dividerCount++;
}
if (getOrientation() == VERTICAL) {
final int dividerSize = mDividerHeight * dividerCount;
setMeasuredDimension(getMeasuredWidth(),
resolveSize(getMeasuredHeight() + dividerSize, heightMeasureSpec));
} else {
final int dividerSize = mDividerWidth * dividerCount;
setMeasuredDimension(resolveSize(getMeasuredWidth() + dividerSize, widthMeasureSpec),
getMeasuredHeight());
}
}
@Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
final boolean begin = (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
final boolean middle = (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
// Offset children to leave space for dividers.
if (getOrientation() == VERTICAL) {
int offset = begin ? mDividerHeight : 0;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.offsetTopAndBottom(offset);
if (middle && child.getVisibility() != GONE) {
offset += mDividerHeight;
}
}
} else {
int offset = begin ? mDividerWidth : 0;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.offsetLeftAndRight(offset);
if (middle && child.getVisibility() != GONE) {
offset += mDividerWidth;
}
}
}
}
@Override
public void dispatchDraw(Canvas canvas) {
if (mDivider == null) {
super.dispatchDraw(canvas);
return;
}
final boolean begin = (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
final boolean middle = (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
final boolean end = (mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END;
final boolean vertical = getOrientation() == VERTICAL;
final Rect bounds = mTempRect;
bounds.left = mPaddingLeft;
bounds.right = mRight - mLeft - mPaddingRight;
bounds.top = mPaddingTop;
bounds.bottom = mBottom - mTop - mPaddingBottom;
if (begin) {
if (vertical) {
bounds.bottom = bounds.top + mDividerHeight;
} else {
bounds.right = bounds.left + mDividerWidth;
}
mDivider.setBounds(bounds);
mDivider.draw(canvas);
}
final int childCount = getChildCount();
int i = 0;
while (i < childCount) {
final View child = getChildAt(i);
i++;
if ((middle && i < childCount && child.getVisibility() != GONE) || end) {
if (vertical) {
bounds.top = child.getBottom();
bounds.bottom = bounds.top + mDividerHeight;
} else {
bounds.left = child.getRight();
bounds.right = bounds.left + mDividerWidth;
}
mDivider.setBounds(bounds);
mDivider.draw(canvas);
}
}
super.dispatchDraw(canvas);
}
}