先看效果圖:
效果圖.png
分析這是線性漸變色,圓弧半徑剛好是高度的一半翁狐,文字居中處理,大小凌蔬,顏色可調(diào)
首先開始自定義控件的基本步驟
1露懒、style自定義屬性
<!--自定義控件屬性-->
<declare-styleable name="MyGradientRoundButton">
<attr name="colorStart" format="reference" />
<attr name="colorEnd" format="reference" />
<attr name="round" format="dimension" />
<attr name="clickEffect" format="boolean" />
<attr name="colorPressStart" format="reference" />
<attr name="colorPressEnd" format="reference" />
<attr name="btnText" format="reference" />
<attr name="btnTextSize" format="dimension" />
<attr name="btnTextColor" format="reference" />
</declare-styleable>
注:原本我是想還有點(diǎn)擊效果的
2、繼承view核心代碼
public class MyGradientRoundButton extends View {
private int colorStart;
private int colorEnd;
private int colorPressStart;
private int colorPressEnd;
private int colorS;
private int colorE;
private String text;
private int textColor;
private float textSize;
private float round;
private boolean clickEffect;
private RectF mBackGroundRect;
private LinearGradient backGradient;
//默認(rèn)畫筆
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mPaintText = new Paint();
public MyGradientRoundButton(Context context, AttributeSet attrs) {
super(context, attrs);
//獲取自定義屬性
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyGradientRoundButton);
colorStart = typedArray.getColor(R.styleable.MyGradientRoundButton_colorStart, getResources().getColor(R.color.btn_color_start));
colorEnd = typedArray.getColor(R.styleable.MyGradientRoundButton_colorEnd, getResources().getColor(R.color.btn_color_end));
round = typedArray.getDimension(R.styleable.MyGradientRoundButton_round, Utils.dip2px(context, 10));
clickEffect = typedArray.getBoolean(R.styleable.MyGradientRoundButton_clickEffect, false);
colorPressStart = typedArray.getColor(R.styleable.MyGradientRoundButton_colorPressStart, getResources().getColor(R.color.btn_color_PStart));
colorPressEnd = typedArray.getColor(R.styleable.MyGradientRoundButton_colorPressEnd, getResources().getColor(R.color.btn_color_PEnd));
text = typedArray.getString(R.styleable.MyGradientRoundButton_btnText);
textColor = typedArray.getColor(R.styleable.MyGradientRoundButton_btnTextColor, getResources().getColor(R.color.black));
textSize = typedArray.getDimension(R.styleable.MyGradientRoundButton_btnTextSize, 16);
colorS = colorStart;
colorE = colorEnd;
typedArray.recycle();
}
//必須加砂心,否則onTouchEvent只響應(yīng)ACTION_DOWN
setClickable(true);
//設(shè)置抗鋸齒
mPaint.setAntiAlias(true);
//設(shè)置防抖動(dòng)
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL);
mPaintText.setAntiAlias(true);
mPaintText.setDither(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBackGroundRect = new RectF(0, 0, w, h);
backGradient = new LinearGradient(0, 0, w, 0, new int[]{colorS, colorE}, null, Shader.TileMode.CLAMP);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(backGradient);
//繪制背景 圓角矩形
if (mBackGroundRect != null) {
canvas.drawRoundRect(mBackGroundRect, round, round, mPaint);
}
//繪制文字
mPaintText.setTextSize(textSize);
mPaintText.setColor(textColor);
mPaintText.setTextAlign(Paint.Align.CENTER);
Paint.FontMetricsInt fontMetrics = mPaintText.getFontMetricsInt();
float baseline = mBackGroundRect.top + (mBackGroundRect.bottom - mBackGroundRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
canvas.drawText(text, canvas.getWidth() / 2, baseline, mPaintText);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (clickEffect) {
//刷新
invalidate();
//判斷點(diǎn)擊操作
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
colorS = colorPressStart;
colorE = colorPressEnd;
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
colorS = colorStart;
colorE = colorEnd;
break;
case MotionEvent.ACTION_CANCEL:
break;
}
}
return super.onTouchEvent(event);
}
public void setText(String text) {
if (!TextUtils.isEmpty(text)) {
this.text = text;
invalidate();
}
}}
關(guān)鍵代碼講解:
onDraw():繪制圖形過程懈词,canvas.drawXXX()就是在繪制一層層圖層,所以drawRoundRect要在drawText之前
LinearGradient:線性漸變色
RectF:正方形辩诞,配合drawRoundRect就可以畫出帶圓角的圖形
onSizeChanged():發(fā)生在onDraw()之前坎弯,一般可以做些不變的參數(shù)設(shè)定,調(diào)用onDraw(),它也不調(diào)用的
invalidate():每調(diào)一次,也就調(diào)用了一次onDraw()方法荞怒,這樣就可以做點(diǎn)擊效果了
3、引用列子
<com.yiban1314.yiyue.widge.MyGradientRoundButton
android:id="@+id/dialog_guide_reg"
android:layout_width="match_parent"
android:layout_height="@dimen/d80px"
app:clickEffect="false"
app:round="@dimen/d40px"
app:colorStart="@color/btn_color_start"
app:colorEnd="@color/btn_color_end"
app:btnText="@string/register"
app:btnTextColor="@color/c_22"
app:btnTextSize="@dimen/s32px"
android:layout_marginBottom="@dimen/d64px"
android:layout_marginTop="@dimen/d64px"/>
這個(gè)自定義控件有個(gè)缺陷寬高不能用wrap_content屬性秧秉。