自定义ViewPorterDuffXfermodeWord格式文档下载.docx

上传人:b****3 文档编号:17235184 上传时间:2022-11-29 格式:DOCX 页数:18 大小:556.31KB
下载 相关 举报
自定义ViewPorterDuffXfermodeWord格式文档下载.docx_第1页
第1页 / 共18页
自定义ViewPorterDuffXfermodeWord格式文档下载.docx_第2页
第2页 / 共18页
自定义ViewPorterDuffXfermodeWord格式文档下载.docx_第3页
第3页 / 共18页
自定义ViewPorterDuffXfermodeWord格式文档下载.docx_第4页
第4页 / 共18页
自定义ViewPorterDuffXfermodeWord格式文档下载.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

自定义ViewPorterDuffXfermodeWord格式文档下载.docx

《自定义ViewPorterDuffXfermodeWord格式文档下载.docx》由会员分享,可在线阅读,更多相关《自定义ViewPorterDuffXfermodeWord格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。

自定义ViewPorterDuffXfermodeWord格式文档下载.docx

mPaint.setStyle(Paint.Style.FILL);

mPaint.setAntiAlias(true);

mPaint.setDither(true);

@Override

protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){

super.onSizeChanged(w,h,oldw,oldh);

mViewWidth=w;

mViewHeight=h;

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

}

实现代码:

//自定义View

canvas.translate(mViewWidth/2,mViewHeight/2);

firstExample(canvas);

/**

*制作具有相交部分的圆和正方形

*/

privatevoidfirstExample(Canvascanvas){

//绘制一个正方型

mPaint.setColor(Color.BLUE);

canvas.drawRect(-300,-300,0,0,mPaint);

//绘制一个圆

mPaint.setColor(Color.RED);

canvas.drawCircle(0,0,200,mPaint);

首先我们要知道系统是如何绘制图形的,系统每绘制一个图形(如:

canvas.drawXxx())就代表创建了一个图层,那么什么叫做图层?

我们看一张图就明白了

1、图片中的三个颜色分别代表一个图层,每个图层的内容就是绘制的图形。

2、系统默认是图层向上累加绘制,也就是红色是最先绘制的,蓝色是之后绘制的,黄色是最后绘制的。

所以图形相交的部分,就被上层的图层的内容给掩盖了。

既然明白了图层的概念,我们就可以回到正题,如何处理图层的相交部分。

Android为我们提供了PorterDuffXfermode这个类,来处理关于图层相交的问题。

PorterDuffXfermode的使用

PorterDuffXfermode能够实现的功能

首先我们来看一下PorterDuffXfermode有哪些功能

注:

(dst表示先绘制的图,src表示后绘制的图)

稍微简单的解释一下常用的功能:

凡是带有IN的表示:

取两个图层的相交部分,关于相交部分显示什么内容有DST和SRC决定。

凡是带有OUT的表示:

取两个图层中另一方不相交的部分。

凡是带有OVER的表示:

当俩个图层存在相交部分时,显示哪个图层的内容

PorterDuffXfermode的简单使用

作用一:

图层的交换

任务:

将第一幅图的正方形显示在顶部,圆形显示在底部。

首先如何创建PorterDuffXfermode。

//构造方法

*PorterDuff.Mode:

这是一个枚举类,枚举类的参数为上面的示意图

PorterDuffXfermode(PorterDuff.Modemode)

然后,将创建好的PorterDuffXfermode放入Paint中

mPaint.setXfermode(newPorterDuffXfermode(mode))

为什么是将模式放入到画笔中00,这是表示画笔当遇到图形相交的问题的时候,按照这种方式来解决。

代码的实现:

privatevoidsecondExample(Canvascanvas){

//设置相交时候,图层显示的模式(表示相交部分显示前一个图层的内容)

mPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_OVER));

效果图:

我们发现,竟然红色的圆消失了--,什么鬼跟说好的不一样呀!

原因是这种直接使用PorterDuffXfermode的用法是错误的--,真是糟糕的体验,哪里错了,原理上完全没问题好吧。

(警告:

PorterDuffXfermode的第一道坑)

正确的使用方法:

首先需要创造一个Bitmap,然后首先在这个Bitmap上绘制完成之后,再将这个Bitmap通过canvas显示在View上。

正确代码:

privatevoidthirdExample(Canvascanvas){

//创建一个Bmap

Bitmapout=Bitmap.createBitmap(600,600,Bitmap.Config.ARGB_8888);

//创建该Bitmap的画布

CanvasbitmapCanvas=newCanvas(out);

bitmapCanvas.drawRect(0,0,300,300,mPaint);

//设置相交时候,图层显示的模式(表示当相交的时候,圆形为先绘制的图形)

bitmapCanvas.drawCircle(300,300,200,mPaint);

//最后,将完成的图片绘制在View上

canvas.drawBitmap(out,-300,-300,null);

效果图:

天哪,真是太麻烦了--,直接让圆形和方形的绘制顺序调换一下,才是最快最省时间的方法~~。

当然对与这个例子通过调换执行顺序是最快的,但是毕竟我们是来学习使用技巧的。

实现圆框图片

作用二:

实现两张图相交部分显示的效果

原理说明:

首先创建一个圆形,这个圆形是用来设置图片显示的区域。

之后获取图片资源(图片的大小最好比设定的圆形大)。

然后,设置Xfermode为SRC_IN就表示,当圆形和图片相交的时候,截取相交部分(也就是截取圆形),相交部分显示后一个图层的内容(也就是图片)

代码展示:

privatevoidforthExample(Canvascanvas){

//创建自定义的Bitmap

Bitmapout=Bitmap.createBitmap(300,300,Bitmap.Config.ARGB_8888);

//获取图片

Bitmapbitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.picture);

//获取Bitmap的画笔

//在Bitmap上绘制一个圆形

bitmapCanvas.drawCircle(150,150,150,mPaint);

//设置显示后画图形的交集

mPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC_IN));

