特别推荐:
使用Android自带Gallery组件实现CoverFlow,源码+解析
http://www.eoeandroid.com/thread-39709-1-1.html
android平台水波效果!
http://www.eoeandroid.com/thread-263-1-1.html
对“中文天气预报”代码全注释(带有详细注解)
http://www.eoeandroid.com/thread-40558-1-1.html
这里就不做什么特别的说明了,源码里面说的很清楚。还是直接代码吧!
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);
}
}
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);
}
}
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 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更加熟练。
*/
}