Android 自定义 view(三)—— onDraw 方法理解
前言:
上一篇已经介绍了用自己定义的属性怎么简单定义一个view《Android 自定义view(二) —— attr 使用》,那么接下来我们继续深究自定义view,下一步将要去简单理解自定义view的一个比较重要的方法 onDraw(Canvas canvas) ,在探究 onDraw方法之前,我们必须先深入了解两个类Paint和Canvas 。
第一:认识Paint
在探究onDraw之前首先必须要认识两个类,这里给出非常不错的两个资料参考网站,我也是从这里得到想要知道的东西,简单的说这下面几篇文章已经够我们喝一壶了,这里我就不再献丑了
http://www.apihome.cn/api/android/Paint.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1105/1907.html
http://blog.csdn.net/harvic880925/article/details/39080931
第二:认识Canvas
Canvas类简单理解就是表示一块画布,可以在上面画我们想画的东西
Canvas中的方法很多,Canvas可以绘制的对象有:
- 弧线(arcs) canvas.
- 填充颜色(argb和color)
- Bitmap
- 圆(circle和oval)
- 点(point)
- 线(line)
- 矩形(Rect)
- 图片(Picture)
- 圆角矩形 (RoundRect)
- 文本(text)
- 顶点(Vertices)
- 路径(path)
canvas.save():把当前的绘制的图像保存起来,让后续的操作相当于是在一个新的图层上的操作。
canvas.restore(); 把当前画布返回(调整)到上一个save()状态之前
canvas.translate(dx, dy); //把当前画布的原点移到(dx,dy),后面的操作都以(dx,dy)作为参照点,默认原点为(0,0)
canvas.scale(x,y);扩大。x为水平方向的放大倍数,y为竖直方向的放大倍数
canvas.rotate(angel):旋转.angle指旋转的角度,顺时针旋转。
canvas.transform():切变。所谓切变,其实就是把图像的顶部或底部推到一边。
canvas.saveLayer(bounds, paint, saveFlags);
推荐文章:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html
第三:Canvas 简单使用
有了上面对Canvas 方法的认识,那么下面我就用上面的方法来进行相关练习
/**
* Created by yishujun on 16/6/3.
*/
public class YView extends View {
private Context mContext;
//定义一个paint
private Paint mPaint;
public YView(Context context) {
this(context, null);
}
public YView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public YView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawNomal(canvas);
drawTest(canvas);
//drawDial(canvas);
}
/**
* 常规绘制 以(0,0)作为坐标原点参考点
* @param canvas
*/
private void drawNomal(Canvas canvas){
mPaint =new Paint();
// 绘制画布背景
canvas.drawColor(Color.GRAY);
//设置画笔颜色
mPaint.setColor(Color.BLUE);
//设置画笔为空心 如果将这里改为Style.STROKE 这个图中的实线圆柱体就变成了空心的圆柱体
mPaint.setStyle(Paint.Style.STROKE);
//绘制直线
canvas.drawLine(50, 50, 450, 50, mPaint);
//绘制矩形
canvas.drawRect(100, 100, 200, 300, mPaint);
//绘制矩形
mPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(300, 100, 400, 400, mPaint);
mPaint.setColor(Color.YELLOW);
RectF r = new RectF(150, 500, 270, 600);
// 画矩形
canvas.drawRect(r, mPaint);
// 画圆
canvas.drawCircle(50, 500, 50, mPaint);
RectF oval = new RectF(350, 500, 450, 700);
// 画椭圆
canvas.drawOval(oval, mPaint);
RectF rect = new RectF(100, 700, 170, 800);
// 画圆角矩形
canvas.drawRoundRect(rect, 30, 20, mPaint);
//绘制圆弧 绘制弧形
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
RectF re1 = new RectF(1000, 50, 1400, 200);
canvas.drawArc(re1, 10, 270, false, mPaint);
RectF re2 = new RectF(1000, 300, 1400, 500);
canvas.drawArc(re2, 10, 270, true, mPaint);
//设置Path路径
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(3);
Path path = new Path();
path.moveTo(500, 100);
path.lineTo(920, 80);
path.lineTo(720, 200);
path.lineTo(600, 400);
path.close();
mPaint.setTextSize(46);
canvas.drawPath(path, mPaint);
canvas.drawTextOnPath("7qiuwoeruowoqjifasdkfjksjfiojio23ur8950", path, -20, -20, mPaint);
//三角形
path.moveTo(10, 330);
path.lineTo(70, 330);
path.lineTo(40, 270);
path.close();
canvas.drawPath(path, mPaint);
//把开始的点和最后的点连接在一起,构成一个封闭梯形
path.moveTo(10, 410);//绘画基点
path.lineTo(70, 410);
path.lineTo(55, 350);
path.lineTo(25, 350);
//如果是Style.FILL的话,不设置close,也没有区别,可是如果是STROKE模式, 如果不设置close,图形不封闭。当然,你也可以不设置close,再添加一条线,效果一样。
path.close();
canvas.drawPath(path, mPaint);
//参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点,其中参数new int[]{startColor, midleColor,endColor}是参与渐变效果的颜色集合,
// 其中参数new float[]{0 , 0.5f, 1.0f}是定义每个颜色处于的渐变相对位置, 这个参数可以为null,如果为null表示所有的颜色按顺序均匀的分布
// Shader.TileMode三种模式
// REPEAT:沿着渐变方向循环重复
// CLAMP:如果在预先定义的范围外画的话,就重复边界的颜色
// MIRROR:与REPEAT一样都是循环重复,但这个会对称重复
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW},
null, Shader.TileMode.REPEAT);
mPaint.setShader(mShader);// 用Shader中定义定义的颜色来话
mPaint.setStyle(Paint.Style.FILL);
Path path1 = new Path();
path1.moveTo(170, 410);
path1.lineTo(230, 410);
path1.lineTo(215, 350);
path1.lineTo(185, 350);
path1.close();
canvas.drawPath(path1, mPaint);
canvas.save();
}
/**
* 绘制方法练习
* @param canvas
*/
private void drawTest(Canvas canvas){
mPaint =new Paint();
mPaint.setColor(Color.RED);
//平移测试
canvas.translate(50, 900);
canvas.drawRect(new Rect(0, 0, 100, 100), mPaint);
canvas.translate(50, 50);
canvas.drawRect(new Rect(0, 0, 100, 100), mPaint);
//缩放测试
canvas.translate(100,-50);
canvas.drawRect(new Rect(0, 0, 300, 300), mPaint);
// 保存画布状态
canvas.save();
canvas.scale(0.5f, 0.5f);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 300, 300), mPaint);
// 画布状态回滚
canvas.restore();
// 先将画布平移到矩形的中心
canvas.translate(400, -50);
canvas.drawRect(new Rect(0, 0, 300, 300), mPaint);
//旋转测试
canvas.save();
canvas.translate(350, 50);
canvas.drawRect(new Rect(0, 0, 200, 200), mPaint);
mPaint.setColor(Color.RED);
canvas.rotate(45,200,200);
canvas.drawRect(new Rect(0, 0, 200, 200), mPaint);
canvas.restore();
//画布错切 三角函数tan的值
canvas.translate(350, 300);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
// y 方向上倾斜45 度
canvas.skew(0, 1);
mPaint.setColor(0x8800ff00);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
}
}
示例截图