//绘制需要显示的图片

bitmapCanvas.drawBitmap(bitmap,0,0,mPaint);

canvas.drawBitmap(out,-150,-150,null);

补充:

图层的合并

在制作刮刮卡我们还需要补充一个知识,在开始的位置我曾讲到绘制一次图形就相当于创建一个图层。

其实实际上还有一个步骤,当使用canvas完成一次绘制过程后,就会将当前图层,和上一个图层合并为一个图层。

也就是说,我们首先创建了一个图层,并在其上画了个正方形,然后我们又创建了一个图层,并在其上绘制了一个圆形。

当圆形绘制完成的时候,两个图层合并成为了一个图层。

那么这有什么后果呢?

合并之后就表示,相交部分不再是红色覆盖在蓝色上的上下层关系。

而是相交部分是红色代替了。

如果不合并图层的话,那么我创建了第三个图层,是圆的内接矩形,并使用DST_OUT(表示挖出红色圆的内接矩形)那么之后,倒影出得应该是这样的图形。

代码:

privatevoidfifthExample(Canvascanvas){

//首先在View上绘制正方形

//创建Bitmap

Bitmapout=Bitmap.createBitmap(400,400,Bitmap.Config.ARGB_8888);

//在Bitmap上绘制圆

bitmapCanvas.drawCircle(200,200,200,mPaint);

//设置模式为DST_OUT

mPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_OUT));

//圆的内接正方形的参数

floatsquareLeft=200-100*(float)Math.sqrt

(2);

floatsquareTop=squareLeft;

floatsquareRight=squareLeft+200*(float)Math.sqrt

(2);

floatsquareBottom=squareRight;

//取圆与内接正方形不相交的部分bitmapCanvas.drawRect(squareLeft,squareTop,squareRight,squareBottom,mPaint);

//绘制在View上

canvas.drawBitmap(out,-200,-200,null);

但是实际上是这样的:

如果是三个图层的话,第二个第三个图层合并之后,透明部分显示应该有第一个图层的内容。

但是由于图层的合并,之后就没有层次这个概念了,最后透明部分显示的就是View的背景

privatevoidsixthExample(Cnvascanvas){

Bitmapout=Bitmap.createBitmap(500,500,Bitmap.Config.ARGB_8888);

//在Bitmap上绘制正方形(这是与上面代码区别的部分)

bitmapCanvas.drawRect(0,0,250,250,mPaint);

bitmapCanvas.drawCircle(250,250,200,mPaint);

floatsquareLeft=250-100*(float)Math.sqrt

(2);

bitmapCanvas.drawRect(squareLeft,squareTop,squareRight,squareBottom,mPaint);

大招:

实现刮刮卡的效果

原理:

首先获取遮盖的图片,之后再创建遮盖在图片上的蒙版。

最后通过点击事件,设置擦除的路径,制作出路径和蒙版合并的遮罩层。

publicclassScratchViewextendsView{

privateBitmapmContentBitmap;

privateBitmapmMaskBitmap;

privateCanvasmBitmapCanvas;

privatefinalPathmPath=newPath();

privateintmBitmapWidth;

privateintmBitmapHeight;

publicScratchView(Contextcontext){

publicScratchView(Contextcontext,AttributeSetattrs){

publicScratchView(Contextcontext,AttributeSetattrs,intdefStyleAttr){

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeWidth(20);

mPaint.setStrokeCap(Paint.Cap.ROUND);

mPaint.setColor(Color.TRANSPARENT);

//初始化,刮刮卡的内容

mContentBitmap=BitmapFactory.

decodeResource(getResources(),R.mipmap.picture);

mBitmapWidth=mContentBitmap.getWidth();

mBitmapHeight=mContentBitmap.getHeight();

//初始化刮刮卡的遮盖效果

mMaskBitmap=Bitmap.createBitmap(mBitmapWidth,mBitmapHeight,Bitmap.Config.ARGB_8888);

mBitmapCanvas=newCanvas(mMaskBitmap);

//设置灰色的遮盖层

mBitmapCanvas.drawColor(Color.GRAY);

//绘制图片

canvas.drawBitmap(mContentBitmap,0,0,null);

//绘制蒙版

canvas.drawBitmap(mMaskBitmap,0,0,null);

publicbooleanonTouchEvent(MotionEventevent){

intx=(int)event.getX();

inty=(int)event.getY();

switch(event.getAction()){

caseMotionEvent.ACTION_DOWN:

mPath.moveTo(x,y);

break;

caseMotionEvent.ACTION_MOVE:

mPath.lineTo(x,y);

caseMotionEvent.ACTION_UP:

//设置擦除的路径

mBitmapCanvas.drawPath(mPath,mPaint);

//重绘

invalidate();

returntrue;

但是我们知道在自定义View中不光有canvas,还有path,如何在Path类上,使用类似集合这样的功能呢?

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 教育学心理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1