1,继承自view,实现ondraw方法:

    初始化画笔,TextPaint paint,并设置画笔属性:

      paint.setFlags(Paint.ANTI_ALIAS_FLAG):画笔抗锯齿。

      paint.setStyle(Paint.Style.STROKE):设置画笔样式,默认全部填充Full

        {  1.Paint.Style.STROKE:描边;

            2.Paint.Style.FILL_AND_STROKE:描边并填充

            3.Paint.Style.FILL:填充

        }

     paint.setStrokeCap(Paint.Cap.ROUND):画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式

       {   1,圆形样式    Cap.ROUND,

           2,方形样式  Cap.SQUARE

       }

     paint.setColor(0xff00ff00):设置画笔颜色

     Canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint):利用TextPaint在canvas上绘制线条:坐标从(startX,startY)到(stopX,stopY),坐标点起点为左上角,起点为0,0

2,在xml布局里面设置自定义布局控件

package com.soyoungboy.customview.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View; import com.example.customview.R; /**
* 自定义view基础 练习
*
* @author soyoungboy
*
*/
public class CustomView extends View {
public TextPaint paint;
private float textHeight;
private float fontSize = getResources().getDimensionPixelSize(
R.dimen.default_font_size);
private float density = getResources().getDisplayMetrics().density; public CustomView(Context context) {
super(context);
init(null, 0);
} public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
} public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
} /**
* 初始化操作
*
* @param attrs
* @param defStyleAttr
*/
private void init(AttributeSet attrs, int defStyleAttr) {
// 初始化TextPaint
paint = new TextPaint(); // paint的默认字体大小
Log.i("iSpring", "默认字体大小: " + paint.getTextSize() + "px"); // paint的默认颜色
Log.i("iSpring", "默认颜色: " + Integer.toString(paint.getColor(), 16)); // paint的默认style是FILL,即填充模式
Log.i("iSpring", "默认style: " + paint.getStyle().toString()); // paint的默认cap是
Log.i("iSpring", "默认cap: " + paint.getStrokeCap().toString()); // paint默认的strokeWidth
Log.i("iSpring", "默认strokeWidth: " + paint.getStrokeWidth() + ""); paint.setFlags(Paint.ANTI_ALIAS_FLAG);// 设置为抗锯齿
paint.setTextSize(fontSize);// 设置字体大小 // 初始化textHeight
textHeight = fontSize;
// Paint.FontMetrics fontMetrics = paint.getFontMetrics();
// textHeight = Math.abs(fontMetrics.top) + fontMetrics.bottom;
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawAxis(canvas);
} /**
* 绘制坐标系
*
* @param canvas
*/
private void drawAxis(Canvas canvas) {
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
// 置画笔样式,如果不设置,默认是全部填充(FILL)。可选项为:FILL,FILL_OR_STROKE,或STROKE
// 画笔样式分三种:
// 1.Paint.Style.STROKE:描边
// 2.Paint.Style.FILL_AND_STROKE:描边并填充
// 3.Paint.Style.FILL:填充 paint.setStyle(Paint.Style.STROKE);
// 该方法用来设置我们画笔的 笔触风格 ,比如:ROUND,表示是圆角的笔触。
// 那么什么叫笔触呢,其实很简单,就像我们现实世界中的笔,如果你用圆珠笔在纸上戳一点,
// 那么这个点一定是个圆,即便很小,它代表了笔的笔触形状,如果我们把一支铅笔笔尖削成方形的,
// 那么画出来的线条会是一条弯曲的“矩形”,这就是笔触的意思。
// 除了ROUND,Paint.Cap还提供了另外两种类型:SQUARE和BUTT
paint.setStrokeCap(Paint.Cap.ROUND);
//当画笔样式(style)为STROKE或FILL_OR_STROKE时(空心样式时),设置笔刷的粗细度。
paint.setStrokeWidth(6 * density);
//用绿色画x轴,用蓝色画y轴 //第一次绘制坐标轴
//设置画笔颜色为绿色
paint.setColor(0xff00ff00);//绿色
//Canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
//从开始点为0,0的地方绘制线条到canvasWidth,0坐标,也就是说,沿着x轴绘制线条
canvas.drawLine(0, 0, canvasWidth, 0, paint);//绘制x轴
//设置画笔颜色为蓝色
paint.setColor(0xff0000ff);//蓝色,也就说沿着Y轴绘制线条
//从开始点为0,0的地方绘制线条到0,canvasHeight坐标
canvas.drawLine(0, 0, 0, canvasHeight, paint);//绘制y轴
}
}

