日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义View之HenCoder学习笔记

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义View之HenCoder学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文是學習公眾號 hencoder 中的自定義View部分的學習筆記。

1-1 onDraw()和Paint詳解

具體參考http://hencoder.com/ui-1-1/ 寫的非常詳細

練習:畫弧形,扇形,心形,直方圖,餅圖

1-1-1.弧形 扇形 使用 canvas.drawArc()

drawArc() 是使用一個橢圓來描述弧形的。left, top, right, bottom 描述的是這個弧形所在的橢圓;startAngle 是弧形的起始角度(x 軸的正向,即正右的方向,是 0 度的位置;順時針為正角度,逆時針為負角度),sweepAngle 是弧形劃過的角度;useCenter 表示是否連接到圓心,如果不連接到圓心,就是弧形,如果連接到圓心,就是扇形。

Paint paint = new Paint();paint.setStyle(Paint.Style.FILL); // 填充模式 // canvas.drawOval(200, 100, 800, 500,paint);canvas.drawArc(200, 100, 800, 500, -110, 100, true, paint); // 繪制扇形canvas.drawArc(200, 100, 800, 500, 20, 140, false, paint); // 繪制弧形paint.setStyle(Paint.Style.STROKE); // 畫線模式canvas.drawArc(200, 100, 800, 500, 180, 60, false, paint); // 繪制不封口的弧形

1-1-2 心形

使用drawPath(Path path, Paint paint)
Path類中的各種方法Hencoder已經寫的非常清楚

Paint paint = new Paint();paint.setAntiAlias(true);paint.setColor(Color.RED);paint.setStrokeWidth(10);paint.setStyle(Paint.Style.STROKE);Path path = new Path();//畫圓弧,圓弧的最左側距離y軸距離200 最上距離x軸距離200,//最下距離x軸400 最右距離y軸400// 開始弧度-225 弧形掃過的角度225path.addArc(200, 200, 400, 400, -225, 225);//畫圓弧,圓弧的最左側距離y軸距離400 最上距離x軸距離200,//最下距離x軸400 最右距離y軸600 //開始弧度-180 弧形掃過的角度225 保留移動痕跡path.arcTo(400, 200, 600, 400, -180, 225, false);path.lineTo(400, 542);//從當前位置畫線到(400,542)path.close();//閉合圖形canvas.drawPath(path,paint); 圖片.png

該圖是對這句代碼的解釋,剩下的幾句代碼的解釋注釋中都已寫的很清楚。

//畫圓弧,圓弧的最左側距離y軸距離200 最上距離x軸距離200,// 最下距離x軸400 最右距離y軸400 開始弧度-225 弧形掃過的角度225path.addArc(200, 200, 400, 400, -225, 225);

1-1-3 畫直方圖

確定好坐標后,畫坐標系,文字,矩形,如下圖所示


圖片.png Paint paint = new Paint();//繪制坐標系paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(2);paint.setColor(Color.WHITE);Path path = new Path();path.moveTo(150,100);//移動起點到(150,100)path.lineTo(150,500);//從(150,100)開始畫線,畫到(150,150)處path.lineTo(900,500);canvas.drawPath(path,paint);//繪制文字paint.setTextSize(22);paint.setStyle(Paint.Style.FILL);paint.setStrokeWidth(1);canvas.drawText("Froyo",200,520,paint);canvas.drawText("GB",315,520,paint);canvas.drawText("ICS",415,520,paint);canvas.drawText("JB",515,520,paint);canvas.drawText("KitKat",605,520,paint);canvas.drawText("L",725,520,paint);canvas.drawText("M",825,520,paint);//繪制長方形paint.setColor(getResources().getColor(R.color.green_light));paint.setStyle(Paint.Style.FILL);canvas.drawRect(190,495,270,500,paint);canvas.drawRect(290,485,370,500,paint);canvas.drawRect(390,485,470,500,paint);canvas.drawRect(490,350,570,500,paint);canvas.drawRect(590,250,670,500,paint);canvas.drawRect(690,180,770,500,paint);canvas.drawRect(790,370,870,500,paint);

1-1-4 繪制餅圖

1.繪制扇形
分析如下圖所示


餅圖分析.png

