最近研究了下自定義View,就自己寫了個Demo練練手复斥。網(wǎng)上有很多講自定義View實現(xiàn)的文章营密,我這里就不說了,直接上Demo目锭。
先看下效果
八卦圖.png
實現(xiàn)思路
1评汰、左右兩邊分別畫一個背景為黑色和白色的半圓。
2痢虹、上下畫兩個小圓
3被去、最后畫魚眼
實現(xiàn)步驟
1、設置自定義屬性
//這里我們設置了兩個屬性奖唯,一個是背景色惨缆,另一個是八卦的半徑
<declare-styleable name="BaGuaView">
<attr name="bgColor" format="color"></attr>
<attr name="radius" format="integer"></attr>
</declare-styleable>
2、定義畫筆和其他屬性
/**
* 黑色畫筆
*/
private Paint mBlackPaint;
/**
* 白色畫筆
*/
private Paint mWhitePaint;
/**
* 背景顏色
*/
private int mBgColor;
/**
* 八卦半徑
*/
private int mRadius;
3丰捷、初始化畫筆
public BaGuaView(Context context) {
this(context, null);
}
public BaGuaView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BaGuaView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BaGuaView, defStyleAttr, 0);
try {
mBgColor = array.getColor(R.styleable.BaGuaView_bgColor, Color.GRAY);//默認為棕色
mRadius = array.getInteger(R.styleable.BaGuaView_radius, 100);//默認半徑為100
} finally {
array.recycle();
}
mWhitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mWhitePaint.setColor(Color.WHITE);
mBlackPaint.setColor(Color.BLACK);
}
4坯墨、畫兩個半圓
//將Canvas坐標移動到畫布中心
canvas.translate(getWidth() / 2, getHeight() / 2);
//設置背景色
canvas.drawColor(mBgColor);
//設置繪制區(qū)域,這里是以畫布中心為坐標原點
RectF rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
//畫左邊黑色半圓
canvas.drawArc(rectF, 90, 180, true, mBlackPaint);
//畫右邊白色半圓
canvas.drawArc(rectF, -90, 180, true, mWhitePaint);
效果如下
八卦1.png
5病往、繪制兩個魚頭
//圓心分別上下移動半徑的一半捣染,半徑為原來的一半
canvas.drawCircle(0, -mRadius / 2, mRadius / 2, mBlackPaint);
canvas.drawCircle(0, mRadius / 2, mRadius / 2, mWhitePaint);
效果如下
八卦2.png
6、繪制魚眼
//畫兩個更小的圓荣恐,還以魚頭的圓心為圓心液斜,半徑為原半徑的1/6,這個值可以自己設定
canvas.drawCircle(0, -mRadius / 2, mRadius / 6, mWhitePaint);
canvas.drawCircle(0, mRadius / 2, mRadius / 6, mBlackPaint);
效果如下
八卦3.png
7累贤、讓八卦轉動起來
//設置旋轉角度
private float degrees = 0;
//設置完背景色之后讓Canvas旋轉
degrees = degrees + 3;
canvas.rotate(degrees);
//在八卦繪制完成之后每隔15ms刷新繪制,實現(xiàn)旋轉效果
postInvalidateDelayed(15);
這樣我們就通過自定義View實現(xiàn)了八卦圖的功能叠穆。是不是很酷炫呀。
完整代碼
public class BaGuaView extends View {
/**
* 黑色畫筆
*/
private Paint mBlackPaint;
/**
* 白色畫筆
*/
private Paint mWhitePaint;
/**
* 背景顏色
*/
private int mBgColor;
/**
* 八卦半徑
*/
private int mRadius;
public BaGuaView(Context context) {
this(context, null);
}
public BaGuaView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BaGuaView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BaGuaView, defStyleAttr, 0);
try {
mBgColor = array.getColor(R.styleable.BaGuaView_bgColor, Color.GRAY);//默認為棕色
mRadius = array.getInteger(R.styleable.BaGuaView_radius, 100);//默認半徑為100
} finally {
array.recycle();
}
mWhitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mWhitePaint.setColor(Color.WHITE);
mBlackPaint.setColor(Color.BLACK);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
//設定寬度
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = getPaddingLeft() + getPaddingRight() + widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = getPaddingLeft() + getPaddingRight() + mRadius * 2;
}
//設定高度
int heightMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(widthMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
height = getPaddingBottom() + getPaddingTop() + heightSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
height = getPaddingBottom() + getPaddingTop() + mRadius * 2;
}
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
//設置旋轉角度
private float degrees = -5;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//將Canvas坐標移動到畫布中心
canvas.translate(getWidth() / 2, getHeight() / 2);
//設置背景色
canvas.drawColor(mBgColor);
//設置完背景色之后讓Canvas旋轉
degrees = degrees + 5;
canvas.rotate(degrees);
//設置繪制區(qū)域臼膏,這里是以畫布中心為坐標原點
RectF rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
//畫左邊黑色半圓
canvas.drawArc(rectF, 90, 180, true, mBlackPaint);
//畫右邊白色半圓
canvas.drawArc(rectF, -90, 180, true, mWhitePaint);
//繪制兩個小圓
canvas.drawCircle(0, -mRadius / 2, mRadius / 2, mBlackPaint);
canvas.drawCircle(0, mRadius / 2, mRadius / 2, mWhitePaint);
//
//繪制兩個魚眼硼被,畫兩個更小的圓,還以剛魚頭的圓心為圓心渗磅,半徑為原半徑的1/6,這個值可以自己設定
canvas.drawCircle(0, -mRadius / 2, mRadius / 6, mWhitePaint);
canvas.drawCircle(0, mRadius / 2, mRadius / 6, mBlackPaint);
//每隔15ms刷新
postInvalidateDelayed(15);
}
}