背景颜色绘制:

  canvas.drawARGB(a, r, g, b):其中a,r,g,b为0到255的int值,用来组成画布的背景颜色

  canvas.drawColor(Color.BLUE) :将会以颜色ARBG填充整个控件的Canvas背景

  canvas.drawColor(Color.BLUE, Mode.SCREEN) :绘制颜色,但是要制定一个mode

    mode参数:

    

    对应下图:

    

    对应如下规则:

      SRC :只绘制源图像

      DST :只绘制目标图像

      DST_OVER :在源图像的顶部绘制目标图像

       DST_IN :只在源图像和目标图像相交的地方绘制目标图像

      DST_OUT :只在源图像和目标图像不相交的地方绘制目标图像

      DST_ATOP :在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像

      SRC_OVER :在目标图像的顶部绘制源图像

       SRC_IN :只在源图像和目标图像相交的地方绘制源图像

      SRC_OUT :只在源图像和目标图像不相交的地方绘制源图像

      SRC_ATOP :在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像

       XOR :在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容

      LIGHTEN :获得每个位置上两幅图像中最亮的像素并显示

      DARKEN :获得每个位置上两幅图像中最暗的像素并显示

      MULTIPLY :将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255

      SCREEN :反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)

如上代码ondraw里面代码:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawARGB(168, 138, 179, 233);
}

效果:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.RED);
}

效果:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLUE, Mode.SCREEN);
}


绘制文字

博客园里面有篇文字讲的很细,可以去看看:http://www.cnblogs.com/tianzhijiexian/p/4297664.html

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置抗锯齿
paint.setAntiAlias(true);
//控制文字大小
paint.setTextSize(24);
//控制文字颜色
paint.setColor(Color.RED);
//设置文字粗体
paint.setFakeBoldText(true);
//设置是否显示下划线
paint.setUnderlineText(true);
//设置字体类型
paint.setTypeface(Typeface.SANS_SERIF);
//左上角倾斜
paint.setTextSkewX(-0.25f);
//文本删除线
paint.setStrikeThruText(true); //第一个为显示的内容,第二个参数为文字显示的x轴坐标,第三个为Y坐标
canvas.drawText("我是大帅哥", canvas.getWidth()/2, canvas.getHeight()/2, paint);
}

效果如下:


绘制点:

StrokeWidth  --  控制宽度
color -- 控制颜色
StrokeCap -- 控制形状
通过drawpoint来进行绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setStrokeWidth(100);
paint.setColor(Color.YELLOW);
// paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawPoint(canvas.getWidth()/3, canvas.getHeight()/3, paint);
}

效果:


绘制方块

擦,还有这种:

如上三种方法来进行绘制方块:

canvas.drawcircle为绘制圆

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect r = new Rect(100, 100, 300, 300);
//方块背后的颜色
canvas.drawColor(Color.RED);
//绘制方格的颜色
paint.setColor(Color.WHITE);
//绘制方格
canvas.drawRect(r, paint);
paint.setColor(Color.BLACK);
//绘制黑色的圆
canvas.drawCircle(200, 200, 100, paint);
}

绘制圆,style有三种:

代码试试,看看效果:

填充,填充轮廓和里面

Fill或者Fill_AND_STROKE:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect r = new Rect(100, 100, 300, 300);
//方块背后的颜色
canvas.drawColor(Color.RED);
//绘制方格的颜色
paint.setColor(Color.WHITE);
//绘制方格
canvas.drawRect(r, paint);
paint.setColor(Color.BLACK);
paint.setStyle(Style.FILL);
//绘制黑色的圆
canvas.drawCircle(200, 200, 100, paint);
}

效果如上图:

设置为:

Stoke,绘制轮廓

paint.setStyle(Style.STROKE);


绘制椭圆

虽然调用的是drawoval,其实还是主要通过RectF和上下左右的位置的计算来进行控制

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int Width = canvas.getWidth();
int height = canvas.getHeight()/2;
float left = 10 * density;
float right = Width-left;
float top = height/4;
float bottom = height/2+height/4;
paint.setColor(Color.BLACK);
paint.setStyle(Style.FILL);
RectF f = new RectF(left, top, right, bottom);
//绘制黄色的椭圆
canvas.drawOval(f, paint);
}

paint.setStyle(Style.STROKE)为图2


drawBitmap:绘制图片

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher);
canvas.drawBitmap(mBmp , mBmp.getWidth(), mBmp.getHeight(), paint);
canvas.restore();
}