此處使用的是canvas的drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 其中各參數的作用:left, top, right, bottom 描述的是這個弧形所在的橢圓;startAngle 是弧形的起始角度(x 軸的正向,即正右的方向,是 0 度的位置;順時針為正角度,逆時針為負角度),sweepAngle 是弧形劃過的角度;useCenter 表示是否連接到圓心,如果不連接到圓心,就是弧形,如果連接到圓心,就是扇形。

注意要計算好角度Paint paint = new Paint();Path path = new Path();//紅色區(qū)域paint.setColor(getResources().getColor(R.color.red_light));canvas.drawArc(200,150,558,500,-180,125,true,paint);//圓心(385,325) 直徑350//黃色區(qū)域paint.setColor(getResources().getColor(R.color.yellow_light));//left, top, right, bottom 描述的是這個弧形所在的橢圓;startAngle 是弧形的起始角度//sweepAngle 是弧形劃過的角度;useCenter 表示是否連接到圓心canvas.drawArc(210,157,568,507,-55,55,true,paint);//紫色區(qū)域paint.setColor(getResources().getColor(R.color.purple_light));canvas.drawArc(210,157,568,507,3,8,true,paint);//灰色區(qū)域paint.setColor(getResources().getColor(R.color.grey_light));canvas.drawArc(210,157,568,507,13,7,true,paint);//青色區(qū)域paint.setColor(getResources().getColor(R.color.cyan_light));canvas.drawArc(210,157,568,507,22,55,true,paint);//藍色區(qū)域paint.setColor(getResources().getColor(R.color.blue_light));canvas.drawArc(210,157,568,507,79,98,true,paint);

2.繪制白色的指示線
白色指示線的終點在每個弧形中點的位置,計算出每個白線中點。

//畫線paint.setColor(Color.WHITE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(1);path.moveTo(170,180);path.lineTo(240,180);path.lineTo(250,200);canvas.drawPath(path,paint);//第二條線 (385,325)圓心path.moveTo(680,250);path.lineTo(580,250);path.lineTo(550,270);canvas.drawPath(path,paint);//第三條線path.moveTo(680,370);path.lineTo(640,370);path.lineTo(620,350);path.lineTo(565,350);canvas.drawPath(path,paint);//第四條線path.moveTo(680,400);path.lineTo(640,400);path.lineTo(620,380);path.lineTo(563,380);canvas.drawPath(path,paint);//第五條線path.moveTo(600,470);path.lineTo(550,470);path.lineTo(520,450);canvas.drawPath(path,paint);//第六條線path.moveTo(170,470);path.lineTo(240,470);path.lineTo(250,450);canvas.drawPath(path,paint);//繪制文字paint.setStyle(Paint.Style.FILL);paint.setTextSize(20);canvas.drawText("Lollipop",90,185,paint);canvas.drawText("Marshmallow",690,255,paint);canvas.drawText("Gingerbread",690,375,paint);canvas.drawText("Ice Cream Sandwich",690,405,paint);canvas.drawText("Jelly Bean",610,475,paint);canvas.drawText("KitKat",100,475,paint);

1-2 Paint 詳解

具體參考:http://hencoder.com/ui-1-2/ 寫的十分詳細

1-3 drawText() 文字的繪制

具體參考:http://hencoder.com/ui-1-3/ 也是寫的十分詳細

1-4 Canvas 對繪制的輔助 clipXXX() 和 Matrix

具體參考: http://hencoder.com/ui-1-4/ 知識點寫的十分詳細

1-4-1 clipXXX()方法 裁切方法

1) clipRect() 在矩形范圍內裁切