示例代码下载
Android 自定义 view(三)—— onDraw 方法理解的更多相关文章
- Android自定义View的实现方法,带你一步步深入了解View(四)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回 ...
- 【转】Android自定义View的实现方法,带你一步步深入了解View(四)
原文网址: 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到 ...
- Android 自定义View (三) 圆环交替 等待效果
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24500107 一个朋友今天有这么个需求(下图),我觉得那自定义View来做还是很 ...
- android 自定义view 前的基础知识
本篇文章是自己自学自定义view前的准备,具体参考资料来自 Android LayoutInflater原理分析,带你一步步深入了解View(一) Android视图绘制流程完全解析,带你一步步深入了 ...
- Android 自定义 view(四)—— onMeasure 方法理解
前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...
- Android自定义View(三、深入解析控件测量onMeasure)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51490283 本文出自:[openXu的博客] 目录: onMeasure什么时候会被调用 ...
- 【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍
前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10979161.html],谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然 ...
- Android自定义View的三种实现方式
在毕设项目中多处用到自定义控件,一直打算总结一下自定义控件的实现方式,今天就来总结一下吧.在此之前学习了郭霖大神博客上面关于自定义View的几篇博文,感觉受益良多,本文中就参考了其中的一些内容. 总结 ...
- Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程
转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...
随机推荐
- iOS @@创建NSURL的字面量
@@ 是创建 NSURL 的字面量的绝佳方法(例如:@@"http://example.com")
- React使用jquery方式动态获取数据
好久没写react了,今天有空写一下来react实现实时请求数据,并刷新数据的小demo. 首先我还是选择了jquery方式中自带的ajax获取数据,首先要引用所需的js包 接下来要写一个自定义的js ...
- WSDL项目---添加头信息和附件
用于底层协议的SOAP请求是HTTP,可以添加两个自定义HTTP头(例如用于身份验证或会话)和附件. 让我们看一下这两个. 1. 自定义HTTP标头 直接添加自定义HTTP头: 我们已经添加了自定义内 ...
- Codeforces Round #279 (Div. 2) vector
A. Team Olympiad time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- C#中UnixTime和DateTime的转换(转载)
由于在API请求中返回回来的时间格式为UNIX形式,需要转换成正常的显示方式,在网上找到了这么一个例子. 使用是在C#中使用的,所以WP8开发应该也可以. 转载源地址:http://blog.linu ...
- JDBC、JTA、Spring的事务管理
Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么 ...
- AFNetworking3.1.0检查网络状态
我们知道AFNetworking3.0版本中,弃用了AFHTTPRequestOperationManager.那么进行网络判断的时候就需要使用 AFNetworkReachabilityManage ...
- C++ string
C++ string best practices => LPTSTR, PSTR, CString, _T, TEXT, Win32 API, Win16. string, wstring. ...
- 读取java目录中相同目录、相同名称的文件
使用ClassLoader的getResources方法(注意,不是getResource,少了s),可获得指定文件的包含jar包名称的多个路径值,然后依次读取文件即可. 使用class,只能通过ge ...
- poj3740
#include<stdio.h>#include<iostream>int map[16][300];int vistx[16];int visty[300];int zhe ...