自定义控件基础知识--Canvas
来源:互联网 发布:知乎 日本研究生申请 编辑:程序博客网 时间:2024/06/15 20:28
Canvas(一)
一、今天我们就先通过下面两方面去了解
- Canvas是什么,能干什么?
- Canvasn怎么用
二、是什么?
Canvas时android图像处理最常用的一个类了,通俗的说叫画布,主要负责android中View的绘制工作,Canvas的获取方法有两种,一种时候通过View的onDraw(Canvas canvas)方法的参数中直接拿来使用,另一种则是直接new出来:
//第一种方式使用参数中的canvas@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //第二种方式(其中之一) Bitmap bitmap = Bitmap.createBitmap(101,101, Bitmap.Config.RGB_565); Canvas _canvas = new Canvas(bitmap);}
三、那么接下来我们看下Canvas各个方法的具体使用
1、设置画布背景颜色
canvas.drawColor(int color);
2、一个画圆的方法canvas.drawCircle();
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //设置画笔 mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(8); //获取控件宽高 int height = getMeasuredHeight(); int width = getMeasuredWidth(); //计算圆的半径,对宽高进行判断,防止圆不完整 int radius = height > width ? width / 2 - 10 : height / 2 - 10; /** * 参数1:圆心的x坐标 * 参数2:圆心的Y坐标 * 参数3:圆的半径 * 参数4:画笔 * ps:坐标都是以控件的左上角为基准 */ canvas.drawCircle(width / 2, height / 2,radius,mPaint);}
3、接下来是画文字的canvas.drawText(...)这个方法是有多个重载方法的,下面就不一一介绍(原因往下看),介绍一个跟path有关的,因为这个比较炫一点
- canvas.drawTextOnPath(...),看代码跟效果图,其实就是用Path控制文字的绘制路径
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); String str = "琛琛、仙仙、旺旺、基基几个二货!"; //创建画文字专用画笔 TextPaint paint = new TextPaint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); paint.setTextSize(48); /** * path的使用等后面深入点研究再单独记录 */ Path path = new Path(); path.rLineTo(0,300); path.rLineTo(100,50); path.rLineTo(200,300); path.rLineTo(200,300); /** * 参数1:将要绘制的文字 * 参数2:文字绘制轨迹 * 参数3:x轴偏移量(没搞懂) * 参数4:y轴偏移量(也没搞懂) * 参数5:画笔 */ canvas.drawTextOnPath(str,path,0,0,paint); }
4、其实上面不说canvas.drawText(...)是有原因的,因为我刚开始也兴冲冲的写了一大堆那个方法去画文字,结果发现,字数多了之后就懵逼了,换不了行,所以感觉没卵用,如果是画那种很少字,并比较固定的倒是可以考虑用下,找了下资料看,发现很多人都用StaticLayout来实现,查了下看TextView其实也是用这个实现的,下面简单的实现下看看!
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); String str = "琛琛、仙仙、旺旺、基基几个二货!一个带坏了一班人,一个约了几十次妹子吃饭手都没得拖,一个菊花黑完,最后一个就不说了,肥猪肉都不放过!"; //创建画文字专用画笔 TextPaint paint = new TextPaint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); paint.setTextSize(48); /** * 参数1:要画的文字 * 参数2:画笔 * 参数3:画多宽后换行(这个值理应用控件的宽跟padding等值进行计算,dome中偷懒写死了) * 参数4:文字对其方式 * 参数5:试了下,应该是行高 * 参数6:试了下,应该是行间距 * 参数7:这个真没搞懂,以后知道了再说吧(尴尬) */ StaticLayout layout = new StaticLayout(str,paint,300, Layout.Alignment.ALIGN_CENTER,1.0F,10.0F,true); layout.draw(canvas); }
5、使用canvas画线条,canvas.drawLine(...);这是画单条线条的,还有一个一次画多条线条的,canvas.drawLines(...),看事例:
- canvas.drawLine(...),画线其实很好理解,两个点就能定义一条线,所以找到两个点,跟一支笔,加上画布(canvas)就妥妥的了
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //创建画笔(手续详细记录paint的使用) Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10.0f); paint.setAntiAlias(true); /** * 参数1:起点的x坐标 * 参数2:起点的y坐标 * 参数3:终点的x坐标 * 参数4:终点的y坐标 * 参数5:画笔 * ps:这里其实就是在画布上画条对角线 */ canvas.drawLine(0,0,getMeasuredWidth(),getMeasuredHeight(),paint); }
- canvas.drawLines(...),多条线条的绘制其实也不复杂,只会是把所有线条的点封装到了数组里面而已,下面看代码:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //创建画笔(后续详细记录paint的使用) Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10.0f); paint.setAntiAlias(true); /** * 参数1:一个float数组,里面的元素按顺序往后,每四个点描述一条线,前两个描述线条起始点的x,y坐标,后两个点描述线条结束点的x,y坐标 * 如果出现剩下的元素不够四个点的,剩下的元素会被丢弃,下面例子中画了两条线条 * * 参数2:画笔 */ canvas.drawLines(new float[]{20,50,getMeasuredWidth()-20,50,20,100,getMeasuredWidth()-20,100},paint); //drawLines还有个重载方法,想用的可自行查阅文档,这里就不多说了 }
6、画椭圆canvas.drawOval(Rectf rectf,Paint paint),创建椭圆就要用到另一个东西,就是好RectF,这个东西表示的是一块区域,后续再深入点研究再做笔记
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //创建画笔(后续详细记录paint的使用) Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10.0f); paint.setAntiAlias(true); /** * 参数1:椭圆的left值 * 参数2:椭圆的top值 * 参数3:椭圆的right值 * 参数4:椭圆的bottom值 */ RectF oval = new RectF(150, 200, 500, 400); // 画一个椭圆 canvas.drawOval(oval, paint);}
为了便于理解元素在画布中的位置,下面是椭圆在控件中的位置示意图:
7、画弧度(扇形)canvas.drawArc(...),画弧分为两种方式,一种时候弧线的两端不跟中心点相连,这种就真的是弧,另外一种是跟中心点相连的,那就成扇形了,看代码并附上对比图:
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //创建画笔(后续详细记录paint的使用) Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10.0f); paint.setAntiAlias(true); /** * 创建第一块区域 * 参数1:left * 参数2:top * 参数3:right * 参数4:bottom */ RectF oval = new RectF(100, 300, 300, 500); /** * 创建第二块区域(用于测试不连接圆心的) */ RectF _oval = new RectF(500, 300, 700, 500); /** * 参数1:RectF对象。 * 参数2:开始的角度。(水平向右为0度顺时针反向为正方向) * 参数3:扫过的角度 * 参数4:是否和中心连线 * 参数5:画笔 */ canvas.drawArc(oval, 0, 120, true, paint); /** * 弧线两端不连接圆心 */ canvas.drawArc(_oval, 0, 120, false, paint);}
8、画矩形canvas.drawRect(...),直接上代码:
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //创建画笔(后续详细记录paint的使用) Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10.0f); paint.setAntiAlias(true); /** * 矩形区域 * 参数1:float left * 参数2:float top * 参数3:float right * 参数4:float bottom */ canvas.drawRect(100,100, 300, 300, paint); //画圆角矩形 RectF _oval = new RectF(80, 260, 200, 300); /** * 参数1:矩形区域 * 参数2:圆角x轴方向半径 * 参数3:圆角y轴方向半径(第二第三个参数,可以把两个值调得相差大点,运行看效果就明白了) * ps:矩形的圆角还可以通过设置paint的Join来实现,或许在Paint的笔记中详细说明 */ canvas.drawRoundRect(_oval, 10, 10, paint); }
9、画多边形canvas.drawPath(Path path,Paint paint);,绘制多边形的原理其实是一个画线的过程,最后把线的点和终点连起来而已,所以这里就用到了一个绘制路径用的Path类,这类还木有时间深入研究,后续学习到了再补充笔记,下面看一个简单例子:
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布背景颜色 canvas.drawColor(Color.YELLOW); //创建画笔(后续详细记录paint的使用) Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10.0f); paint.setAntiAlias(true); //创建一个path对象 Path path = new Path(); int width = getMeasuredWidth(); int height = getMeasuredHeight(); //初始化起始点,如果不初始化默认坐标为(0,0) path.moveTo(width / 2, 0); //五角星各个点的坐标(瞎猜的,不会算正规五角星的坐标) path.lineTo(width-width/10, height-height/10); path.lineTo(0,height/3); path.lineTo(width,height/3); path.lineTo(width/10,height-height/10); //连接起点跟终点 path.close(); canvas.drawPath(path,paint);}
THE END!!!更高级的用户后续学习到了再补上,比如说错切、旋转等等!
注:由于个人android学习的大部分知识都来源于网络,比如说:郭霖、张鸿洋、泡在网上的日子等等大牛的博客,在此写下一些学习笔记,并加入一些个人的理解或者说总结,主要用于个人提升。
阅读全文
0 0
- 自定义控件基础知识--Canvas
- Canvas与自定义控件
- Android 自定义控件canvas
- Android自定义控件前导基础知识学习(一)——Canvas
- 自定义控件基础知识
- 自定义控件基础知识
- 自定义控件—canvas、paint
- android 自定义控件基础知识1
- android 自定义控件Canvas用方法
- 【自定义控件】练习:canvas两个demo练习
- 自定义控件设置canvas画布的大小
- Android 自定义控件基础 canvas paint
- Android 自定义控件canvas- Layer图层
- 自定义控件-Canvas的绘制与操作
- 自定义控件---图层,画布和canvas
- 自定义控件基础知识2 -- 自定义ViewGroup
- Canvas基础知识
- Android 自定义控件学习之一 基础知识
- ECMAScript 6 入门学习(1.let和const命令)
- Android Studio 3.0——unable to resolve dependency for cordovalib
- linux 下安装并运行kettle 程序
- siamese(孪生) 网络
- Visual Leak Detector工作原理(旧版本)
- 自定义控件基础知识--Canvas
- 10.25日常总结
- Codeforces Round #442 (Div. 2) D. Olya and Energy Drinks (bfs)
- nginx的启动_停止_重启
- @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
- Servlet学习心得总结
- idea for Mac 错误: 找不到或无法加载主类 com.company.Main
- 前端怎么写出一个好的页面
- 立体匹配的研究背景以及意义