//加上save和restore 恢復到裁切之前的狀態(tài) 不然后面都會裁切掉canvas.save();canvas.clipRect(left,top, left+300,top+200);canvas.drawBitmap(bitmap, left, top, paint);canvas.restore();
  • clipPath() 根據Path形狀裁切
  • // 第一種: 1.畫出path 圓path1.addCircle(point1.x + 200,point1.y + 200,150, Path.Direction.CW);//2.根據path裁切canvas.save();canvas.clipPath(path1);canvas.drawBitmap(bitmap, point1.x, point1.y, paint);canvas.restore();//第二種:/*** FillType 有四個值:* 1.EVEN_ODD: Specifies that "inside" is computed by an odd number of edge crossings.* 2.INVERSE_EVEN_ODD:Same as EVEN_ODD, but draws outside of the path, rather than inside.* 3.WINDING:Specifies that "inside" is computed by a non-zero sum of signed edge crossings.* 4.INVERSE_WINDING:Same as WINDING, but draws outside of the path, rather than inside.*/path2.setFillType(Path.FillType.INVERSE_WINDING);path2.addCircle(point2.x+ 200,point2.y + 200,150, Path.Direction.CCW);canvas.save();canvas.clipPath(path2);canvas.drawBitmap(bitmap, point2.x, point2.y, paint);canvas.restore();

    上面Path的FillType,詳細解釋可見:
    http://android.jobbole.com/83427/

    1-4-2 幾何變換

    幾何變換的使用大概分為三類:
    1. 使用 Canvas 來做常見的二維變換;
    2.使用 Matrix 來做常見和不常見的二維變換;
    3.使用 Camera 來做三維變換。

    1) 使用 Canvas 來做常見的二維變換:
    注意:1.canvas的幾何變換可以疊加使用,但是疊加時,要倒著寫,需要先實現的效果寫在后面
    2.在做幾何變換之前,需要使用save保存狀態(tài),做之后使用restore恢復狀態(tài)
    1.1 Canvas.translate(float dx, float dy) 平移

    canvas.save();//向右移動200canvas.translate(200,0);canvas.drawBitmap(bitmap, point1.x, point1.y, paint);canvas.restore();canvas.save();//向左移動100canvas.translate(-100,0);canvas.drawBitmap(bitmap, point2.x, point2.y, paint);canvas.restore();

    1.2 旋轉Canvas.rotate(float degrees, float px, float py)

    canvas.save();//如果想要兩個效果疊加使用 需要倒著寫,比如說想要先旋轉再移動 需要把移動寫在旋轉之前canvas.rotate(45,point1.x + bitmapWidth/2,point1.y+ bitmapHeight/2);canvas.translate(200,100);//先移動 再繪制 先旋轉 再繪制canvas.drawBitmap(bitmap, point1.x, point1.y, paint);canvas.restore();

    1.3 縮放 Canvas.scale(float sx, float sy, float px, float py)

    canvas.save();//參數里的 sx sy 是橫向和縱向的放縮倍數; px py 是放縮的軸心。canvas.scale(1.3f,1.3f,point1.x + bitmapWidth/2 ,point1.y + bitmapHeight/2);canvas.drawBitmap(bitmap, point1.x, point1.y, paint);canvas.restore();

    1.4 skew(float sx, float sy) 錯切

    //參數里的 sx 和 sy 是 x 方向和 y 方向的錯切系數。canvas.save();canvas.skew(0, 0.5f);canvas.drawBitmap(bitmap, point1.x, point1.y, paint);canvas.restore();
  • 使用 Matrix 來做變換
    2.1 使用 Matrix 來做常見變換
    Matrix 做常見變換的方式:
    1.創(chuàng)建 Matrix 對象;
    2.調用 Matrix 的 pre/postTranslate/Rotate/Scale/Skew() 方法來設置幾何變換,Matrix做幾何變換時,可以自己設定順序,pre是插入在某個效果之前,post是在某個效果之后。;
    3.使用 Canvas.setMatrix(matrix) 或 Canvas.concat(matrix) 來把幾何變換應用到 Canvas。
  • 1)平移

    canvas.save();matrix.reset();matrix.postTranslate(-100, -100);canvas.concat(matrix);canvas.drawBitmap(bitmap, point1.x, point1.y, paint);canvas.restore();canvas.save();matrix.reset();matrix.postTranslate(200, 0);canvas.concat(matrix);canvas.drawBitmap(bitmap, point2.x, point2.y, paint);canvas.restore();
  • 縮放
  • 把 Matrix 應用到 Canvas 有兩個方法: Canvas.setMatrix(matrix) 和 Canvas.concat(matrix)。
    1.Canvas.setMatrix(matrix):用 Matrix 直接替換 Canvas 當前的變換矩陣,即拋棄 Canvas 當前的變換,改用 Matrix 的變換(注:根據下面評論里以及我在微信公眾號中收到的反饋,不同的系統(tǒng)中 setMatrix(matrix) 的行為可能不一致,所以還是盡量用 concat(matrix) 吧);
    2.Canvas.concat(matrix):用 Canvas 當前的變換矩陣和 Matrix 相乘,即基于 Canvas 當前的變換,疊加上 Matrix 中的變換。

    總結

    以上是生活随笔為你收集整理的自定义View之HenCoder学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。