zoukankan      html  css  js  c++  java
  • 3.View自定义布局canvas画布知识

    一、基础知识

    1.Canvas画布

    2.Paint画笔

    3.Canvas的常用方法:drawArc(画圆弧)、drawCircle(画圆)、drawLine(画线)

    二、常用方法的讲解

    1.drawArc(RectF,starrtAngle,sweepAngle,useCenter,paint)

    我们通常使用该方法画圆弧,第一参数RectF表示我们绘画的区域(范围),第二个参数是圆弧开始的度数(这里度数表示与上课讲的不一样,课堂讲的角度是从x轴逆时针方向开始,而这里是逆时针算,所以90度是6点钟),第三个参数是扫过的角度,第四参数是否居中,第五个参数是画笔。

    2.drawCircle(cx,cy,radius,paint)

    我们通常使用该方法画圆,第一、二表示圆心的坐标,坐标原点是手机屏幕的左上角,屏幕上的位置都是正数,与我们平时在课堂讲的不一样,第三个参数是半径,第四个参数是画笔

    3.drawLine(startX,startY,stopX,stopY,paint)

    我们通常使用该方法画线条,课堂上我们都学过两点确定一条直线,所以确定两个点就可以画一条直线了。第一、二个参数表示第一个点的参数,第三、四表示第二个点的参数。

    4.DectF(left,top,right,bottom)

    我们通常使用该方法定义一片区域,left表是与屏幕左边的距离,top表示与屏幕上边的距离,right表示与屏幕左边的距离,bottom表示与屏幕顶部距离,都是以顶部或左边为基准。

    三、使用案例

    画这样的一个图形有点复杂,但找对方法就很容易。

    看到这样的一个图形,先分析(这个很重要),要怎么画这个图形,下面可以这样想:

    1.最外面的线条,你可以看成是一个圆弧只不过这个圆弧比较窄(窄成线了)

    2.而时刻就是线条drawLine就可以,只不过要用到旋转布局,这个后面会讲到。

    3.里面的圆环也是一个扇形drawArc

    4.指针是drawLine

    5.里面的圆可以drawArc或drawCircle都可以,drawCircle比较方便

    注:定义画笔的宽度pain.setStockWidth(表示画笔粗细,到时定义扇形的宽也是通过这个方法来设置的)

    先把代码补上,来日再讲解

    /**
    * 时表
    */
    public class PanelView extends View {
    private int width;
    private int height;
    private int percent = 50;
    private int scendArcWidth;//第二个弧的宽度
    private int minCircleRadius;//最小圆的半径
    private int rectWidth;//文字矩形的宽
    private String text;//文字内容
    private int textSize;//文字的大小
    private int textColor;//文字颜色
    private int arcColor = Color.WHITE;//
    private int minCircleColor = Color.WHITE;//小圆和指针颜色
    private int tikeCount = 13;//刻度的个数
    private int tikeWidth = 3;//刻度的长度
    private Context context;

    public PanelView(Context context) {
    super(context);
    }

    public PanelView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init(context,attrs);
    }

    public PanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context,attrs);
    }

    public PanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init(context,attrs);
    }

    private void init(Context context,AttributeSet attributeSet){
    TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.PanelView);
    arcColor = typedArray.getColor(R.styleable.PanelView_arcColor,
    Color.parseColor("#5FB1ED"));
    minCircleColor = typedArray.getColor(R.styleable.PanelView_minCircleColor,
    Color.parseColor("#5FB1ED"));
    tikeCount = typedArray.getInt(R.styleable.PanelView_tikeCount,0);
    textSize = typedArray.getDimensionPixelSize(R.styleable.PanelView_textSize,0);
    text = typedArray.getString(R.styleable.PanelView_android_text);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    if(widthMode == MeasureSpec.EXACTLY){
    width = widthSize;
    }
    if(heightMode == MeasureSpec.EXACTLY){
    height = heightSize;
    }
    setMeasuredDimension(width,height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
    Paint p = new Paint();
    int strokeWidth = 10;
    p.setStrokeWidth(strokeWidth);
    p.setAntiAlias(true);
    p.setStyle(Paint.Style.STROKE);
    p.setColor(arcColor);
    //最外面线条
    canvas.drawArc(new RectF(strokeWidth,strokeWidth,width - strokeWidth,height - strokeWidth),
    145,250,false,p);
    strokeWidth = 50;
    p.setStrokeWidth(strokeWidth);
    //里面的第二个圆弧
    RectF secondRectF = new RectF(strokeWidth + 50,strokeWidth + 50,
    width - strokeWidth - 50,height - strokeWidth - 50);
    float percent = this.percent / 100f;

    //充满的圆弧的度数 -5是大小弧的偏差
    float fill = 250 * percent;

    //空的圆弧的度数
    float empty = 250 - fill;

    if(percent == 0) {
    p.setColor(Color.WHITE);
    }

    //弧1
    canvas.drawArc(secondRectF,135,11,false,p);
    //弧2
    canvas.drawArc(secondRectF, 145, fill, false, p);
    p.setColor(Color.WHITE);
    //弧3
    canvas.drawArc(secondRectF,145 + fill, empty,false,p);
    if(percent == 1) p.setColor(arcColor);
    //弧4
    canvas.drawArc(secondRectF,144+fill+empty,10,false,p);

    //绘制小圆外圆
    p.setColor(arcColor);
    p.setStrokeWidth(3);
    canvas.drawCircle(width / 2, height / 2, 30,p);

    //绘制内圆
    p.setColor(minCircleColor);
    p.setStrokeWidth(8);
    minCircleRadius = 15;
    canvas.drawCircle(width / 2,height / 2,minCircleRadius,p);

    //绘制刻度旋转画布
    p.setColor(arcColor);
    //绘制第一条最上面的刻度
    tikeWidth = 30;
    p.setStrokeWidth(6);
    canvas.drawLine(width/2,6,width/2,tikeWidth,p);
    tikeCount = 13;
    float angle = 250f/tikeCount;
    //通过旋转画布 绘制右面的刻度
    for(int i = 0;i < tikeCount/2;i++) {
    canvas.rotate(angle,width/2,height/2);
    canvas.drawLine(width/2,6,width/2,tikeWidth,p);
    }
    canvas.rotate(-angle * tikeCount/2,width / 2, height / 2);
    for(int i = 0;i < tikeCount/2;i++){
    canvas.rotate(-angle,width/2,height/2);
    canvas.drawLine(width/2,6,width/2,tikeWidth,p);
    }
    canvas.rotate(angle * tikeCount/2,width / 2, height / 2);

    //绘制指针
    p.setColor(minCircleColor);
    p.setStrokeWidth(4);

    //按照百分比绘制刻度
    canvas.rotate((250 * this.percent - 250/2),width / 2,height / 2);
    canvas.drawLine(width / 2,
    strokeWidth + 50 + strokeWidth/2,
    width / 2, height / 2 - minCircleRadius, p);
    //将画布旋转回来
    canvas.rotate(-(250 * percent - 250/2),width/2,height/2);
    super.onDraw(canvas);
    }
    }
  • 相关阅读:
    转 进程与线程的区别与联系
    DoEvents的应用及注意事项
    转:error LNK2001 错误
    基于UDP的简单的聊天程序
    VB提示:文件未找到:'c:\windows\sytem32\ieframe.dll\1'的解决方法
    VB PopupMenu方法
    转 vb中SetWindowsHookEx详细用法及举例
    Python批量转换txt文件为excel文件
    excel自动筛选后分别复制粘贴到新文件的解决办法
    文本编辑
  • 原文地址:https://www.cnblogs.com/riyueqian/p/14698837.html
Copyright © 2011-2022 走看看