自定义View

自定义View

自定义属性

  1. values 下建立attrs.xml文件


    //声明的自定义属性集合
        
        
        
        
        
    

  1. 在View的构造方法中获取 :尺寸得到的是px值整数值(四舍五入后的)
   public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        if (attrs != null) {
//            TypedArray 这种数据结构 存储了我们在xml中获取的值
//            从context通过获得    R.styleable.MyButton是我们定义的属性集合
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyButton);
//         获取键值:自定义Styleable的名字然后下划线属性
            background = typedArray.getDrawable(R.styleable.MyButton_background);
            textSize =  typedArray.getDimension(R.styleable.MyButton_textSize, 0);
            title = typedArray.getString(R.styleable.MyButton_title);
            fraction = typedArray.getFraction(R.styleable.MyButton_fraction, 0, 0, 0);
             typedArray.recycle(); //记得回收
        }
    }
  1. 关与OnMeasure :从MeasureSpec中获得测量模式,然后根据测量模式根据自己的需求设置宽高(得到的都是px) 设置宽高的函数是setMeasureDimension();


 

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        widthSize = MeasureSpec.getSize(widthMeasureSpec);
        heightSize = MeasureSpec.getSize(heightMeasureSpec);

        switch (widthMode) {
            case MeasureSpec.AT_MOST:
                break;
            case MeasureSpec.EXACTLY:
                widthSize = UiUtils.dip2px(mContext, 50);
                break;
            case MeasureSpec.UNSPECIFIED:
                break;
        }
        setMeasuredDimension(widthSize, heightSize);
    }

onDraw() 方法

画文字
- canvas.drawText("你好,中国!",100,60,mPaint);//以View的左上点为原点为,X轴向右为正,Y轴像下为正建立坐标系 (100,60) 指的是文字的左下角点的坐标
- canvas.drawText("你好,中国!",2,4,80,60,mPaint);//文字的开始坐标,结束坐标,以及左下角的坐标
- canvas.drawTextOnPath("1234567897545985445",path,0,0,mPaint);
参数 路径 ,距离路径开始点 x,y轴偏移量
画圆
canvas.drawCircle(100,100,30,mPaint); 以View的左上点为原点为,X轴向右为正,Y轴像下为正建立坐标系 (100,100) 指的是圆心坐标,30指的是半径
画线
canvas.drawLine(20,50,40,90,mPaint);//开始点坐标(20,50),结束点坐标(40,90) 
canvas.drawLines(new float[]{100,100,200,200,200,100,300,100}, p);
同时绘制多条线。 参数1:float数组:每四个一组为一条线。
        画虚线要用path画
        Path path = new Path();
        path.moveTo(0, 0);
        path.lineTo(500, 500);
        mPaint.setPathEffect(new DashPathEffect(new float[]{10, 15, 20, 25}, 0));
        canvas.drawPath(path, mPaint);
画矩形
RectF rectF = new RectF(0, 10, 400, 480); 前两个参数是左上角的坐标,后两个参数是右下角的坐标
Rect 的参数为int ,RectF的参数为float,RectF的精度更高一些,他们都是通过四个坐标参数来确定一个矩形的区域
RectF(float left,float top,fLoat right,float bottom)构造一个指定了4个参数的矩形.
RectF rectF = new RectF(0, 10, 400, 480);
canvas.drawRect(rectF,mPaint);

 //画圆角矩形  20,20为在X和Y轴上的半径 一般相等就好
    canvas.drawRoundRect(rectF,20,20,mPaint);
画椭圆
    RectF rectF = new RectF(0, 10, 400, 480);
    canvas.drawOval(rectF,mPaint);
   

画弧度

 RectF rectF = new RectF(0, 10, 400, 480); //先创建一个矩形,扇形与其相切,中心为矩形的中心点
20 初始角度 水平向右为0度,逆时针为正 
720 扫过的角度 
true 是否和中心点相连,true画出一个扇形 false 画出一个直线与圆弧相组成的图形
canvas.drawArc(rectF,20,60,true,mPaint);

多边形

