- 浏览: 403823 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
ysn003:
这样用就好啦!!!<Button ...
Android学习 之 ColorStateList按钮文字变色 -
ysn003:
Android学习 之 ColorStateList按钮文字变色 -
vitoliao:
楼主你好,如果你的代码需要实现的是回显功能,需要在MainCl ...
Java学习 之 Socket(实现简易的C/S聊天室) -
xinqiqi123:
在item布局中要是引用到自定的东西,item就会显示不全
Android学习 之 问题&解答 ScrollView中嵌套ListView时显示不全的简便解决方案 -
CTXsamCTX:
很好,学习了。
Android 图形用户界面 之 绘图(一)
直接贴上代码:
BasicViewDraw.java
package com.view; import com.test.R; import android.view.View; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Path; import android.graphics.Shader; import android.graphics.LinearGradient; /* 自定义继承View 的MyView*/ public class BasicViewDraw extends View { public BasicViewDraw(Context context) { super(context); } /* 重写onDraw() */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /* 设置背景为白色 */ canvas.drawColor(Color.WHITE); Paint paint = new Paint(); /* 去锯齿 */ 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); /* 画一个空心椭圆形 */ RectF re = new RectF(10, 220, 70, 250); canvas.drawOval(re, paint); /* 画一个空心三角形 */ Path path = new Path(); path.moveTo(10, 330); path.lineTo(70, 330); path.lineTo(40, 270); path.close();//记得要close canvas.drawPath(path, paint); /* 画一个空心梯形 */ Path path1 = new Path(); 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); /* 画一个实心椭圆 */ RectF re2 = new RectF(90, 220, 150, 250); canvas.drawOval(re2, paint); /* 画一个实心三角形 */ Path path2 = new Path(); path2.moveTo(90, 330); path2.lineTo(150, 330); path2.lineTo(120, 270); path2.close(); canvas.drawPath(path2, paint); /* 画一个实心梯形 */ Path path3 = new Path(); path3.moveTo(90, 410); path3.lineTo(150, 410); path3.lineTo(135, 350); path3.lineTo(105, 350); path3.close(); canvas.drawPath(path3, paint); /* 设置渐变色 */ Shader mShader = new LinearGradient(0, 0, 100, 100, new int[] { 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); /* 画一个渐变色椭圆 */ RectF re3 = new RectF(170, 220, 230, 250); canvas.drawOval(re3, paint); /* 画一个渐变色三角形 */ Path path4 = new Path(); path4.moveTo(170, 330); path4.lineTo(230, 330); path4.lineTo(200, 270); path4.close(); canvas.drawPath(path4, paint); /* 画一个渐变色梯形 */ Path path5 = new Path(); 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
class BasicView2Draw extends View{ Paint paint; Bitmap bitmap; public BasicView2Draw(Context context) { super(context); paint = new Paint(Paint.ANTI_ALIAS_FLAG); bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); } private Bitmap createBitmap1(){ Bitmap bitmap1 = Bitmap.createBitmap(100, 100, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap1); canvas.drawColor(Color.BLUE); // canvas.drawARGB(0, 0, 0, 0);// 透明色 canvas.drawBitmap(bitmap, 0, 0, paint); canvas.drawText("Hello Android", 25, 55, paint); return bitmap1; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制位图 // 1.绘制位图在(10,10)位置上 canvas.drawBitmap(createBitmap1(), 10, 10, paint); // 2. canvas.drawBitmap(Bitmap bitmap,Rect src,Rect dest,Paint paint); // canvas.drawBitmap(Bitmap bitmap,Rect src,RectF dest,Paint paint); // 绘制位图到一个指定的矩形dest中,位图会自动进行平移和缩放等操作,如果src的参数不为null // 则会裁剪位图的部分区域来进行绘制 Rect rect = new Rect(10, 10, 50, 60); RectF rectF1 = new RectF(180.0f, 20.0f, 240.0f, 80.0f); RectF rectF2 = new RectF(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(new float[]{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(new float[]{ 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(new Rect(10, 260, 150, 280), paint); paint.setColor(Color.DKGRAY); canvas.drawRect(new RectF(20.2f, 290.9f, 120.2f, 300.3f), paint); // 绘制文本 // paint.setTextSize(20); // paint.setColor(0x40ffffff);// 半透明白色 // paint.setTextAlign(Paint.Align.RIGHT);// 对齐方向 // canvas.drawText("Cool Android", 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(float sx, float sy, float px, float py){ 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(float degrees, float px, float py){ translate(px,py); rotate(degrees); translate(-px,-py); } */ // 画布倾斜 // skew(float sx,float xy);将画布在x及y轴方向上倾斜相应的角度,sx或sy为倾斜角度的tan值, // 如canvas.skew(1,0);为在x方向上倾斜45度 >> tan(45) = 1 // canvas.skew(1,0); } }
ClipRectDraw.java
package com.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Region; import android.util.AttributeSet; import android.view.View; /** * ---------------------------------------------------矩形区域------------------------------------------------- * canvas.clipRect(左上角x轴坐标, 左上角y轴坐标, 右下角x轴坐标, 右下角y轴坐标, Region.Op.XOR); * 最后一个参数有多个选择分别是: * //DIFFERENCE是第一次不同于第二次的部分显示出来 //REPLACE是显示第二次的 //REVERSE_DIFFERENCE 是第二次不同于第一次的部分显示 //INTERSECT:交集显示 //UNION:全部显示 //XOR补集,就是全集的减去交集剩余部分显示 * @author emmet1988.iteye.com * */ public class ClipRectDraw extends View { Context context; Paint paint; Path path; public ClipRectDraw(Context context) { super(context); init(); } public ClipRectDraw(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ClipRectDraw(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init(){ paint = new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(5); paint.setTextSize(15); paint.setTextAlign(Paint.Align.RIGHT); path = new Path(); } @Override protected void onDraw(Canvas canvas) { 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(); } private void drawScene(Canvas canvas){ 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
package com.view; import com.test.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.drawable.BitmapDrawable; import android.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 , * @author emmet1988.iteye.com * */ public class MatrixDraw extends View implements Runnable{ Bitmap bitmap; Matrix matrix = new Matrix(); Paint paint; public MatrixDraw(Context context) { super(context); bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.rotate_surfaceview)).getBitmap(); paint = new Paint(); paint.setAntiAlias(true); new Thread(this).start(); } float m; float n; @Override protected void onDraw(Canvas canvas) { /* float cosValue = (float)Math.cos(-Math.PI/m); float sinValue = (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(new float[]{ cosValue,-sinValue,100, sinValue,cosValue,100, 0, 0, 2 });//举例,若缩放值为0.9,代表放大原图的十分之一 // super.onDraw(canvas);//当然,如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。 // Matrix matrix2 = new Matrix(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 public void run() { while(!Thread.currentThread().isInterrupted()){ try { Thread.sleep(100); postInvalidate(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } /** * 以左上角为顶点,缩放一半,逆时针旋转30度, * 然后沿x轴和y轴分别平移50个像素, * 代码 里面写的是100,为什么是平移50呢, * 因为缩放了一半。 * 大家可以自己设置一下Matrix的值,或者尝试一下两个 * Matrix相乘,得到的值设置进去, * 这样才能对Matrix更加熟练。 */ }
Matrix2Draw.java
public class Matrix2Draw extends View { private Bitmap mBitmap; private Matrix mMatrix = new Matrix(); public Matrix2Draw(Context context) { super(context); initialize(); } private void initialize() { Bitmap bmp = ((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); } @Override protected void onDraw(Canvas canvas) { // super.onDraw(canvas); //如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。 Paint paint = new Paint(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
package com.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.view.View; public class SimpleDraw extends View implements Runnable { /* * 我们继续来介绍Android平台底层绘图类的相关内容,在Android UI开发专题(一) * 之界面设计中我们介绍了有关Android平台资源使用以及Bitmap相关类的操作 * ,接下来将会以实例的方式给大家演示各种类的用处以及注意点。今天我们继续 * 了解android.graphics包中比较重要的绘图类。 * * 一、 android.graphics.Matrix有关图形的变换、缩放等相关操作常用的方法有: * Java代码: void reset() // 重置一个matrix对象。 * void set(Matrix src) //复制一个源矩阵,和本类的构造方法 Matrix(Matrix src) 一样 * boolean isIdentity() //返回这个矩阵是否定义(已经有意义) * void setRotate(float degrees) //指定一个角度以0,0为坐标进行旋转 * void setRotate(float degrees, float px, float py) //指定一个角度以px,py为坐标进行旋转 * void setScale(float sx, float sy) // 缩放 * void setScale(float sx, float sy, float px, float py) //以坐标px,py进行缩放 * void setTranslate(float dx, float dy) //平移 * void setSkew (float kx, float ky, float px, float py) //以坐标px,py进行倾斜 * void setSkew (float kx, float ky) //倾斜 复制代码 二、android.graphics.NinePatch * * NinePatch是Android平台特有的一种非矢量图形自然拉伸处理方法,可以帮助常规的 * 图形在拉伸时不会缩放, * 实例中Android开发网提示大家对于Toast的显示就是该原理,同时SDK中提供了一 * 个工具名为Draw * 9-Patch,有关该工具的使用方法可以参考我们经发布的 Draw * 9-Patch使用方法介绍一文。由于该类提供了高质量支持透明的缩放方式,所以图形 * 格式为PNG,文件命名方式为.9.png * 的后缀比如eoeandroid。 * * 三、android.graphics.Paint。Paint类我们可以理解为画笔、画刷的属性定义,本类 * 常用的方法如下: * * Java代码: void reset() //重置 * void setARGB(int a, int r, int g, int b) 或 void setColor(int color) * //均为设置Paint对象的颜色 * void setAntiAlias(boolean aa) * * //是否抗锯齿,需要配合void setFlags (Paint.ANTI_ALIAS_FLAG) 来帮助消除锯齿 * 使其边缘更平滑。 * Shader setShader(Shader shader) * * //设置阴影,Shader类是一个矩阵对象,如果为NULL将清除阴影。 * void setStyle(Paint.Style style) //设置样式,一般为 FILL 填充,或者STROKE凹陷 * 效果。 * void setTextSize(float textSize) //设置字体大小 * void setTextAlign(Paint.Align align) //文本对齐方式 * Typeface setTypeface(Typeface typeface) * //设置字体,通过Typeface可以加载Android内部的字体,一般为宋体对于中文, * 部分ROM可以自己添加比如雅黑等等 * void setUnderlineText(boolean underlineText) * * //是否设置下划线,需要撇和void setFlags (Paint.UNDERLINE_TEXT_FLAG) 方法。 复制代码 * 四、android.graphics.Rect * * Rect我们可以理解为矩形区域,类似的还有Point一个点,Rect类除了表示一个矩 * 形区域位置描述外, * eoeandroid提示主要可以帮助我们计算图形之间是否碰撞 * (包含)关系,对于Android游戏开发比较有用,其主要的成员contains包含了三种 * 重载方法,来判断包含关系. * * Java代码: * boolean contains(int left, int top, int right, int bottom) * boolean contains(int x, int y) * * boolean contains(Rect r) 复制代码 五、android.graphics.Region * Region在Android平台中表示一个区域和Rect不同的是 * ,它表示的是一个不规则的样子,可以是椭圆、多边形等等,而Rect仅仅是矩形。 * 同样Region的boolean contains(int x, * int y) 成员可以判断一个点是否在该区域内。 * * 六、android.graphics.Typeface * Typeface类是帮助描述一个字体对象,在TextView中通过使用setTypeface方法来 * 制定一个输出文本的字体 * ,其直接构造调用成员create方法可以直接指定一个字体名称和样式,比如 * Java代码: static Typeface create(Typeface family, int style) * * static Typeface create(String familyName, int style) 复制代码 * 同时使用isBold和isItalic方法可以判断出是否包含粗体或斜体的字型。 * * Java代码: final boolean isBold() * final boolean isItalic() 复制代码 该类的创建方法还有从apk的资源或从一个具体的 * 文件路径,其具体方法为 * Java代码: static Typeface createFromAsset(AssetManager mgr, String path) * static Typeface createFromFile(File path) * static Typeface createFromFile(String path) 复制代码 */ private Paint paint; public SimpleDraw(Context context) { super(context); paint = new Paint(); new Thread(this).start(); } @Override protected void onDraw(Canvas canvas) { 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(new Rect(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(new Rect(10, 10, 50, 50), paint); canvas.restore(); // canvas.save(); canvas.translate(120, 120); canvas.clipRect(new Rect(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(new Rect(10, 10, 50, 50), paint); canvas.restore(); } float m = 0.0f; public void run() { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(500);// 每半秒执行一次 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } postInvalidate(); } } }
TextDraw.java
package com.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.util.Log; import android.view.View; public class TextDraw extends View { public TextDraw(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint textPaint = new Paint( Paint.ANTI_ALIAS_FLAG); textPaint.setTextSize( 35); textPaint.setColor( Color.WHITE); // FontMetrics FontMetrics fontMetrics = textPaint.getFontMetrics(); String text = "abcdefghijklm"; // float baseX = 0; float baseY = 100; Log.d("textDraw", "top = "+fontMetrics.top+ "ascent = "+fontMetrics.ascent+ "descent = "+fontMetrics.descent+ "bottom = "+fontMetrics.bottom+"\n"); float topY = baseY + fontMetrics.top; float ascentY = baseY + fontMetrics.ascent; float descentY = baseY + fontMetrics.descent; float bottomY = baseY + fontMetrics.bottom; Log.d("textDraw", "topY = "+topY+ "ascentY = "+ascentY+ "descentY = "+descentY+ "bottomY = "+bottomY); // canvas.drawText( text, baseX, baseY, textPaint); // BaseLine Paint baseLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG); baseLinePaint.setColor( Color.RED); canvas.drawLine(0, baseY, getWidth(), baseY, baseLinePaint); // Base canvas.drawCircle( baseX, baseY, 5, baseLinePaint); // TopLine Paint topLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG); topLinePaint.setColor( Color.LTGRAY); canvas.drawLine(0, topY, getWidth(), topY, topLinePaint); // AscentLine Paint ascentLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG); ascentLinePaint.setColor( Color.GREEN); canvas.drawLine(0, ascentY, getWidth(), ascentY, ascentLinePaint); // DescentLine Paint descentLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG); descentLinePaint.setColor( Color.YELLOW); canvas.drawLine(0, descentY, getWidth(), descentY, descentLinePaint); // ButtomLine Paint bottomLinePaint = new Paint( Paint.ANTI_ALIAS_FLAG); bottomLinePaint.setColor( Color.MAGENTA); canvas.drawLine(0, bottomY, getWidth(), bottomY, bottomLinePaint); } }
RoundAndReflectionDraw.java
class RoundImageView extends View { private Bitmap bitmap; int bitmapWidth; int bitmapHeight; public RoundImageView(Context context) { super(context); bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.rotate_surfaceview); bitmapWidth = bitmap.getWidth(); bitmapHeight = bitmap.getHeight(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 第一种方法: /*Bitmap roundBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight,Bitmap.Config.ARGB_8888); canvas = new Canvas(roundBitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLUE); canvas.drawRoundRect(new RectF(0, 0, bitmapWidth, bitmapHeight),20.0f, 20.0f, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawBitmap(bitmap, 0, 0, null); canvas.drawBitmap(roundBitmap, 0, 0, paint);*/ // 第二种方法: Paint paint = new Paint(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); } public Bitmap getRoundedCornerBitmap(Bitmap bitmap) { // 创建一个指定宽度和高度的空位图对象 Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888); // 用该位图创建画布 Canvas canvas = new Canvas(output); // 画笔对象 final Paint paint = new Paint(); // 画笔的颜色 final int color = 0xff424242; // 矩形区域对象 final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); // 未知 final RectF rectF = new RectF(rect); // 拐角的半径 final float roundPx = 12; // 消除锯齿 paint.setAntiAlias(true); // 画布背景色 canvas.drawARGB(0, 0, 0, 0); // 设置画笔颜色 paint.setColor(color); // 绘制圆角矩形 canvas.drawRoundRect(rectF, roundPx, roundPx,paint); // 未知 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); // 把该图片绘制在该圆角矩形区域中 canvas.drawBitmap(bitmap, rect, rect, paint); // 最终在画布上呈现的就是该圆角矩形图片,然后我们返回该Bitmap对象 return output; } //获得带倒影的图片方法 public Bitmap createReflectionImageWithOrigin(Bitmap bitmap){ // 图片与倒影之间的距离间隔 final int reflectionGap = 2; // 原图的宽度 int width = bitmap.getWidth(); // 原图的高度 int height = bitmap.getHeight(); // 图片旋转,缩放等控制对象 Matrix matrix = new Matrix(); // 缩放(这里pre,set,post三种效果是不一样的,注意区别) matrix.preScale(1, -1); /** set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。 post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post, 来完成所需的整个变换。例如,要将一个图片旋 转30度,然后平移到(100,100)的地方,那么可以这样做: Matrix m = new Matrix(); m.postRotate(30); m.postTranslate(100, 100); 这样就达到了想要的效果。 pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。 例如上面的例子,如果用pre的话,就要这样: Matrix m = new Matrix(); 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()); */ // 创建一个初始的倒影位图 Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height/2, width, height/2, matrix, false); // 新建一个宽度为原图宽度,高度为原图高度的3/2的位图,用于绘制新的位图,即整体的效果图位图对象 Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2), Config.ARGB_8888); // 由该位图对象创建初始画布(规定了画布的宽高) Canvas canvas = new Canvas(bitmapWithReflection); // 在该画布上绘制原图 canvas.drawBitmap(bitmap, 0, 0, null); // 创建一个画笔 Paint deafalutPaint = new Paint(); // 绘制一个矩形区域,该矩形区域便是原图和倒影图之间的间隔图 canvas.drawRect(0, height,width,height + reflectionGap,deafalutPaint); // 绘制该倒影图于间隔图的下方 canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); // 创建一个画笔 Paint paint = new Paint(); // 创建一个线性渐变对象 LinearGradient shader = new LinearGradient( 0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP ); // 把渐变效果应用在画笔上 paint.setShader(shader); // Set the Transfer mode to be porter duff and destination in // 未知 paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); // Draw a rectangle using the paint with our linear gradient // 绘制出该渐变效果,也就是最终的倒影效果图 canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); // 返回 return bitmapWithReflection; } } /** * 绘制圆角背景以及图片圆角的处理 .配置文件实现 <?xml version="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如下 * <?xml version="1.0" encoding="utf-8"?> * <shape * xmlns:android="http://schemas.android.com/apk/res/android"> <solid * android:color="#60000000"/> * <stroke android:width="3dp" * color="#ff000000"/> * <corners android:radius="10dp" /> * </shape> * 或者直接使用一种效果 * <?xml version="1.0" encoding="UTF-8"?> * <shape * xmlns:android="http://schemas.android.com/apk/res/android"> * <solid * android:color="#99FFFFFF"/> * <corners android:radius="30px"/> * <padding * android:left="0dp" android:top="0dp" android:right="0dp" * android:bottom="0dp" /> * </shape> * 然后 * android:background="@drawable/my_shape_file" * * * 2.图片本身加上圆角 Bitmap myCoolBitmap = ... ; // <-- Your bitmap you want rounded * * int w = myCoolBitmap.getWidth(), h = myCoolBitmap.getHeight(); * Bitmap rounder = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888); Canvas * canvas = new Canvas(rounder); * * Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG); * xferPaint.setColor(Color.RED); * * canvas.drawRoundRect(new RectF(0,0,w,h), 20.0f, 20.0f, xferPaint); * * xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); * canvas.drawBitmap(myCoolBitmap, 0,0, null); * canvas.drawBitmap(rounder, 0,0, xferPaint); * 或者 * public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) { * Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), * bitmap.getHeight(), Config.ARGB_8888); * Canvas canvas = newCanvas(output); * * final int color = 0xff424242; final Paint paint = new Paint(); final Rect * rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF * rectF = new RectF(rect); final float roundPx = 12; * * paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); * paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx,paint); * * paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); * canvas.drawBitmap(bitmap, rect, rect, paint); * * return output; * } */
SurfaceViewDraw.java
package com.view; import com.test.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * http://wallage.blog.163.com/blog/static/173896242010101232220959/ * @author emmet1988.iteye.com * */ public class SurfaceViewDraw extends SurfaceView implements Runnable,SurfaceHolder.Callback { private Bitmap backgroundBitmap; private Bitmap rotateBitmap; SurfaceHolder surfaceHolder; public SurfaceViewDraw(Context context) { super(context); backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_surfaceview); rotateBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rotate_surfaceview); surfaceHolder = this.getHolder(); surfaceHolder.addCallback(this); } public void surfaceCreated(SurfaceHolder holder) { new Thread(this).start(); Log.d("surfaceview", "surfaceCreated"); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d("surfaceview", "surfaceChanged"); } public void surfaceDestroyed(SurfaceHolder holder) { Log.d("surfaceview", "surfaceDestroyed"); } @Override public void run() { Log.d("surfaceview", "run"); Canvas canvas = null; int rotateValue = 0;//旋转角度 int frameCount = 0;//帧计数器 while (!Thread.currentThread().isInterrupted()) { try { // canvas = surfaceHolder.lockCanvas();//获取画布对象(获取整个屏幕的画布) canvas = surfaceHolder.lockCanvas(new Rect(10, 10, 240, 250));//获取某个区域的画布 Paint paint = new Paint(); Log.d("surfaceview", "rotateValue " +rotateValue+"|frameCount "+frameCount); if (frameCount++ < 2) {//仅在第一次绘制时绘制背景 /* * 这里为什么设置成<2,而不是1,是由于SurfaceView本身的双缓冲技术。 覆盖刷新其实就是将每次的新的图形绘制到上一帧去, 所以如果图像是半透明的,就要考虑重复叠加导致的问题了, 而如果是完全不透明的图形则不会有任何问题。 背景会在背景图和黑色背景之间来回闪。 这个问题其实是源于SurfaceView的双缓冲机制,我理解就是它会缓冲 前两帧的图像交替传递给后面的帧用作覆盖,这样由于我们仅在第一帧 绘制了背景,第二帧就是无背景状态了,且通过双缓冲机制一直保持下 来,解决办法就是改为在前两帧都进行背景绘制。 */ canvas.drawBitmap(backgroundBitmap, 0, 0, paint);//绘制背景 } //创建矩阵以控制图片的旋转和平移 Matrix matrix = new Matrix(); 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 (InterruptedException e) { Thread.currentThread().interrupt(); Log.d("surfaceview", "InterruptedException"); } finally { Log.d("surfaceview", "finally"); } } } }
评论
6 楼
CTXsamCTX
2014-09-20
很好,学习了。
5 楼
梦林忆雨
2012-03-30
谢谢,学习了啊!
4 楼
力争向日葵
2012-02-24
谢谢呀!很好的学下了
3 楼
ldci3gandroid
2011-09-28
不夜的星辰 写道
请问下你这种版述效果如何设置?
不好意思啊,没明白你说的是什么意思?
2 楼
不夜的星辰
2011-09-21
请问下你这种版述效果如何设置?
1 楼
JACKDG2010
2011-07-20
发表评论
-
Android 学习 之 使用ActivityGroup调用对应Activity的菜单
2011-12-23 17:34 2615代码很简单,直接贴在这里了。 在使用ActivityGrou ... -
Android 学习 之 TextView结合SpannableString
2011-12-22 12:02 5430protected void onCreate(Bundle ... -
Android 学习 之 图形绘制篇 获取要绘制的文字的宽度/长度
2011-11-29 15:43 7383转自:http://www.cnblogs.com/Tiger ... -
Android 学习 之 键盘问题
2011-10-12 12:00 45151.隐藏键盘 一般情况下,都是在点击某个View的时候 ... -
Android 学习 之 SD卡相关
2011-08-19 15:42 13011.获取SD的路径字符串 public static Str ... -
Android 学习 之 关于应用程序的自适应问题(一)
2011-08-16 12:18 1615转自:http://venus-chen.iteye.com/ ... -
Android 学习 之 资源文件 布局中ID的引用
2011-08-16 11:30 5983转自:http://tiantian0521.blog.163 ... -
Android 学习 之 关闭应用程序的方法
2011-08-10 11:46 1406package com.close; import jav ... -
Android 学习 之 资源文件 动态修改strings.xml中的字符资源
2011-08-10 11:25 6500转自:http://www.cnblogs.com/cools ... -
Android 学习 之 Intent 调用大全
2011-08-10 11:21 1030从别人那里抠的,代码有点乱,仅供自己参考,需要的自己整理下吧, ... -
Android学习 之 动态切换全屏和非全屏模式
2011-06-02 10:03 4409直接贴出代码: package com.screen; ... -
Android学习 之 常见知识点记录
2011-06-01 20:35 1854也是转的,呜呜,人家写的好好,有记录的习惯,值得学习,转载请说 ... -
Android学习 之 获取可视区域的Rect对象(顺带获取状态栏和标题栏高度的方法)
2011-06-01 11:31 10875这个有什么用捏,这 ... -
Android 基本控件 之 Dialog(二)Dialog主题的Activity
2011-06-01 10:10 2690转自:http://www.cnblogs.com/xi ... -
Android 基本控件 之 SeekBar(一) 个性你的视图
2011-05-31 16:34 12148系统自带的SeekBar组件 ... -
Android 系统设置 之 保持手机屏幕常亮的方法
2011-05-25 18:13 9784方法一: 在Activity的onCreate()中: ... -
Android 图形用户界面 之 绘图(二) Paint类 主要方法介绍
2011-05-25 18:09 9258摘自《Ophone应用开发权威指南》: /** * P ... -
【转】Android 画图 之 Matrix(三)
2011-05-24 19:04 1645原文地址:http://developer.51cto.com ... -
【转】Android 画图 之 Matrix(二)
2011-05-24 18:51 1403原文地址:http://chroya.iteye.com/ ... -
【转】Android 画图 之 Matrix(一)
2011-05-24 17:44 1389原文地址: http://chroya.iteye.com/ ...
相关推荐
在Android系统中,图形用户界面(GUI)的输出是通过图形设备接口(GDI)来实现的。GDI负责管理图形图像的输出,并处理显示缓冲区的操作和管理。GDI可以被视为管理物理屏幕使用的设备管理器,它负责将应用程序的输出...
在Android应用开发中,图形和图表的展示是至关重要的,特别是在数据分析、统计报告或用户界面设计方面。Android图形图表绘制控件提供了丰富的功能,帮助开发者创建动态、交互式的图形,以便更好地传达信息和数据。本...
在Android平台上,图形与图像处理是一项关键技能,它涉及到用户界面设计、游戏开发、相机应用以及其他涉及视觉元素的移动应用程序。本主题主要涵盖Android系统如何处理图形和图像,包括基本概念、API使用以及实例...
在Android平台上,2D图形绘制是一项基础且重要的技术,它允许开发者创建丰富的用户界面和动态效果。本主题将深入探讨Android 2D图形绘制的...通过不断地实践和学习,你可以创造出富有创意和互动性的2D图形用户界面。
本教程“Android图形开发实例”旨在帮助开发者深入理解和掌握Android图形系统,提升应用程序的视觉表现和用户体验。 一、Android图形系统基础 Android的图形系统主要基于OpenGL ES,一个为嵌入式设备设计的2D和3D...
总之,Android图形处理和动画机制是构建动态、交互式用户界面的关键组成部分。理解SurfaceFlinger、Skia图形库、View绘制流程以及帧动画和补间动画的工作原理,对于开发高性能、引人入胜的应用至关重要。
4. 用户界面交互:分析图形解锁界面的UI设计和动画效果,学习如何提升用户体验。 通过对这个源码的深入研究,你不仅可以掌握Android图形解锁的实现原理,还能提升你在Android应用开发中的安全意识和定制能力。同时...
Android图形系统是确保移动设备具有流畅、精致的图形用户界面的核心组件之一。在移动操作系统领域内,优秀的图形性能不仅提升了用户体验,也是衡量设备整体性能的重要指标之一。Android图形系统主要包括两个核心组件...
在Android开发中,图像处理是不可或缺的一部分,尤其是在创建引人入胜的用户界面或实现复杂的动画效果时。本文将深入探讨Android的图像处理机制,特别是关于图形特效处理的知识点,包括Matrix和BitmapMesh的使用。 ...
这份"Android图形解锁源码.zip"包含了实现这一功能的源代码,对于深入理解Android安全机制和自定义解锁方式具有很高的学习价值。下面我们将详细探讨相关的Android知识点。 1. **Android解锁机制**: - Android提供...
然而,Go语言同样支持GUI(图形用户界面)开发,其中`fyne`框架就是一个优秀的例子。`fyne`为开发者提供了构建跨平台GUI应用的能力,它使用纯Go编写,支持Windows、macOS、Linux、iOS和Android等操作系统。 `fyne`...
这个项目涉及到Android平台上的蓝牙通信、数据处理以及图形用户界面(UI)的创建。以下是实现这一功能的关键知识点: 1. **蓝牙通信**: - **BluetoothManager**: Android提供的系统服务,用于获取对蓝牙系统的访问...
以下是一些关于Android图形画图的关键知识点: 1. **Canvas与Paint**: - `Canvas`是Android中用于在Bitmap或屏幕表面绘制的基本类。它提供了多种绘图方法,如`drawRect()`, `drawCircle()`, `drawText()`等。 - ...
在Android手机开发中,绘制图形是一项重要的技能,它允许开发者创造出独特的用户界面和交互体验。Android提供了多种方式来实现图形绘制,包括使用Canvas、Bitmap、Path、Paint等类。让我们深入探讨这些基础知识。 ...
在Android开发中,图形描画是一项重要的技能,它允许开发者创造出独特且丰富的用户界面,以及动态的动画效果。本文将深入探讨如何在Android平台上进行复杂图形的绘制,以实现自定义视图和交互式UI。 首先,我们从...
Android图形优化是一个涉及多个层面和步骤的复杂过程,它需要开发者对Android的图形渲染管线、界面渲染原理以及性能瓶颈有深入的理解。本文旨在探讨Android界面优化中的关键知识点,结合Google工程师Chet Haase和...
在Android平台上,绘制图形是构建丰富用户界面的关键技术之一。Android提供了一系列的API,使得开发者可以灵活地在屏幕上创建自定义的视觉元素。本篇将深入探讨Android绘图的方法,包括基本绘图、图形对象、画布操作...
在Android开发中,图形绘制是实现用户界面动态展示和数据可视化的重要手段。"android绘图"这个主题,尤其是提到的"achartengine-1.0.0-demo-source"压缩包,是一个专门针对Android平台的图表绘制库,它为开发者提供...
总结,Android绘图系统提供了丰富的API来创建和绘制基本图形,开发者可以根据需求自由组合使用,构建出独特且交互性强的用户界面。通过熟练掌握`Canvas`和`Paint`的使用,可以实现从简单的图标到复杂的动画效果,...
在Android平台上进行录音并进行频谱分析绘图是一项复杂但有趣的任务,涉及到多个技术领域,如音频处理、图形渲染和用户界面设计。以下是对这个主题的详细解释: 1. **Android录音**:Android系统提供了AudioRecord...