zoukankan      html  css  js  c++  java
  • android 之绘图

    特别推荐:
    使用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更加熟练。
    */
     
    }
  • 相关阅读:
    leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法
    FizzBuzz and Fibonacci优化
    mysql 存储过程 演示样例代码
    《深入理解Android 卷III》第二章 深入理解Java Binder和MessageQueue
    jsp中URL传递中文參数的处理
    键盘录入多名学生的信息: 格式:姓名,数学成绩,语文成绩,英文成绩,按总分由高到低 将学生的信息进行排列到文件里
    iOS_block代码块
    自己动手写android图片异步载入库
    三分钟教你学Git(十三)
    文本文件打印类库(C#)
  • 原文地址:https://www.cnblogs.com/vus520/p/2644228.html
Copyright © 2011-2022 走看看