`

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 UI开发专题(一) 之界面设计.docx

    近期很多网友对Android用户界面的设计表示很感兴趣,对于Android UI开发自绘控件和游戏制作而言掌握好绘图基础是必不可少的。本次专题分10节来讲述,有关OpenGL ES相关的可能将放到以后再透露。本次主要涉及以下四个...

    Android UI开发专题

    近期很多网友对Android用户界面的设计表示很感兴趣,对于Android UI开发自绘控件和游戏制作而言掌握好绘图基础是必不可少的。本次专题分10节来讲述,有关OpenGL ES相关的可能将放到以后再透露。本次主要涉及以下四个...

    android UI 界面设计专题

    android 界面设计专题, 近期很多网友对Android用户界面的设计表示很感兴趣,对于Android UI开发自绘控件和游戏制作而言掌握好绘图基础是必不可少的. 本次主要涉及以下四个包的相关内容: android.content.res 资源...

    Android移动应用开发 第3版 卷1卷2合集part2

    第3版 卷Ⅱ:提高篇》涵盖了Android开发从概念 技术到市场推广应用的全部话题 内容包括:高级Android应用程序设计原则 高级Android用户界面设计原则 使用常用Android API Android中的绘图 动画与图形编程 ...

    Android基础教程

    4.1 Android图形基础 4.1.1 Color类 4.1.2 Paint类 4.1.3 Canvas类 4.1.4 Path类 4.1.5 Drawable类 4.2 在数独程序中添加图形 4.2.1 开始游戏 4.2.2 定义Game类 4.2.3 定义PuzzleView类 4.2.4 绘制游戏盘面 4.2.5 ...

    Android高级编程--源代码

     ◆高级开发主题,包括安全、ipc以及一些高级图形和用户界面技术  读者对象  本书面向希望在android手机平台上创建应用程序的所有人员。不管是经验丰富的移动开发人员,还是初出茅庐的新手,都能从本书提供的宝贵...

    Android移动应用开发 第3版 卷1卷2合集part1

    第3版 卷Ⅱ:提高篇》涵盖了Android开发从概念 技术到市场推广应用的全部话题 内容包括:高级Android应用程序设计原则 高级Android用户界面设计原则 使用常用Android API Android中的绘图 动画与图形编程 ...

    《Android高级编程》

    3.6.3 To-DoList资源示例 3.6.4 为不同的语言和硬件创建资源 3.6.5 运行时配置更改 3.7 深入探讨Android活动 3.7.1 创建一个活动 3.7.2 活动生命周期 3.7.3 Android活动类 3.8 小结 第4章 创建用户界面 4.1 Android ...

    Android 4游戏编程入门经典

     12.5.1 用户界面的资源  12.5.2 游戏资源  12.5.3 音效与音乐  12.6 开始编写代码  12.7 assets类  12.8 settings类  12.9 主活动  12.10 主菜单  12.11 游戏设置画面  12.12 模拟类  12.12.1 shield类 ...

    疯狂Android讲义源码

     1.4 开始第一个Android应用 20  1.4.1 使用Eclipse开发第一个  Android应用 20  1.4.2 通过ADT运行Android应用 23  1.5 Android应用结构分析 24  1.5.1 创建一个Android应用 24  1.5.2 自动生成的R.java 26 ...

    Android高级编程.pdf

    4.2.1 使用View创建Activity(活动)用户界面 4.2.2 Android Widget工具箱 4.3 布局简介 4.4 创建新的View 4.4.1 修改现有的View 4.4.2 创建复合控件 4.4.3 创建定制的Widget和控件 4.4.4 使用定制的控件 4.5 创建和...

    推荐8款常用的Python GUI图形界面开发框架

    作为Python开发者,你迟早都会用到图形用户界面来开发应用。本文将推荐一些 Python GUI 框架,希望对你有所帮助,如果你有其他更好的选择,欢迎在评论区留言。 Python 的 UI 开发工具包 Kivy Kivy是一个开源工具包...

    android游戏编程入门

     12.5.1 用户界面的资源 485  12.5.2 游戏资源 486  12.5.3 音效与音乐 488  12.6 开始编写代码 488  12.7 Assets类 489  12.8 Settings类 492  12.9 主活动 493  12.10 主菜单 494  12.11 游戏设置画面 ...

    Google Android SDK开发范例大全(PDF高清完整版1)(4-1)

    第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——...

    Android_UI开发专题.doc

    近期很多网友对Android用户界面的设计表示很感兴趣,对于Android UI开发自绘控件和游戏制作而言掌握好绘图基础是必不可少的。本次专题分10节来讲述,有关OpenGL ES相关的可能将放到以后再透露。本次主要涉及以下四个...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——...

    疯狂Android讲义.part2

    1.4 开始第一个Android应用 20 1.4.1 使用Eclipse开发第一个 Android应用 20 1.4.2 通过ADT运行Android应用 23 1.5 Android应用结构分析 24 1.5.1 创建一个Android应用 24 1.5.2 自动生成的R.java 26 1.5.3 res目录...

Global site tag (gtag.js) - Google Analytics