您的位置:首页 > 移动开发 > Android开发

Android 中如何自己通过代码绘图

2011-12-12 14:16 453 查看
下文来自:

/article/4136306.html

----------------------------------

BasicViewDraw.java

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); } }

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

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);
}
}

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

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); } }
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

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更加熟练。
*/

}

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

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)点来进行。
*/

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

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();
}
}
}

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

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);
}
}

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

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;
* }
*/

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

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");
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