专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 图形/图像

Android 图形用户界面 之 绘图(1)

发布时间:2011-06-27 20:28:35 文章来源:www.iduyao.cn 采编人员:星星草
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");
			}
		}
	}

}

 

1 楼 JACKDG2010 2011-07-20  
   
2 楼 不夜的星辰 2011-09-21  
请问下你这种版述效果如何设置?
3 楼 ldci3gandroid 2011-09-28  
不夜的星辰 写道
请问下你这种版述效果如何设置?

不好意思啊,没明白你说的是什么意思?
4 楼 力争向日葵 2012-02-24  
谢谢呀!很好的学下了
5 楼 梦林忆雨 2012-03-30  
谢谢,学习了啊!
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: