下文来自:
http://emmet1988.iteye.com/blog/1058517
----------------------------------
BasicViewDraw.java
- packagecom.view;
- importcom.test.R;
- importandroid.view.View;
- importandroid.content.Context;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.graphics.RectF;
- importandroid.graphics.Path;
- importandroid.graphics.Shader;
- importandroid.graphics.LinearGradient;
- /*自定义继承View的MyView*/
- publicclassBasicViewDrawextendsView{
- publicBasicViewDraw(Contextcontext){
- super(context);
- }
- /*重写onDraw()*/
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- /*设置背景为白色*/
- canvas.drawColor(Color.WHITE);
- Paintpaint=newPaint();
- /*去锯齿*/
- paint.setAntiAlias(true);
- /*设置paint的颜色*/
- paint.setColor(Color.RED);
- /*设置paint的style为STROKE:空心*/
- paint.setStyle(Paint.Style.STROKE);
- /*设置paint的外框宽度*/
- paint.setStrokeWidth(3);
- /*画一个空心圆形*/
- canvas.drawCircle(40,40,30,paint);
- /*画一个空心正方形*/
- canvas.drawRect(10,90,70,150,paint);
- /*画一个空心长方形*/
- canvas.drawRect(10,170,70,200,paint);
- /*画一个空心椭圆形*/
- RectFre=newRectF(10,220,70,250);
- canvas.drawOval(re,paint);
- /*画一个空心三角形*/
- Pathpath=newPath();
- path.moveTo(10,330);
- path.lineTo(70,330);
- path.lineTo(40,270);
- path.close();//记得要close
- canvas.drawPath(path,paint);
- /*画一个空心梯形*/
- Pathpath1=newPath();
- path1.moveTo(10,410);
- path1.lineTo(70,410);
- path1.lineTo(55,350);
- path1.lineTo(25,350);
- path1.close();
- canvas.drawPath(path1,paint);
- /*设置paint的style为FILL:实心*/
- paint.setStyle(Paint.Style.FILL);
- /*设置paint的颜色*/
- paint.setColor(Color.BLUE);
- /*画一个实心圆*/
- canvas.drawCircle(120,40,30,paint);
- /*画一个实心正方形*/
- canvas.drawRect(90,90,150,150,paint);
- /*画一个实心长方形*/
- canvas.drawRect(90,170,150,200,paint);
- /*画一个实心椭圆*/
- RectFre2=newRectF(90,220,150,250);
- canvas.drawOval(re2,paint);
- /*画一个实心三角形*/
- Pathpath2=newPath();
- path2.moveTo(90,330);
- path2.lineTo(150,330);
- path2.lineTo(120,270);
- path2.close();
- canvas.drawPath(path2,paint);
- /*画一个实心梯形*/
- Pathpath3=newPath();
- path3.moveTo(90,410);
- path3.lineTo(150,410);
- path3.lineTo(135,350);
- path3.lineTo(105,350);
- path3.close();
- canvas.drawPath(path3,paint);
- /*设置渐变色*/
- ShadermShader=newLinearGradient(0,0,100,100,newint[]{
- Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},null,
- Shader.TileMode.REPEAT);
- paint.setShader(mShader);
- /*画一个渐变色圆*/
- canvas.drawCircle(200,40,30,paint);
- /*画一个渐变色正方形*/
- canvas.drawRect(170,90,230,150,paint);
- /*画一个渐变色长方形*/
- canvas.drawRect(170,170,230,200,paint);
- /*画一个渐变色椭圆*/
- RectFre3=newRectF(170,220,230,250);
- canvas.drawOval(re3,paint);
- /*画一个渐变色三角形*/
- Pathpath4=newPath();
- path4.moveTo(170,330);
- path4.lineTo(230,330);
- path4.lineTo(200,270);
- path4.close();
- canvas.drawPath(path4,paint);
- /*画一个渐变色梯形*/
- Pathpath5=newPath();
- path5.moveTo(170,410);
- path5.lineTo(230,410);
- path5.lineTo(215,350);
- path5.lineTo(185,350);
- path5.close();
- canvas.drawPath(path5,paint);
- /*写字*/
- paint.setTextSize(24);
- canvas.drawText(getResources().getString(R.string.str_text1),240,50,paint);
- canvas.drawText(getResources().getString(R.string.str_text2),240,120,paint);
- canvas.drawText(getResources().getString(R.string.str_text3),240,190,paint);
- canvas.drawText(getResources().getString(R.string.str_text4),240,250,paint);
- canvas.drawText(getResources().getString(R.string.str_text5),240,320,paint);
- canvas.drawText(getResources().getString(R.string.str_text6),240,390,paint);
- }
- }
BasicView2Draw.java
- classBasicView2DrawextendsView{
- Paintpaint;
- Bitmapbitmap;
- publicBasicView2Draw(Contextcontext){
- super(context);
- paint=newPaint(Paint.ANTI_ALIAS_FLAG);
- bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.icon);
- }
- privateBitmapcreateBitmap1(){
- Bitmapbitmap1=Bitmap.createBitmap(100,100,Config.ARGB_8888);
- Canvascanvas=newCanvas(bitmap1);
- canvas.drawColor(Color.BLUE);
- //canvas.drawARGB(0,0,0,0);//透明色
- canvas.drawBitmap(bitmap,0,0,paint);
- canvas.drawText("HelloAndroid",25,55,paint);
- returnbitmap1;
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- //绘制位图
- //1.绘制位图在(10,10)位置上
- canvas.drawBitmap(createBitmap1(),10,10,paint);
- //2.canvas.drawBitmap(Bitmapbitmap,Rectsrc,Rectdest,Paintpaint);
- //canvas.drawBitmap(Bitmapbitmap,Rectsrc,RectFdest,Paintpaint);
- //绘制位图到一个指定的矩形dest中,位图会自动进行平移和缩放等操作,如果src的参数不为null
- //则会裁剪位图的部分区域来进行绘制
- Rectrect=newRect(10,10,50,60);
- RectFrectF1=newRectF(180.0f,20.0f,240.0f,80.0f);
- RectFrectF2=newRectF(180.0f,100.0f,240.0f,160.0f);
- canvas.drawBitmap(createBitmap1(),null,rectF1,paint);
- canvas.drawBitmap(createBitmap1(),rect,rectF2,paint);
- //点
- paint.setStyle(Paint.Style.FILL_AND_STROKE);
- paint.setStrokeWidth(5.0f);
- paint.setColor(Color.YELLOW);
- canvas.drawPoints(newfloat[]{120,120,140,140,160,160,180,180},paint);
- //线
- paint.reset();//重置画笔
- paint.setColor(Color.GREEN);
- paint.setAntiAlias(true);
- canvas.drawLine(30,30,130,40,paint);
- paint.setColor(Color.RED);
- canvas.drawLines(newfloat[]{40,40,140,40,50,50,90,90},paint);
- //矩形
- paint.setColor(Color.CYAN);
- canvas.drawRect(10,150,150,250,paint);
- paint.setColor(Color.GRAY);
- canvas.drawRect(newRect(10,260,150,280),paint);
- paint.setColor(Color.DKGRAY);
- canvas.drawRect(newRectF(20.2f,290.9f,120.2f,300.3f),paint);
- //绘制文本
- //paint.setTextSize(20);
- //paint.setColor(0x40ffffff);//半透明白色
- //paint.setTextAlign(Paint.Align.RIGHT);//对齐方向
- //canvas.drawText("CoolAndroid",250,180,paint);//这里注意,坐标(180,180)是文本的左下点坐标
- //画布平移:
- //平移的单位是像素,分别是在x,y轴上平移的像素点
- //正数代表的正方向,x轴为平面的右侧,y轴为平面的下方,相应的,负数则向反方向平移
- //canvas.translate(30.0f,30.0f);
- //画布缩放:
- //参数分别是在想x,y轴上放大或缩小的倍数,大雨1为放大,小于1为缩小,
- //缩放的原点默认为画布的原点(0,0),也可以指定缩放的原点
- //canvas.scale(2.0f,1.5f);
- //canvas.scale(0.5f,0.5f,100.0f,100.0f);//指定坐标(100.0f,100.0f)为缩放原点
- //这里剖析一下第二个缩放方法,其实系统为我们做的事情是这样的
- /*
- scale(floatsx,floatsy,floatpx,floatpy){
- translate(px,py);
- scale(sx,sy);
- translate(-px,-py);
- }
- */
- //画布旋转
- //1.以画布为原点,顺时针旋转40.0f度
- //canvas.rotate(40.0f);
- //2.以(100.11f,100.22f)为原点,顺时针旋转50.0f度
- //canvas.rotate(50.0f,100.11f,100.22f);
- //相应的,为了加深理解,我们再剖析一下第二个旋转方法
- //,其实系统为我们做的事情是这样的
- /*
- rotate(floatdegrees,floatpx,floatpy){
- translate(px,py);
- rotate(degrees);
- translate(-px,-py);
- }
- */
- //画布倾斜
- //skew(floatsx,floatxy);将画布在x及y轴方向上倾斜相应的角度,sx或sy为倾斜角度的tan值,
- //如canvas.skew(1,0);为在x方向上倾斜45度>>tan(45)=1
- //canvas.skew(1,0);
- }
- }
ClipRectDraw.java
- packagecom.view;
- importandroid.content.Context;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.graphics.Path;
- importandroid.graphics.Region;
- importandroid.util.AttributeSet;
- importandroid.view.View;
- /**
- *---------------------------------------------------矩形区域-------------------------------------------------
- *canvas.clipRect(左上角x轴坐标,左上角y轴坐标,右下角x轴坐标,右下角y轴坐标,Region.Op.XOR);
- *最后一个参数有多个选择分别是:
- *//DIFFERENCE是第一次不同于第二次的部分显示出来
- //REPLACE是显示第二次的
- //REVERSE_DIFFERENCE是第二次不同于第一次的部分显示
- //INTERSECT:交集显示
- //UNION:全部显示
- //XOR补集,就是全集的减去交集剩余部分显示
- *@authoremmet1988.iteye.com
- *
- */
- publicclassClipRectDrawextendsView{
- Contextcontext;
- Paintpaint;
- Pathpath;
- publicClipRectDraw(Contextcontext){
- super(context);
- init();
- }
- publicClipRectDraw(Contextcontext,AttributeSetattrs){
- super(context,attrs);
- init();
- }
- publicClipRectDraw(Contextcontext,AttributeSetattrs,intdefStyle){
- super(context,attrs,defStyle);
- init();
- }
- privatevoidinit(){
- paint=newPaint();
- paint.setAntiAlias(true);
- paint.setStrokeWidth(5);
- paint.setTextSize(15);
- paint.setTextAlign(Paint.Align.RIGHT);
- path=newPath();
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- canvas.drawColor(Color.GRAY);
- //左上图
- canvas.save();
- canvas.translate(10,10);
- drawScene(canvas);
- canvas.restore();
- //右上图
- canvas.save();
- canvas.translate(160,10);
- canvas.clipRect(10,10,90,90);
- canvas.clipRect(30,30,70,70,Region.Op.XOR);
- drawScene(canvas);
- canvas.restore();
- //左中图
- canvas.save();
- canvas.translate(10,130);
- path.reset();
- /*抛物曲线*/
- path.cubicTo(0,0,100,0,100,100);
- path.cubicTo(100,100,0,100,0,0);
- canvas.clipPath(path,Region.Op.REPLACE);
- drawScene(canvas);
- canvas.restore();
- //右中图
- canvas.save();
- canvas.translate(160,130);
- canvas.clipRect(0,0,60,60);
- canvas.clipRect(40,40,100,100,Region.Op.UNION);
- drawScene(canvas);
- canvas.restore();
- //左下图
- canvas.save();
- canvas.translate(10,250);
- canvas.clipRect(0,0,60,60);
- canvas.clipRect(40,40,100,100,Region.Op.XOR);
- drawScene(canvas);
- canvas.restore();
- //右下图
- canvas.translate(160,250);
- canvas.clipRect(0,0,60,60);
- canvas.clipRect(40,40,100,100,Region.Op.REVERSE_DIFFERENCE);
- drawScene(canvas);
- canvas.restore();
- }
- privatevoiddrawScene(Canvascanvas){
- canvas.clipRect(0,0,100,100);
- canvas.drawColor(Color.WHITE);
- paint.setColor(Color.RED);
- canvas.drawLine(0,0,100,100,paint);
- paint.setColor(Color.GREEN);
- canvas.drawCircle(30,70,30,paint);
- paint.setColor(Color.BLUE);
- canvas.drawText("ChenJianLi",100,30,paint);
- }
- }
MatrixDraw.java
- packagecom.view;
- importcom.test.R;
- importandroid.content.Context;
- importandroid.graphics.Bitmap;
- importandroid.graphics.Canvas;
- importandroid.graphics.Matrix;
- importandroid.graphics.Paint;
- importandroid.graphics.drawable.BitmapDrawable;
- importandroid.view.View;
- /**
- *在Android里面,Matrix由9个float值构成,是一个3*3的矩阵。
- *cosX,-sinX,translateX
- *sinX,cosX,translateY
- *0,0,scale
- *解释一下,上面的sinX和cosX,表示旋转角度的cos值和sin值,注意,
- *旋转角度是按顺时针方向计算的。translateX和translateY表示x和y的平移量。
- *scale是缩放的比例,1是不变,2是表示缩放1/2,
- *@authoremmet1988.iteye.com
- *
- */
- publicclassMatrixDrawextendsViewimplementsRunnable{
- Bitmapbitmap;
- Matrixmatrix=newMatrix();
- Paintpaint;
- publicMatrixDraw(Contextcontext){
- super(context);
- bitmap=((BitmapDrawable)getResources().getDrawable(R.drawable.rotate_surfaceview)).getBitmap();
- paint=newPaint();
- paint.setAntiAlias(true);
- newThread(this).start();
- }
- floatm;
- floatn;
- @Override
- protectedvoidonDraw(Canvascanvas){
- /*
- floatcosValue=(float)Math.cos(-Math.PI/m);
- floatsinValue=(float)Math.sin(-Math.PI/m);
- Log.d("matrixdraw","Math.PI="+Math.PI);
- Log.d("matrixdraw","Math.PI/m="+Math.PI/m);
- Log.d("matrixdraw","Math.cos(-Math.PI/m)="+(float)Math.cos(-Math.PI/m));
- Log.d("matrixdraw","Math.sin(-Math.PI/m)="+(float)Math.sin(-Math.PI/m));
- matrix.setValues(newfloat[]{
- cosValue,-sinValue,100,
- sinValue,cosValue,100,
- 0,0,2
- });//举例,若缩放值为0.9,代表放大原图的十分之一
- //super.onDraw(canvas);//当然,如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。
- //Matrixmatrix2=newMatrix(matrix);
- canvas.drawBitmap(bitmap,matrix,paint);
- //canvas.drawBitmap(bitmap,matrix2,paint);
- */
- n++;
- if(n==60){
- n=0;
- }
- matrix.postRotate(n);
- matrix.postTranslate(n,n);
- matrix.postScale(1,1,n,n);
- canvas.drawBitmap(bitmap,matrix,paint);
- }
- @Override
- publicvoidrun(){
- while(!Thread.currentThread().isInterrupted()){
- try{
- Thread.sleep(100);
- postInvalidate();
- }catch(InterruptedExceptione){
- Thread.currentThread().interrupt();
- }
- }
- }
- /**
- *以左上角为顶点,缩放一半,逆时针旋转30度,
- *然后沿x轴和y轴分别平移50个像素,
- *代码里面写的是100,为什么是平移50呢,
- *因为缩放了一半。
- *大家可以自己设置一下Matrix的值,或者尝试一下两个
- *Matrix相乘,得到的值设置进去,
- *这样才能对Matrix更加熟练。
- */
- }
Matrix2Draw.java
- publicclassMatrix2DrawextendsView{
- privateBitmapmBitmap;
- privateMatrixmMatrix=newMatrix();
- publicMatrix2Draw(Contextcontext){
- super(context);
- initialize();
- }
- privatevoidinitialize(){
- Bitmapbmp=((BitmapDrawable)getResources().getDrawable(R.drawable.rotate_surfaceview)).getBitmap();
- mBitmap=bmp;
- /*首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/
- bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是float型的,
- 直接用100f就好。*/
- mMatrix.setScale(100f/bmp.getWidth(),100f/bmp.getHeight());
- /*//post方式:后乘>>当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。
- //平移到(100,100)处
- mMatrix.postTranslate(100,100);
- //倾斜x和y轴,以(100,100)为中心。
- mMatrix.postSkew(0.2f,0.2f,100,100);*/
- //pre方式:前乘>>参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。
- //平移到(100,100)处
- mMatrix.preTranslate(100,100);
- //倾斜x和y轴,以(100,100)为中心。
- mMatrix.preSkew(0.2f,0.2f,100,100);
- }
- @OverrideprotectedvoidonDraw(Canvascanvas){
- //super.onDraw(canvas);//如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。
- Paintpaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- canvas.drawBitmap(mBitmap,mMatrix,paint);
- }
- }
- /**
- Matrix的操作:
- 总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在
- Android的API里都提供了set,post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
- set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
- post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。
- pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。
- 旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。
- */
SimpleDraw.java
- packagecom.view;
- importandroid.content.Context;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.graphics.Rect;
- importandroid.view.View;
- publicclassSimpleDrawextendsViewimplementsRunnable{
- /*
- *我们继续来介绍Android平台底层绘图类的相关内容,在AndroidUI开发专题(一)
- *之界面设计中我们介绍了有关Android平台资源使用以及Bitmap相关类的操作
- *,接下来将会以实例的方式给大家演示各种类的用处以及注意点。今天我们继续
- *了解android.graphics包中比较重要的绘图类。
- *
- *一、android.graphics.Matrix有关图形的变换、缩放等相关操作常用的方法有:
- *Java代码:voidreset()//重置一个matrix对象。
- *voidset(Matrixsrc)//复制一个源矩阵,和本类的构造方法Matrix(Matrixsrc)一样
- *booleanisIdentity()//返回这个矩阵是否定义(已经有意义)
- *voidsetRotate(floatdegrees)//指定一个角度以0,0为坐标进行旋转
- *voidsetRotate(floatdegrees,floatpx,floatpy)//指定一个角度以px,py为坐标进行旋转
- *voidsetScale(floatsx,floatsy)//缩放
- *voidsetScale(floatsx,floatsy,floatpx,floatpy)//以坐标px,py进行缩放
- *voidsetTranslate(floatdx,floatdy)//平移
- *voidsetSkew(floatkx,floatky,floatpx,floatpy)//以坐标px,py进行倾斜
- *voidsetSkew(floatkx,floatky)//倾斜复制代码二、android.graphics.NinePatch
- *
- *NinePatch是Android平台特有的一种非矢量图形自然拉伸处理方法,可以帮助常规的
- *图形在拉伸时不会缩放,
- *实例中Android开发网提示大家对于Toast的显示就是该原理,同时SDK中提供了一
- *个工具名为Draw
- *9-Patch,有关该工具的使用方法可以参考我们经发布的Draw
- *9-Patch使用方法介绍一文。由于该类提供了高质量支持透明的缩放方式,所以图形
- *格式为PNG,文件命名方式为.9.png
- *的后缀比如eoeandroid。
- *
- *三、android.graphics.Paint。Paint类我们可以理解为画笔、画刷的属性定义,本类
- *常用的方法如下:
- *
- *Java代码:voidreset()//重置
- *voidsetARGB(inta,intr,intg,intb)或voidsetColor(intcolor)
- *//均为设置Paint对象的颜色
- *voidsetAntiAlias(booleanaa)
- *
- *//是否抗锯齿,需要配合voidsetFlags(Paint.ANTI_ALIAS_FLAG)来帮助消除锯齿
- *使其边缘更平滑。
- *ShadersetShader(Shadershader)
- *
- *//设置阴影,Shader类是一个矩阵对象,如果为NULL将清除阴影。
- *voidsetStyle(Paint.Stylestyle)//设置样式,一般为FILL填充,或者STROKE凹陷
- *效果。
- *voidsetTextSize(floattextSize)//设置字体大小
- *voidsetTextAlign(Paint.Alignalign)//文本对齐方式
- *TypefacesetTypeface(Typefacetypeface)
- *//设置字体,通过Typeface可以加载Android内部的字体,一般为宋体对于中文,
- *部分ROM可以自己添加比如雅黑等等
- *voidsetUnderlineText(booleanunderlineText)
- *
- *//是否设置下划线,需要撇和voidsetFlags(Paint.UNDERLINE_TEXT_FLAG)方法。复制代码
- *四、android.graphics.Rect
- *
- *Rect我们可以理解为矩形区域,类似的还有Point一个点,Rect类除了表示一个矩
- *形区域位置描述外,
- *eoeandroid提示主要可以帮助我们计算图形之间是否碰撞
- *(包含)关系,对于Android游戏开发比较有用,其主要的成员contains包含了三种
- *重载方法,来判断包含关系.
- *
- *Java代码:
- *booleancontains(intleft,inttop,intright,intbottom)
- *booleancontains(intx,inty)
- *
- *booleancontains(Rectr)复制代码五、android.graphics.Region
- *Region在Android平台中表示一个区域和Rect不同的是
- *,它表示的是一个不规则的样子,可以是椭圆、多边形等等,而Rect仅仅是矩形。
- *同样Region的booleancontains(intx,
- *inty)成员可以判断一个点是否在该区域内。
- *
- *六、android.graphics.Typeface
- *Typeface类是帮助描述一个字体对象,在TextView中通过使用setTypeface方法来
- *制定一个输出文本的字体
- *,其直接构造调用成员create方法可以直接指定一个字体名称和样式,比如
- *Java代码:staticTypefacecreate(Typefacefamily,intstyle)
- *
- *staticTypefacecreate(StringfamilyName,intstyle)复制代码
- *同时使用isBold和isItalic方法可以判断出是否包含粗体或斜体的字型。
- *
- *Java代码:finalbooleanisBold()
- *finalbooleanisItalic()复制代码该类的创建方法还有从apk的资源或从一个具体的
- *文件路径,其具体方法为
- *Java代码:staticTypefacecreateFromAsset(AssetManagermgr,Stringpath)
- *staticTypefacecreateFromFile(Filepath)
- *staticTypefacecreateFromFile(Stringpath)复制代码
- */
- privatePaintpaint;
- publicSimpleDraw(Contextcontext){
- super(context);
- paint=newPaint();
- newThread(this).start();
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- canvas.drawColor(Color.GRAY);//
- paint.setAntiAlias(true);//
- canvas.save();//
- canvas.clipRect(10,10,110,110);//
- canvas.drawColor(Color.WHITE);//
- //canvas.rotate(m);//以屏幕左上角为坐标原点旋转
- m+=45.0f;
- if(m==360.0f){
- m=0.0f;
- }
- canvas.rotate(m,60,60);//以(60,60)为原点旋转
- paint.setColor(Color.GREEN);
- canvas.drawRect(newRect(50,50,70,70),paint);
- canvas.restore();
- canvas.save();
- canvas.translate(140,10);
- canvas.clipRect(0,0,100,100);//一定要先剪辑出矩形区域再设画布背景,
- //否则会覆盖整张画布
- canvas.drawColor(Color.BLACK);
- paint.setColor(Color.BLUE);
- canvas.drawRect(newRect(10,10,50,50),paint);
- canvas.restore();
- //
- canvas.save();
- canvas.translate(120,120);
- canvas.clipRect(newRect(0,0,100,100));
- canvas.drawColor(Color.GREEN);
- //paint.setColor(Color.BLUE);
- paint.setStrokeWidth(4);
- paint.setColor(Color.BLACK);
- canvas.drawLine(0,60,100,60,paint);
- paint.setARGB(255,51,51,51);
- paint.setTextSize(20);
- paint.setFlags(Paint.ANTI_ALIAS_FLAG);
- paint.setUnderlineText(true);
- //paint.setFlags(Paint.UNDERLINE_TEXT_FLAG);
- canvas.drawText("陈建立",25,80,paint);
- paint.setColor(Color.WHITE);
- canvas.drawRect(newRect(10,10,50,50),paint);
- canvas.restore();
- }
- floatm=0.0f;
- publicvoidrun(){
- while(!Thread.currentThread().isInterrupted()){
- try{
- Thread.sleep(500);//每半秒执行一次
- }catch(InterruptedExceptione){
- Thread.currentThread().interrupt();
- }
- postInvalidate();
- }
- }
- }
TextDraw.java
- packagecom.view;
- importandroid.content.Context;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.graphics.Paint.FontMetrics;
- importandroid.util.Log;
- importandroid.view.View;
- publicclassTextDrawextendsView{
- publicTextDraw(Contextcontext){
- super(context);
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- PainttextPaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- textPaint.setTextSize(35);
- textPaint.setColor(Color.WHITE);
- //FontMetrics
- FontMetricsfontMetrics=textPaint.getFontMetrics();
- Stringtext="abcdefghijklm";
- //
- floatbaseX=0;
- floatbaseY=100;
- Log.d("textDraw","top="+fontMetrics.top+
- "ascent="+fontMetrics.ascent+
- "descent="+fontMetrics.descent+
- "bottom="+fontMetrics.bottom+"\n");
- floattopY=baseY+fontMetrics.top;
- floatascentY=baseY+fontMetrics.ascent;
- floatdescentY=baseY+fontMetrics.descent;
- floatbottomY=baseY+fontMetrics.bottom;
- Log.d("textDraw","topY="+topY+
- "ascentY="+ascentY+
- "descentY="+descentY+
- "bottomY="+bottomY);
- //
- canvas.drawText(text,baseX,baseY,textPaint);
- //BaseLine
- PaintbaseLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- baseLinePaint.setColor(Color.RED);
- canvas.drawLine(0,baseY,getWidth(),baseY,baseLinePaint);
- //Base
- canvas.drawCircle(baseX,baseY,5,baseLinePaint);
- //TopLine
- PainttopLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- topLinePaint.setColor(Color.LTGRAY);
- canvas.drawLine(0,topY,getWidth(),topY,topLinePaint);
- //AscentLine
- PaintascentLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- ascentLinePaint.setColor(Color.GREEN);
- canvas.drawLine(0,ascentY,getWidth(),ascentY,ascentLinePaint);
- //DescentLine
- PaintdescentLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- descentLinePaint.setColor(Color.YELLOW);
- canvas.drawLine(0,descentY,getWidth(),descentY,descentLinePaint);
- //ButtomLine
- PaintbottomLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- bottomLinePaint.setColor(Color.MAGENTA);
- canvas.drawLine(0,bottomY,getWidth(),bottomY,bottomLinePaint);
- }
- }
RoundAndReflectionDraw.java
- classRoundImageViewextendsView{
- privateBitmapbitmap;
- intbitmapWidth;
- intbitmapHeight;
- publicRoundImageView(Contextcontext){
- super(context);
- bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.rotate_surfaceview);
- bitmapWidth=bitmap.getWidth();
- bitmapHeight=bitmap.getHeight();
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- //第一种方法:
- /*BitmaproundBitmap=Bitmap.createBitmap(bitmapWidth,bitmapHeight,Bitmap.Config.ARGB_8888);
- canvas=newCanvas(roundBitmap);
- Paintpaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- paint.setColor(Color.BLUE);
- canvas.drawRoundRect(newRectF(0,0,bitmapWidth,bitmapHeight),20.0f,20.0f,paint);
- paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_IN));
- canvas.drawBitmap(bitmap,0,0,null);
- canvas.drawBitmap(roundBitmap,0,0,paint);*/
- //第二种方法:
- Paintpaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- paint.setColor(0xffffffff);
- paint.setTextSize(15);
- canvas.drawText("生成带圆角的图片",10,25,paint);
- canvas.drawBitmap(getRoundedCornerBitmap(bitmap),10,30,paint);
- canvas.drawText("生成带倒影的图片",170,160,paint);
- canvas.drawBitmap(createReflectionImageWithOrigin(bitmap),170,165,paint);
- }
- publicBitmapgetRoundedCornerBitmap(Bitmapbitmap){
- //创建一个指定宽度和高度的空位图对象
- Bitmapoutput=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Config.ARGB_8888);
- //用该位图创建画布
- Canvascanvas=newCanvas(output);
- //画笔对象
- finalPaintpaint=newPaint();
- //画笔的颜色
- finalintcolor=0xff424242;
- //矩形区域对象
- finalRectrect=newRect(0,0,bitmap.getWidth(),bitmap.getHeight());
- //未知
- finalRectFrectF=newRectF(rect);
- //拐角的半径
- finalfloatroundPx=12;
- //消除锯齿
- paint.setAntiAlias(true);
- //画布背景色
- canvas.drawARGB(0,0,0,0);
- //设置画笔颜色
- paint.setColor(color);
- //绘制圆角矩形
- canvas.drawRoundRect(rectF,roundPx,roundPx,paint);
- //未知
- paint.setXfermode(newPorterDuffXfermode(Mode.SRC_IN));
- //把该图片绘制在该圆角矩形区域中
- canvas.drawBitmap(bitmap,rect,rect,paint);
- //最终在画布上呈现的就是该圆角矩形图片,然后我们返回该Bitmap对象
- returnoutput;
- }
- //获得带倒影的图片方法
- publicBitmapcreateReflectionImageWithOrigin(Bitmapbitmap){
- //图片与倒影之间的距离间隔
- finalintreflectionGap=2;
- //原图的宽度
- intwidth=bitmap.getWidth();
- //原图的高度
- intheight=bitmap.getHeight();
- //图片旋转,缩放等控制对象
- Matrixmatrix=newMatrix();
- //缩放(这里pre,set,post三种效果是不一样的,注意区别)
- matrix.preScale(1,-1);
- /**
- set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
- post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,
- 来完成所需的整个变换。例如,要将一个图片旋
- 转30度,然后平移到(100,100)的地方,那么可以这样做:
- Matrixm=newMatrix();
- m.postRotate(30);
- m.postTranslate(100,100);
- 这样就达到了想要的效果。
- pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。
- 例如上面的例子,如果用pre的话,就要这样:
- Matrixm=newMatrix();
- m.setTranslate(100,100);
- m.preRotate(30);
- 旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,
- 是围绕(0,0)点来进行。
- 关于缩放:
- scale的参数是比例。例如,我们缩放为100%,则有一点要注意,如果直接用
- 100/bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是
- float型的,直接用100f就好。
- 如:matrix.setScale(100f/bmp.getWidth(),100f/bmp.getHeight());
- */
- //创建一个初始的倒影位图
- BitmapreflectionImage=Bitmap.createBitmap(bitmap,0,height/2,width,height/2,matrix,false);
- //新建一个宽度为原图宽度,高度为原图高度的3/2的位图,用于绘制新的位图,即整体的效果图位图对象
- BitmapbitmapWithReflection=Bitmap.createBitmap(width,(height+height/2),Config.ARGB_8888);
- //由该位图对象创建初始画布(规定了画布的宽高)
- Canvascanvas=newCanvas(bitmapWithReflection);
- //在该画布上绘制原图
- canvas.drawBitmap(bitmap,0,0,null);
- //创建一个画笔
- PaintdeafalutPaint=newPaint();
- //绘制一个矩形区域,该矩形区域便是原图和倒影图之间的间隔图
- canvas.drawRect(0,height,width,height+reflectionGap,deafalutPaint);
- //绘制该倒影图于间隔图的下方
- canvas.drawBitmap(reflectionImage,0,height+reflectionGap,null);
- //创建一个画笔
- Paintpaint=newPaint();
- //创建一个线性渐变对象
- LinearGradientshader=newLinearGradient(
- 0,bitmap.getHeight(),
- 0,bitmapWithReflection.getHeight()+reflectionGap,
- 0x70ffffff,0x00ffffff,
- TileMode.CLAMP
- );
- //把渐变效果应用在画笔上
- paint.setShader(shader);
- //SettheTransfermodetobeporterduffanddestinationin
- //未知
- paint.setXfermode(newPorterDuffXfermode(Mode.DST_IN));
- //Drawarectangleusingthepaintwithourlineargradient
- //绘制出该渐变效果,也就是最终的倒影效果图
- canvas.drawRect(0,height,width,bitmapWithReflection.getHeight()+reflectionGap,paint);
- //返回
- returnbitmapWithReflection;
- }
- }
- /**
- *绘制圆角背景以及图片圆角的处理
- .配置文件实现
- <?xmlversion="1.0"encoding="utf-8"?>
- <layer-list
- *xmlns:android="http://schemas.android.com/apk/res/android"><item
- *android:drawable="@drawable/icon_home_button_img"/><item
- *android:drawable="@drawable/icon_home_shape_overlay"/>
- *</layer-list>
- *icon_home_shape_overlay如下
- *<?xmlversion="1.0"encoding="utf-8"?>
- *<shape
- *xmlns:android="http://schemas.android.com/apk/res/android"><solid
- *android:color="#60000000"/>
- *<strokeandroid:width="3dp"
- *color="#ff000000"/>
- *<cornersandroid:radius="10dp"/>
- *</shape>
- *或者直接使用一种效果
- *<?xmlversion="1.0"encoding="UTF-8"?>
- *<shape
- *xmlns:android="http://schemas.android.com/apk/res/android">
- *<solid
- *android:color="#99FFFFFF"/>
- *<cornersandroid:radius="30px"/>
- *<padding
- *android:left="0dp"android:top="0dp"android:right="0dp"
- *android:bottom="0dp"/>
- *</shape>
- *然后
- *android:background="@drawable/my_shape_file"
- *
- *
- *2.图片本身加上圆角BitmapmyCoolBitmap=...;//<--Yourbitmapyouwantrounded
- *
- *intw=myCoolBitmap.getWidth(),h=myCoolBitmap.getHeight();
- *Bitmaprounder=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);Canvas
- *canvas=newCanvas(rounder);
- *
- *PaintxferPaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- *xferPaint.setColor(Color.RED);
- *
- *canvas.drawRoundRect(newRectF(0,0,w,h),20.0f,20.0f,xferPaint);
- *
- *xferPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_IN));
- *canvas.drawBitmap(myCoolBitmap,0,0,null);
- *canvas.drawBitmap(rounder,0,0,xferPaint);
- *或者
- *publicstaticBitmapgetRoundedCornerBitmap(Bitmapbitmap){
- *Bitmapoutput=Bitmap.createBitmap(bitmap.getWidth(),
- *bitmap.getHeight(),Config.ARGB_8888);
- *Canvascanvas=newCanvas(output);
- *
- *finalintcolor=0xff424242;finalPaintpaint=newPaint();finalRect
- *rect=newRect(0,0,bitmap.getWidth(),bitmap.getHeight());finalRectF
- *rectF=newRectF(rect);finalfloatroundPx=12;
- *
- *paint.setAntiAlias(true);canvas.drawARGB(0,0,0,0);
- *paint.setColor(color);canvas.drawRoundRect(rectF,roundPx,roundPx,paint);
- *
- *paint.setXfermode(newPorterDuffXfermode(Mode.SRC_IN));
- *canvas.drawBitmap(bitmap,rect,rect,paint);
- *
- *returnoutput;
- *}
- */
SurfaceViewDraw.java
- packagecom.view;
- importcom.test.R;
- importandroid.content.Context;
- importandroid.graphics.Bitmap;
- importandroid.graphics.BitmapFactory;
- importandroid.graphics.Canvas;
- importandroid.graphics.Matrix;
- importandroid.graphics.Paint;
- importandroid.graphics.Rect;
- importandroid.util.Log;
- importandroid.view.SurfaceHolder;
- importandroid.view.SurfaceView;
- /**
- *http://wallage.blog.163.com/blog/static/173896242010101232220959/
- *@authoremmet1988.iteye.com
- *
- */
- publicclassSurfaceViewDrawextendsSurfaceViewimplementsRunnable,SurfaceHolder.Callback{
- privateBitmapbackgroundBitmap;
- privateBitmaprotateBitmap;
- SurfaceHoldersurfaceHolder;
- publicSurfaceViewDraw(Contextcontext){
- super(context);
- backgroundBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.background_surfaceview);
- rotateBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.rotate_surfaceview);
- surfaceHolder=this.getHolder();
- surfaceHolder.addCallback(this);
- }
- publicvoidsurfaceCreated(SurfaceHolderholder){
- newThread(this).start();
- Log.d("surfaceview","surfaceCreated");
- }
- publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
- intheight){
- Log.d("surfaceview","surfaceChanged");
- }
- publicvoidsurfaceDestroyed(SurfaceHolderholder){
- Log.d("surfaceview","surfaceDestroyed");
- }
- @Override
- publicvoidrun(){
- Log.d("surfaceview","run");
- Canvascanvas=null;
- introtateValue=0;//旋转角度
- intframeCount=0;//帧计数器
- while(!Thread.currentThread().isInterrupted()){
- try{
- //canvas=surfaceHolder.lockCanvas();//获取画布对象(获取整个屏幕的画布)
- canvas=surfaceHolder.lockCanvas(newRect(10,10,240,250));//获取某个区域的画布
- Paintpaint=newPaint();
- Log.d("surfaceview","rotateValue"+rotateValue+"|frameCount"+frameCount);
- if(frameCount++<2){//仅在第一次绘制时绘制背景
- /*
- *这里为什么设置成<2,而不是1,是由于SurfaceView本身的双缓冲技术。
- 覆盖刷新其实就是将每次的新的图形绘制到上一帧去,
- 所以如果图像是半透明的,就要考虑重复叠加导致的问题了,
- 而如果是完全不透明的图形则不会有任何问题。
- 背景会在背景图和黑色背景之间来回闪。
- 这个问题其实是源于SurfaceView的双缓冲机制,我理解就是它会缓冲
- 前两帧的图像交替传递给后面的帧用作覆盖,这样由于我们仅在第一帧
- 绘制了背景,第二帧就是无背景状态了,且通过双缓冲机制一直保持下
- 来,解决办法就是改为在前两帧都进行背景绘制。
- */
- canvas.drawBitmap(backgroundBitmap,0,0,paint);//绘制背景
- }
- //创建矩阵以控制图片的旋转和平移
- Matrixmatrix=newMatrix();
- rotateValue+=40;
- matrix.setRotate(rotateValue,rotateBitmap.getWidth()/2,rotateBitmap.getHeight()/2);
- //matrix.postRotate(rotateValue,rotateBitmap.getWidth()/2,rotateBitmap.getHeight()/2);
- //matrix.setTranslate(100,rotateValue);
- if(rotateValue==360){
- rotateValue=0;
- }
- matrix.setTranslate(80,50);//设置左边距和上边距
- //绘制问号
- Log.d("surfaceview","canvas"+canvas);
- Log.d("surfaceview","rotateBitmap"+rotateBitmap);
- Log.d("surfaceview","matrix"+matrix);
- Log.d("surfaceview","paint"+paint);
- if(canvas!=null){
- canvas.drawBitmap(rotateBitmap,matrix,paint);
- //解锁画布,提交画好的图像
- surfaceHolder.unlockCanvasAndPost(canvas);
- }
- Thread.sleep(30);
- }catch(InterruptedExceptione){
- Thread.currentThread().interrupt();
- Log.d("surfaceview","InterruptedException");
- }finally{
- Log.d("surfaceview","finally");
- }
- }
- }
- }