package com.hjdz.install.widget; import com.hjdz.install.R; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.graphics.Paint.FontMetricsInt; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.text.TextPaint; import android.text.TextUtils; import android.util.AttributeSet; import android.widget.RadioButton; /** * * <p>Tab with drawable and text elements, you can use both or one of them. Also , there has simple tip for the Tap , you can decide the Style all by your self.. * <p> hope you like it :-) * @author Darcy * @site www.darcye.com */ public class TabView extends RadioButton{ private Drawable buttonDrawable; private int mDrawableWidth; private int mDrawableHeight; private int mTipBackgroundColor; private int mTipTextColor; private int mTipTextSize; private int mTipDotRadius; private int mTextDotRadius; private TextPaint mTipTextPaint; private Paint mTipBgPaint; private boolean mHasTip; private String mTipText; private int mDrawableLableGap; private RectF mOvalRectF = new RectF(); private int mTipTextDotTopMargin; private int mTipTextDotRightMargin; private int mTipDotTopMargin; private int mTipDotRightMargin; private int mDotOvalPadding; public TabView(Context context, AttributeSet attrs) { super(context, attrs); Resources res = context.getResources(); TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CompoundButton, 0, 0); buttonDrawable = a.getDrawable(R.styleable.CompoundButton_android_button); mDrawableWidth = a.getDimensionPixelSize(R.styleable.CompoundButton_drawableWidth, 0); mDrawableHeight = a.getDimensionPixelSize(R.styleable.CompoundButton_drawableHeight, 0); a.recycle(); TypedArray iconTypedArray = context.obtainStyledAttributes(attrs,R.styleable.TabView, 0, 0); mTipBackgroundColor = iconTypedArray.getColor(R.styleable.TabView_TipBackgroundColor,res.getColor(R.color.default_tab_tip_dot_bg)); mTipTextColor = iconTypedArray.getColor(R.styleable.TabView_TipTextColor,res.getColor(R.color.default_tab_tip_text_color)); mTipTextSize = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TipTextSize, res.getDimensionPixelSize(R.dimen.tab_lable_text_size)); mTipDotRadius = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TipDotRadius, res.getDimensionPixelSize(R.dimen.tab_tip_red_dot_radius)); mTextDotRadius = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TextDotRadius, res.getDimensionPixelSize(R.dimen.tab_tip_text_red_dot_radius)); mDrawableLableGap = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_DrawableLableGap, res.getDimensionPixelSize(R.dimen.tab_drawable_lable_gap)); mTipTextDotRightMargin = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TipTextDotRightMargin, res.getDimensionPixelSize(R.dimen.tab_tip_text_dot_right_margit)); mTipTextDotTopMargin = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TipTextDotTopMargin, res.getDimensionPixelSize(R.dimen.tab_tip_text_dot_right_margit)); mTipDotRightMargin = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TipDotRightMargin, res.getDimensionPixelSize(R.dimen.tab_tip_dot_right_margit)); mTipDotTopMargin = iconTypedArray.getDimensionPixelSize(R.styleable.TabView_TipDotTopMargin, res.getDimensionPixelSize(R.dimen.tab_tip_dot_right_margit)); iconTypedArray.recycle(); setButtonDrawable(R.drawable.empty_drawable); mDotOvalPadding = res.getDimensionPixelSize(R.dimen.tab_tip_dot_oval_padding); mTipBgPaint = new Paint(); mTipBgPaint.setColor(mTipBackgroundColor); mTipBgPaint.setAntiAlias(true); mTipTextPaint = new TextPaint(); mTipTextPaint.setColor(mTipTextColor); mTipTextPaint.setTextSize(mTipTextSize); mTipTextPaint.setAntiAlias(true); } /** * when there exists tip text and dot tip at the same time, text will show to front * @see {@link #setTipText(String tipText)} * @param hasTip */ public void setHasTip(boolean hasTip) { if(mHasTip == hasTip) return; mHasTip = hasTip; invalidate(); } /** * when there exists tip text and dot tip at the same time, text will show to front * @see {@link #setHasTip(boolean hasTip)} * @param tipText */ public void setTipText(String tipText) { if(mTipText == tipText || (mTipText != null && mTipText.equals(tipText))) return; mTipText = tipText; invalidate(); } @Override protected void onDraw(Canvas canvas) { final int width = getWidth(); final int height = getHeight(); final int[] drawableState = getDrawableState(); //draw backgroud Drawable backgroundDrawable = getBackground(); if(backgroundDrawable != null){ backgroundDrawable.setState(drawableState); backgroundDrawable.setBounds(0, 0, width, height); backgroundDrawable.draw(canvas); } final CharSequence lableText = getText(); boolean noLable = false; if(lableText == null || lableText.length() == 0){ noLable = true; } final TextPaint lablePaint = getPaint(); final float lableTextHeight = calculateFontHeight(lablePaint); int buttonDrawableBottom = 0; //draw drawable if (buttonDrawable != null) { buttonDrawable.setState(drawableState); final int drawableHeight = mDrawableWidth == 0? buttonDrawable.getIntrinsicHeight() : mDrawableWidth; int drawableY = 0; if(noLable){ drawableY = (height - drawableHeight) / 2; }else{ drawableY = (int) ((height - drawableHeight - lableTextHeight - mDrawableLableGap) / 2); } int drawableWidth = mDrawableHeight == 0 ? buttonDrawable.getIntrinsicWidth() : mDrawableHeight; int drawableLeft = (width - drawableWidth) / 2; buttonDrawableBottom = drawableY+ drawableHeight; buttonDrawable.setBounds(drawableLeft, drawableY, drawableLeft + drawableWidth, buttonDrawableBottom); buttonDrawable.draw(canvas); } //draw lable text if(!noLable){ ColorStateList lableCSList = getTextColors(); int curColor = lableCSList.getColorForState(drawableState, lableCSList.getDefaultColor()); lablePaint.setColor(curColor); String drawLableText = lableText.toString(); int lableTextWidth = calculateStringWidth(lablePaint, drawLableText); int lableX = ( width - lableTextWidth ) / 2; int lableY = (int) (buttonDrawable != null ? buttonDrawableBottom + mDrawableLableGap - lablePaint.getFontMetrics().top : ( height - lableTextHeight ) / 2 - lablePaint.getFontMetrics().top) ;; canvas.drawText(drawLableText, lableX, lableY, lablePaint); } //draw tip if(!TextUtils.isEmpty(mTipText)){ final float tipTextWidth = mTipTextPaint.measureText(mTipText); final int rightMargin = mTipTextDotRightMargin; int cx,cy ; int textX, textY; final int dotDiameter = mTextDotRadius * 2; final FontMetricsInt fontMetrics = mTipTextPaint.getFontMetricsInt(); final int fontHeight = fontMetrics.bottom - fontMetrics.top; textY = (int) (rightMargin + (dotDiameter - fontHeight) * 0.5 - fontMetrics.top); if(tipTextWidth < dotDiameter){ cx = width - mTextDotRadius - rightMargin; cy = mTipTextDotTopMargin + mTextDotRadius; canvas.drawCircle(cx, cy, mTextDotRadius, mTipBgPaint); textX = (int) (width - (dotDiameter - tipTextWidth ) * 0.5 - rightMargin - tipTextWidth); canvas.drawText(mTipText, textX, textY, mTipTextPaint); }else{ final int ovalPadding = mDotOvalPadding; int ovalWidth = (int) (tipTextWidth + 2 * ovalPadding); final RectF ovalRect = mOvalRectF; ovalRect.right = width - rightMargin; ovalRect.left = ovalRect.right - ovalWidth; ovalRect.top = mTipTextDotTopMargin; ovalRect.bottom = ovalRect.top + dotDiameter; canvas.drawOval(ovalRect, mTipBgPaint); textX = (int) (width - (ovalRect.right - ovalRect.left - tipTextWidth ) * 0.5 - rightMargin - tipTextWidth); canvas.drawText(mTipText, textX, textY, mTipTextPaint); } }else if(mHasTip){ int cx,cy ; final int rightMargin = mTipDotRightMargin; cy = mTipDotTopMargin + mTipDotRadius; cx = width - rightMargin - mTipDotRadius; canvas.drawCircle(cx, cy, mTipDotRadius, mTipBgPaint); } } /** * Calculate the font height of a specific TextPaint * @param textPaint * @return */ private float calculateFontHeight(TextPaint textPaint){ FontMetrics fontMetrics = textPaint.getFontMetrics(); return fontMetrics.bottom - fontMetrics.top; } /** * calculate the width of a string with a specific TextPaint * @param paint * @param s * @return */ private int calculateStringWidth(Paint paint, String s) { int iRet = 0; if (s != null && s.length() > 0) { int len = s.length(); float[] widths = new float[len]; paint.getTextWidths(s, widths); for (int j = 0; j < len; j++) { iRet += (int) Math.ceil(widths[j]); } } return iRet; } }