自定义View————圆环和圆环进度条

来源:互联网 发布:qq企业邮箱绑定域名 编辑:程序博客网 时间:2024/05/16 11:17

可能小伙伴们感觉自定义view很高深,其实大家用多了别人的轮子,研究别人的轮子,自己也要学着造轮子,那就用最简单的练练手,教小伙伴们自定义view的一些步骤,这可能是小伙伴们最需要的。

自定义圆环

import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;import org.w3c.dom.Attr;import example.com.mvpdesign.R;/** * Created by qiang.lin */public class RingView extends View {    //画笔    private Paint mPaint;    //圆环的颜色    private int ringColor;    private int width;    private int high;    private int center;    public RingView(Context context) {        this(context, null);    }    public RingView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }     //看了很多自定义view,也用了很多自定义view,View是会自动//调用带有两个参数的构造器,但是我看了大神的的代码,基本上都是指//向三个构造器。    public RingView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //获取自定义的属性,并赋予初始值。        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingView);        ringColor=  typedArray.getColor(R.styleable.RingView_ringColor, Color.RED);        textSize=  typedArray.getDimensionPixelSize(R.styleable.RingView_ringText, 20);        typedArray.recycle();        //初始化画笔        mPaint = new Paint();        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setDither(true);        mPaint.setAntiAlias(true);    }    //这里获取canvas的高度和宽度,没有使用到,但是经常会使用到,可以研究下。    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        center = getWidth() / 2;        width = getWidth();        high = getHeight();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //半径        int innerCircle=60;        //圆环宽度        int ringWidth=30;        //绘制圆环        mPaint.setColor(ringColor);        //画笔的笔触是在宽度的中间,所以后面需要      //  ringWidth/2,这个才是真实半径        mPaint.setStrokeWidth(ringWidth);        canvas.drawCircle(200,200,innerCircle+ringWidth,mPaint);        //重绘ondraw方法,这个方法就是相当于刷新        invalidate();    }    /**     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)     */    public static int dip2px(Context context, float dpValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dpValue * scale + 0.5f);    }}

配置文件

    <declare-styleable name="RingView">        <attr name="ringColor" format="color"></attr>        <attr name="ringText" format="dimension"></attr>    </declare-styleable>

配置文件在最顶部加上这句

  xmlns:app="http://schemas.android.com/apk/res-auto"

这里一个自定义的圆环就完成了。下面来看看自定义圆环进度条。

import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Typeface;import android.util.AttributeSet;import android.view.View;import example.com.mvpdesign.R;/** * Created by qiang.lin */public class RoundProgressBar extends View {    private int textSize;    private int textColor;    private int ringColor;    private int progressColor;    private int width;    private int high;    private Paint mPaint;    private int progress=50;    private int max=100;    public RoundProgressBar(Context context) {        this(context, null);    }    public RoundProgressBar(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //初始化自定义属性        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);        textSize = typedArray.getDimensionPixelSize(R.styleable.RoundProgressBar_textSize, 50);        textColor = typedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.RED);        ringColor = typedArray.getColor(R.styleable.RoundProgressBar_ringColors, Color.CYAN);        progressColor = typedArray.getColor(R.styleable.RoundProgressBar_progessColor, Color.BLUE);        typedArray.recycle();        //初始化画笔        mPaint = new Paint();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        high = getHeight();        width = getWidth();        //内容的半径//        center=getWidth()/2;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //画背景的圆环,获取的是画布的宽度        int roundWidth = 10;        int center = getWidth() / 2;//圆心        int radius = center - roundWidth /2-5;        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setColor(ringColor);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(roundWidth);        canvas.drawCircle(center, center, radius, mPaint);        //画进度条变分比。        mPaint.setStrokeWidth(0);        mPaint.setColor(textColor);        mPaint.setTextSize(textSize);        mPaint.setTypeface(Typeface.DEFAULT_BOLD);        int percent = (int) (((float) progress / (float) max) * 100);        float textWidth = mPaint.measureText(percent + "%");        if(percent!=0){            canvas.drawText(percent+"%",center-textWidth/2,center+textSize/2,mPaint);        }        //画进度条        mPaint.setStrokeWidth(roundWidth);        mPaint.setColor(progressColor);        //画圆形的区域。        RectF oval=new RectF(center-radius,center-radius,center+radius,center+radius);        mPaint.setStyle(Paint.Style.STROKE);        canvas.drawArc(oval, 90, -360 * progress / max, false, mPaint);  //根据进度画圆弧        invalidate();    }    public int getTextSize() {        return textSize;    }//通过代码来设置字体大小。    public void setTextSize(int textSize) {        this.textSize = textSize;        //重新绘制,走ondraw()        invalidate();    }}
<declare-styleable name="RoundProgressBar">    <attr name="textSize" format="dimension"></attr>    <attr name="ringColors" format="color"></attr>    <attr name="progessColor" format="color"></attr>    <attr name="ringWidth" format="dimension"></attr>    <attr name="textColor" format="color"></attr></declare-styleable>

完事,自定义View——圆环进度条就这样完成了。
总结:自定义view步骤:
1、继承View
2、重写onMeasure和onDraw方法。
3、在调用三个参数构造器,在里面做初始化自定义属性,前提需在attrs xml文件下创建自定义属性。并实例化Paint
4、在onDraw方法里开始你的画画,一大堆数学问题等着你,就是算。
5、设置你的属性的get和set方法,然后再set方法里 invalidate();,好的自定义View就这样完成了。

建议:有些系统类可能大家不是很清楚,可以上网百度,或者直接进入源码,看看源码是怎么讲的,用多了就熟了。

以上如有不恰当之处,评论可给予提出。