项目下载地址:http://download.csdn.net/detail/fkgjdkblxckvbxbgb/9729162
上一篇文章的大概思想我已经说了,这一篇主要是展示细节工作,自定义属性,测量尺寸,以及一些异常情况的处理
如果有兴趣了解绘图方式,可以去看文件一,源代码下面可以提供下载
====================================================
自定义属性
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyView"> <attr name="viewbg" format="color" /> <attr name="progresscolor" format="color" /> <attr name="progresswidth" format="dimension" /> <attr name="textsize" format="dimension" /> <attr name="textcolor" format="color" /> </declare-styleable> </resources>
布局文件=======================================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <com.cdl.demo.MyView android:id="@+id/myview" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" app:progresscolor="#BA55D3" app:progresswidth="20dp" app:textcolor="#ffffff" app:textsize="20dp" app:viewbg="#B0C4DE" /> </RelativeLayout>=================================================
Activity中的引用
package com.cdl.demo; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { MyView myview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myview = (MyView) findViewById(R.id.myview); myview.setProgress(80); // } }==================提供两种方法来绘图=================================1:在主线程中去绘制
2:开线程绘制
个人觉得两个没什么多大的区别,
===============主线程绘制====================================
package com.cdl.demo; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Cap; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint mPaint; /** 画笔的宽度 */ int PROGRESS_WIDTH; /** 半径 */ int circleRadius; /** 文字的描述 */ String textDesc; /** 文字的大小尺寸 */ int TEXT_SIXE; int TEXT_COLOR; int progress = 0; private int PROGRESS_BG; private int PROGRESS_COLOR; boolean running = true; /** 开启线程绘制View */ // MyThread myThread; /** 画弧度递增的变量 */ private int sweepAngle = 0; public MyView(Context context) { this(context, null); } public MyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyView); PROGRESS_BG = ta.getColor(R.styleable.MyView_viewbg, 0xffffffff); PROGRESS_COLOR = ta.getColor(R.styleable.MyView_progresscolor, 0xff7fc6f8); TEXT_COLOR = ta.getColor(R.styleable.MyView_textcolor, 0xff9A32CD); TEXT_SIXE = ta.getDimensionPixelOffset(R.styleable.MyView_textsize, 30); PROGRESS_WIDTH = ta.getDimensionPixelOffset(R.styleable.MyView_progresswidth, 30); ta.recycle(); initView(); } private void initView() { mPaint = new Paint(); mPaint.setAntiAlias(true); // mPaint.setDither(true);// 设置抖动,颜色过渡更均匀 mPaint.setStrokeCap(Cap.ROUND); } public int defaultWidth = 300; protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecModel = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecModel = MeasureSpec.getMode(heightMeasureSpec); int heightSpcSzie = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecModel == MeasureSpec.AT_MOST & heightSpecModel == MeasureSpec.AT_MOST) { widthSpecSize = defaultWidth; heightSpcSzie = defaultWidth; circleRadius = defaultWidth; } else if (widthSpecModel == MeasureSpec.AT_MOST) { widthSpecSize = defaultWidth; circleRadius = defaultWidth; } else if (heightSpecModel == MeasureSpec.AT_MOST) { heightSpcSzie = defaultWidth; circleRadius = defaultWidth; } circleRadius = widthSpecSize; setMeasuredDimension(widthSpecSize, heightSpcSzie); } public void setProgress(int progress) { this.progress = progress; if (running) { System.out.println("====打断"); running = false; } running = true; invalidate(); } protected void onDraw(final Canvas canvas) { super.onDraw(canvas); /** 绘制背景 */ drawbg(canvas); drawText(canvas); drawProgress(canvas); if (sweepAngle != progress) { sweepAngle++; invalidate(); } } private void drawProgress(final Canvas canvas) { int width = getWidth(); int height = getHeight(); mPaint.setColor(PROGRESS_COLOR); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(PROGRESS_WIDTH); int left = width / 2 - circleRadius / 2 + PROGRESS_WIDTH / 2; int top = height / 2 - circleRadius / 2 + PROGRESS_WIDTH / 2; int right = width / 2 + circleRadius / 2 - PROGRESS_WIDTH / 2; int bottom = height / 2 + circleRadius / 2 - PROGRESS_WIDTH / 2; RectF oval1 = new RectF(left, top, right, bottom); int arc = sweepAngle * 360 / 100; canvas.drawArc(oval1, 0, arc, false, mPaint);// 小弧形 } private void drawText(final Canvas canvas) { textDesc = sweepAngle + "%"; final int width = getWidth(); final int height = getHeight(); final Rect bounds = new Rect(); mPaint.setColor(TEXT_COLOR); mPaint.setStyle(Paint.Style.FILL); mPaint.setTextSize(TEXT_SIXE); mPaint.getTextBounds(textDesc, 0, textDesc.length(), bounds); canvas.drawText(textDesc, (width / 2) - (bounds.width() / 2), (height / 2) + (bounds.height() / 2), mPaint); } private void drawbg(Canvas canvas) { int width = getWidth(); int height = getHeight(); mPaint.setColor(PROGRESS_BG); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setStrokeWidth(PROGRESS_WIDTH); canvas.drawCircle(width / 2, height / 2, circleRadius / 2 - PROGRESS_WIDTH / 2, mPaint); } }
=====================开线程============================
package com.example.videodemo; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Cap; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint mPaint; /** 画笔的宽度 */ int PROGRESS_WIDTH; /** 半径 */ int circleRadius; /** 文字的描述 */ String textDesc; /** 文字的大小尺寸 */ int TEXT_SIXE; /**文字的颜色*/ int TEXT_COLOR; /**进度*/ int progress = 0; /**控件的背景色*/ private int PROGRESS_BG; /**进度的颜色*/ private int PROGRESS_COLOR; boolean running = true; /** 开启线程绘制View */ MyThread myThread; /** 画弧度递增的变量 */ private int sweepAngle; public MyView(Context context) { this(context, null); } public MyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //获取自定义的属性 TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyView); PROGRESS_BG = ta.getColor(R.styleable.MyView_viewbg, 0xffffffff); PROGRESS_COLOR = ta.getColor(R.styleable.MyView_progresscolor, 0xff7fc6f8); TEXT_COLOR = ta.getColor(R.styleable.MyView_textcolor, 0xff9A32CD); TEXT_SIXE = ta.getDimensionPixelOffset(R.styleable.MyView_textsize, 30); PROGRESS_WIDTH = ta.getDimensionPixelOffset(R.styleable.MyView_progresswidth, 30); ta.recycle(); initView(); } private void initView() { mPaint = new Paint(); mPaint.setAntiAlias(true); // mPaint.setDither(true);// 设置抖动,颜色过渡更均匀 mPaint.setStrokeCap(Cap.ROUND); } /**如果用户设置wap_content,默认尺寸为300*/ public int defaultWidth = 300; protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecModel = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecModel = MeasureSpec.getMode(heightMeasureSpec); int heightSpcSzie = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecModel == MeasureSpec.AT_MOST & heightSpecModel == MeasureSpec.AT_MOST) { widthSpecSize = defaultWidth; heightSpcSzie = defaultWidth; circleRadius = defaultWidth; } else if (widthSpecModel == MeasureSpec.AT_MOST) { widthSpecSize = defaultWidth; circleRadius = defaultWidth; } else if (heightSpecModel == MeasureSpec.AT_MOST) { heightSpcSzie = defaultWidth; circleRadius = defaultWidth; } circleRadius = widthSpecSize; setMeasuredDimension(widthSpecSize, heightSpcSzie); } public void setProgress(int progress) { this.progress = progress; //用户频繁设置进度,防止界面异常,直接停止刷新,每次重新绘制 if (running) { running = false; } running = true; invalidate(); } protected void onDraw(final Canvas canvas) { super.onDraw(canvas); /** 绘制背景.背景只用绘制一次 */ drawbg(canvas); if (myThread == null) { myThread = new MyThread(); myThread.start(); } else { drawText(canvas); drawProgress(canvas); } } // 开启一个子线程绘制ui private class MyThread extends Thread { @Override public void run() { while (running) { logic(); postInvalidate(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } protected void logic() { sweepAngle += 1; mPaint.setColor(Color.RED); if (sweepAngle == progress) { running = false; } } private void drawProgress(final Canvas canvas) { /** 画笔旋转的角度 */ int width = getWidth(); int height = getHeight(); mPaint.setColor(PROGRESS_COLOR); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(PROGRESS_WIDTH); int left = width / 2 - circleRadius / 2 + PROGRESS_WIDTH / 2; int top = height / 2 - circleRadius / 2 + PROGRESS_WIDTH / 2; int right = width / 2 + circleRadius / 2 - PROGRESS_WIDTH / 2; int bottom = height / 2 + circleRadius / 2 - PROGRESS_WIDTH / 2; RectF oval1 = new RectF(left, top, right, bottom); int arc = sweepAngle * 360 / 100; canvas.drawArc(oval1, 0, arc, false, mPaint);// 小弧形 } private void drawText(final Canvas canvas) { textDesc = sweepAngle + "%"; final int width = getWidth(); final int height = getHeight(); final Rect bounds = new Rect(); mPaint.setColor(TEXT_COLOR); mPaint.setStyle(Paint.Style.FILL); mPaint.setTextSize(TEXT_SIXE); mPaint.getTextBounds(textDesc, 0, textDesc.length(), bounds); canvas.drawText(textDesc, (width / 2) - (bounds.width() / 2), (height / 2) + (bounds.height() / 2), mPaint); } private void drawbg(Canvas canvas) { int width = getWidth(); int height = getHeight(); mPaint.setColor(PROGRESS_BG); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setStrokeWidth(PROGRESS_WIDTH); canvas.drawCircle(width / 2, height / 2, circleRadius / 2 - PROGRESS_WIDTH / 2, mPaint); } }