BitmpaUtils.drawableToBitmap方法代码,将drawable转换为bitmap:

public static Bitmap drawableToBitmap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}

执行效果:

缩放借助Matrix来实现:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher);
canvas.drawBitmap(mBmp , mBmp.getWidth(), mBmp.getHeight(), paint);
Matrix matrix=new Matrix();
matrix.postScale(0.5f, 0.5f
);
Bitmap dstbmp=Bitmap.createBitmap(mBmp,0,0,mBmp.getWidth(),
mBmp.getHeight(),matrix,true);
canvas.drawBitmap(dstbmp, 10, 10, null);
}

看下效果,宽高缩小一半:

对图片进行旋转:

matrix.postRotate(45);

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Matrix matrix=new Matrix();
matrix.postRotate(45);
Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher);
Bitmap dstbmp=Bitmap.createBitmap(mBmp,0,0,mBmp.getWidth(),
mBmp.getHeight(),matrix,true);
canvas.drawBitmap(dstbmp, 10, 10, null);
}

自定义控件学习之canvas和paint相关知识点学习的更多相关文章

  1. 09 Servlet相关知识点---学习笔记

    1.概念:运行在服务器端的小程序 Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则.将来我们自定义一个类,实现Servlet接口,复写方法. 2.快速入门:(1)创 ...

  2. 安卓自定义控件(一)Canvas、Paint、Shader、Xfermode

    关于自定义控件,之前就写过一篇自定义控件,上图下字的Button,图片任意指定大小,但是使用效果还是让人感觉不幸福,这次索性彻彻底底地对自定义控件做一次彻彻底底的总结. 我会花4篇博客来介绍自定义控件 ...

  3. Android使用学习之画图(Canvas,Paint)与手势感应及其应用(乒乓球小游戏)

    作为一个没有学习Android的菜鸟,近期一直在工作之外努力地学习的Android的使用. 这周看了下Android的画图.主要是Canvas,Paint等,感觉须要实践下.下午正好有空,就想整一个乒 ...

  4. Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳

    前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...

  5. django学习-2.urls.py和view.py的相关知识点

    1.URL函数简单解析 1.1.url() 函数可以接收四个参数,分别是两个必选参数:regex.view,和两个可选参数:kwargs.name. def url(regex, view, kwar ...

  6. 学习记录013-NFS相关知识点

    一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...

  7. Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解

    上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定 ...

  8. IOS开发涉及有点概念&相关知识点

    前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...

  9. IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结

    添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...

随机推荐

  1. css ie6最小高度问题

    最小高度问题:  这个最小高度 min-height:的问题,因为min-height:只在IE7\FF中起作用.至于这个IE6死活就是不认.而我这个页面又必需得用这个最小高度来定.   但头痛的是I ...

  2. 从c#基础到java基础的学习的感悟

    从进入培训公司到现在已经有三周多了,我想我和绝大多数人一样,能考虑进入培训学校,肯定是心理做好了准备的,那就是只有一个目的学好这门技术,从之前的开班典礼来看,从每个同学的自我介绍,我们这的大部分人来这 ...

  3. Spring MVC---基于注解的控制器

                                     基于注解的控制器 SpringMVC是一个基于DispatcherServlet的MVC框架,每个请求最先访问的是Dispatcher ...

  4. 50道java线程面试题

    50道Java线程面试题 下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序 ...

  5. qdoc 写法

    Qdoc 注释 Qdoc注释有一些命令, 能够对文档进行组织. QDoc能识别以下3种类型的命令 主题(topic command) 主题命令确定了文档的元素,例如C++类(class),函数(fun ...

  6. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

  7. Logstash安装搭建(一)

    Logstash是一个具有实时管道的开源数据收集引擎.可以动态地统一不同来源的数据,并将数据归到不同目的地.也是一个管理事件和日志工具.你可以用它来收集日志,分析它们,并将它们储存起来以供以后使用. ...

  8. Linux下的数据监控工具

    Vmstat Vmstat,virtual memmory statistics(虚拟内存统计),主要是对操作系统的内存信息.进程状态.cpu活动等进行监视,但是它不能对某个进程进行深入的分析. Pr ...

  9. svn用Cornerstone上传项目丢失静态库.a问题的解决

    最近电脑重装系统后,装上Cornerstone上传项目后,发现又有丢失.a文件的问题,这里说一下解决办法,打开Preferences-->Subversion-->General,将Use ...

  10. Objective-C Runtime 运行时之五:协议与分类(转载)

    Objective-C中的分类允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到. Objective-C中的协议是普遍存在的 ...