用 Path来画
 path.addCircle(100,100,50, Path.Direction.CW);为 Path 中新增一个圆之后,调用 canvas.drawPath(path, paint) ,就能画一个圆出来。最后一个参数 dir 是画圆的路径的方向。路径方向有两种:顺时针 (CW clockwise) 和逆时针 (CCW counter-clockwise) 。对于普通情况,这个参数填 CW 还是填 CCW 没有影响。它只是在需要填充图形 (Paint.Style 为 FILL 或  FILL_AND_STROKE) ,并且图形出现自相交时,用于判断填充范围的。
  path.lineTo(100, 100); //参数是绝对坐标
  path.rLineTo(30,40);//参数是相对当前位置的相对坐标 (前缀 r 指的就是  relatively 「相对地」)。当前位置:所谓当前位置,即最后一次调用画 Path 的方法的终点位置。初始值为原点 (0, 0)
  path.arcTo(100, 100, 300, 300, -90, 90, false); 
  path.arcTo() 只用来画弧形而不画扇形,所以不再需要 useCenter 参数;而多出来的这个 forceMoveTo 参数的意思是,绘制是要「抬一下笔移动过去」,还是「直接拖着笔过去」,区别在于是否留下移动的痕迹。是否与之前连线
 path.addArc() 只是一个直接使用了 forceMoveTo = true 的简化版 arcTo() ;
  
  path.setFillType(Path.FillType.WINDING);//两个相交的圆设置全填充
  path.setFillType(Path.FillType.EVEN_ODD);//两圆相交不填充 两圆其余部分填充
   even-odd rule (奇偶原则):对于平面中的任意一点,向任意方向射出一条射线,这条射线和图形相交的次数(相交才算,相切不算哦)如果是奇数,则这个点被认为在图形内部,是要被涂色的区域;如果是偶数,则这个点被认为在图形外部,是不被涂色的区域。还以左右相交的双圆为例
   
   non-zero winding rule (非零环绕数原则):首先,它需要你图形中的所有线条都是有绘制方向的:同样是从平面中的点向任意方向射出一条射线,但计算规则不一样:以 0 为初始值,对于射线和图形的所有交点,遇到每个顺时针的交点(图形从射线的左边向右穿过)把结果加 1,遇到每个逆时针的交点(图形从射线的右边向左穿过)把结果减 1,最终把所有的交点都算上,得到的结果如果不是 0,则认为这个点在图形内部,是要被涂色的区域;如果是 0,则认为这个点在图形外部,是不被涂色的区域。
  

画点

canvas.drawPoint(60, 390, p);//画一个点  
canvas.drawPoints(new float[]{60,400,65,400,70,400}, p);//画多个点

画图片

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_arrow);
        RectF rectF = new RectF(0, 0, 80, 80);
        //第一个Rect为矩形的图片的显示大小,若为null,则显示整个大小
        //第二个Rect为矩形的显示区域
        canvas.drawBitmap(bitmap,null,rectF,mPaint);
        
        canvas.drawBitmap(bitmap,0,20,mpaint); //0,20图片左上角的坐标

drawColor()

类似的方法还有 drawRGB(int r, int g, int b) 和 drawARGB(int a, int r, int g, int b) ,它们和 drawColor(color) 只是使用方式不同,作用都是一样的
这类颜色填充方法一般用于在绘制之前设置底色,或者在绘制之后为界面设置半透明蒙版。

canvas

canvas .translate(100,50) //画布向X轴方向移动100,Y轴方向移动50
canvas.scale(2, 4);//画布x轴放大2倍,Y轴放大四倍 默认原点为左上角
canvas.scale(2, 4,100,100); 100,100为自定义的原点坐标
canvas.rotate(30);//左上角为中心点 顺时针为正
canvas.rotate(30,100,100); 以(100,100)为中心,旋转30度,顺时针方向为正方向 
Canvas保存和还原

Canvas提供了几个方法,让我们可以方便的对Canvas的状态进行更改和还原。
这些方法是:save()、restore()、restoreToCount(int saveCount)。

我们在对Canvas进行平移、旋转、放大等操作时候,可以调用save()方法,将当前修改过的Canvas状态进行保存,调用restore() 方法后,会将Canvas还原成最近的一个save() 的状态。

save()方法还会有一个返回值,我们也可以调用restoreToCount(int saveCount)方法,将这个返回值作为参数传递进去,就可以将Canvas还原成某一个特定的save()状态。

关于Paint

   setAntiAlias();            //设置画笔的锯齿效果

  setColor();                 //设置画笔的颜色

  setARGB();                 //设置画笔的A、R、G、B值

  setAlpha();                 //设置画笔的Alpha值

  setTextSize();             //设置字体的尺寸

   setDither(true);           //设置防抖动
   
   setStrokeWidth(float width) 设置线条宽度
   
   
  setStyle();                  //设置画笔的风格(空心或实心)
   - Paint.Style.FILL:填充内部
   - Paint.Style.FILL_AND_STROKE  :填充内部和描边
   - Paint.Style.STROKE  :描边

   setStrokeCap( Paint.Cap.BUTT );       // 线帽,即画的线条两端是否带有圆角,butt,无圆角
   
  setStrokeWidth();        //设置空心边框的宽度 画笔的线宽

  getColor();                  //获取画笔的颜色

获取res下面的文字和颜色

      String string = mContext.getString(R.string.app_name);
        int color = mContext.getResources().getColor(R.color.colorAccent);

你可能感兴趣的:(自定义View)