美文网首页
自定义View(一)

自定义View(一)

作者: windfall_ | 来源:发表于2016-11-16 22:20 被阅读0次
  • 添加attr.xml,并在构造器中使用
public ProgressBarView(Context context, AttributeSet attrs) {
        super(context,attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.progressbar);
        paintBold = typedArray.getDimensionPixelSize(R.styleable.progressbar_paintBold,10);
        linelengeth = typedArray.getDimensionPixelSize(R.styleable.progressbar_linelength,25);
        linenumber = typedArray.getInteger(R.styleable.progressbar_linenumber,20);
        backgroundColor = typedArray.getColor(R.styleable.progressbar_backgroundColor, Color.GRAY);
        beforeColor = typedArray.getColor(R.styleable.progressbar_beforeColor,Color.YELLOW);
        textColor = typedArray.getColor(R.styleable.progressbar_textColor,Color.BLACK);
        max = typedArray.getInteger(R.styleable.progressbar_max,100);
    //回收对象
        typedArray.recycle();
    }
  • 初始化Paint
    
        backgroundPaint = new Paint();
        backgroundPaint.setColor(backgroundColor);
        backgroundPaint.setStrokeWidth(paintBold);
//        设置结合处样式,Round为圆弧,Miter为锐角,Bevel为直线
        backgroundPaint.setStrokeJoin(Paint.Join.ROUND);
//        设置笔刷样式
        backgroundPaint.setStrokeCap(Paint.Cap.ROUND);
//        抗锯齿
        backgroundPaint.setAntiAlias(true);
  • 重写onMeasure
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        width = getSize(100,widthMeasureSpec);
        height = getSize(100,heightMeasureSpec);

    }

    public int getSize(int defaultSize,int measureSpec){
        int size = defaultSize;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        switch (specMode){
            case MeasureSpec.UNSPECIFIED:
                size = defaultSize;
                break;
            case MeasureSpec.AT_MOST:
                size = specSize;
                break;
            case MeasureSpec.EXACTLY:
                size = specSize;
                break;
        }
        return size;
    }
  • 重写onDraw
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int x = width/2;
        int y = height/2;
        int r = x-5;
        for (int i = 0;i<linenumber;i++){
            canvas.drawLine(x,y-r,x,y-r+linelengeth,backgroundPaint);
            canvas.rotate(360/linenumber,x,y);
        }
        int count = getProgress()*linenumber/max;
        canvas.drawText(getProgress()*100/max+"%",x,y,textPaint);
        for (;count>0;count--){
            canvas.drawLine(x,y-r,x,y-r+linelengeth,beforePaint);
            canvas.rotate(360/linenumber,x,y);
        }
   } 
  • 调用invalidate()或postInvalidateDelayed()进行页面重绘,重绘时只调用onDraw方法,postInvalidateDelayed()方法传入时间,即一定时间后重绘view。
  • canvas的save和restore方法:
    • save方法保存当前canvas的状态
    • restore恢复save方法保存的状态,比如在canvas旋转之前调用save方法保存canvas状态,旋转后调用restore方法状态恢复到save方法保存的状态,即不用在反向旋转canvas,类似于图层的概念。save把画布状态放进状态栈中,restore返回栈中最顶层的状态栈画布。
  • 当需要重绘的只是一个view里的一小部分,并不需要重绘其他部分,如钟表只用重绘指针并不用重绘表盘,可考虑建立两个view一个为表盘,一个是指针,然后用FrameLayout把两个view组合起来,重绘的时候只用重绘指针部分,个人觉得会提高性能。
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int x = ClockView.getCirleX()/2;
        int y = ClockView.getCirleY()/2;

        int r= x-5;
        initTime();
        if (hour>12) hour = hour-12;
        hourDegree = hour*30+minute/2;
        minDegree = minute*6+second/10;
        secDegree = second*6;

        canvas.save();
        canvas.rotate(secDegree,x,y);
        canvas.drawLine(x,y-r+scalelength,x,y,secondPaint);

        canvas.restore();
        canvas.save();
        canvas.rotate(minDegree,x,y);
        canvas.drawLine(x,y-r+scalelength*4,x,y,minPaint);
        canvas.restore();


        canvas.rotate(hourDegree,x,y);
        canvas.drawLine(x,y-r+scalelength*6,x,y,hourPaint);
        postInvalidateDelayed(1000);
    }

Demo地址https://github.com/liuchangjiang0119/CustomView

相关文章

  • 自定义View5---完整的自定义View

    移步自定义View系列 1.自定义view的分类自定义单一view(不含子view)继承view继承特定view如...

  • Android View(转)

    自定义View的原理自定义View基础 - 最易懂的自定义View原理系列自定义View Measure过程 - ...

  • 自定义View系列

    自定义View1---知识储备自定义View2---View Measure过程自定义View3---View L...

  • 自定义View

    自定义View系列文章 自定义View view向上滚动

  • 自定义View(一) 自定义View的概述

    不怕跌倒,所以飞翔 自定义View概述 1.自定义View分类 自定义View 直接继承View主要是绘制 自定义...

  • Android自定义View

    Android自定义View 参考:从此再有不愁自定义View——Android自定义view详解android ...

  • 通过圆形载入View了解自定义View

    这是自定义View的第一篇文章,通过制作简单的自定义View来了解自定义View的流程。自定义View是Andro...

  • 自定义view

    Android自定义View 为什么要自定义View自定义View的基本方法 自定义View的最基本的三个方法分别...

  • 自定义View理论

    自定义View类型 1. 自定义View 在没有现成的View,需要自己实现的时候,就使用自定义View,一般继承...

  • Android 之 自定义View全解

    本文主要有以下内容: 自定义View的分类 自定义View的注意事项 自定义View的不同实现 自定义View使其...

网友评论

      本文标题:自定义View(一)

      本文链接:https://www.haomeiwen.com/subject/pvorpttx.html