/* * 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); } }