寸阳分阴须爱惜,休负春色与时光。这篇文章主要讲述Android 自定义View - 饼图相关的知识,希望能为你提供帮助。
【Android 自定义View - 饼图】最近有看到一个自定义等分圆的View,自己尝试做了一个类似的,效果图如下图(1)所示:
文章图片
图(1)
实现方法:自定义View-ColorCircle,需要的知道的值有圆的半径,等分个数以及扇形颜色。
/** * 定义几种颜色 */ private static int COLOR[] = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.BLACK}; /** * 圆等分默认数目 */ private static int DIV_SIZE = 3; private Paint mPaint; /**
* 圆默认半径
*/ private static final int DEFAULT_RADIUS = 200; private int mRadius = DEFAULT_RADIUS;
public ColorCircle(Context context) { this(context, null); }public ColorCircle(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); }public ColorCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); }
在onMeasure中我们需要根据widthMeasureSpec & heightMeasureSpec重新计算ColorCircle View的尺寸以及圆的半径(因为默认圆的直径可能会大于View的高 or 宽)。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = mRadius * 2 + getPaddingLeft() + getPaddingRight(); if (widthMode == MeasureSpec.AT_MOST) { width = Math.min(width, widthSize); } }if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = mRadius * 2 + getPaddingTop() + getPaddingBottom(); if (heightMode == MeasureSpec.AT_MOST) { height = Math.min(width, heightSize); } }setMeasuredDimension(width, height); mRadius = (int) (Math.min(width - getPaddingLeft() - getPaddingRight(), height - getPaddingTop() - getPaddingBottom()) * 1.0f / 2); }
最后在onDraw里通过canvas.drawArc()来绘制扇形。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas);
//平移Canvas到屏幕中心,之后的绘制以中心点为初始点 canvas.translate((getWidth() + getPaddingLeft() - getPaddingRight()) / 2,
(getHeight() + getPaddingTop() - getPaddingBottom()) / 2);
//定义一个RectF对象,表示扇形绘制区域 RectF oval = new RectF(-mRadius, -mRadius, mRadius, mRadius); float firstAngle = 0.0f; float divideAngle = (360 * 1.0f) / DIV_SIZE; //根据DIV_SIZE来算每个扇形的角度 for (int i=0; i< DIV_SIZE; i++) { mPaint.setColor(COLOR[i]); canvas.drawArc(oval, (firstAngle + i * divideAngle), divideAngle, true, mPaint); } }
public void setDivSize(int size){
DIV_SIZE = size;
invalidate();
}
public int getDivSize(){
DIV_SIZE = size;
}
最后还预留了一个setDivSize()接口,方便自定义ColorCircle View动态变化扇形数目。我这里是通过Seekbar来动态切换DIV_SIZE。
mColorCircle = (ColorCircle)findViewById(R.id.color_circle); mSeekBar = (SeekBar)findViewById(R.id.seek_bar); mSeekBar.setMax(4); //因为颜色数目原因,这里seekBar的最大值设置为了4。
int pro = mColorCircle.getSize(); mSeekBar.setProgress(pro); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mColorCircle.setDivSize(progress + 1); }@Override public void onStartTrackingTouch(SeekBar seekBar) { }@Override public void onStopTrackingTouch(SeekBar seekBar) { } });
效果图如下:
文章图片
文章图片
文章图片
文章图片
推荐阅读
- xxx.app已损坏,打不开.你应该将它移到废纸篓-已解决
- Android 使用AIDL实现进程间的通信
- 25款最佳免费绿屏(色度键)软件和应用程序
- 18款最佳免费DVD复制软件合集(哪个最适合你())
- PC的19款最佳视频压缩软件合集(免费/付费)
- 22款Windows的最佳免费屏幕录制软件合集
- 30款最佳屏幕截图软件、工具和应用程序合集
- 25个最佳M4V转MP4转换器合集(免费/付费)
- 40大最佳视频编辑软件合集(哪个最适合你())