Android学习之路(一)Android绘图

Android学习之路(一)Android绘图Paint的基本使用

Android开发中,使用自定义控件是非常普遍的,通过继承View来重写onDraw()方法,而Paint的使用就是必须要熟练掌握的,本文通过一个例子实现Paint的基本使用

1.简单图形的绘制

public class MyView extends View {
//View下构造器有3种重载方式,如需在xml中配置应用该View,必须实现该构造器
    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    //重写onDraw()方法
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);//绘制黑色背景
        Paint paint = new Paint();//创建画笔
        paint.setColor(Color.WHITE);//设置画笔颜色
        canvas.drawRect(10,10,330,330,paint);向View中绘制矩形,前四个参数分别是左上角的x,y和右下角的x,y
        paint.setTextSize(50);//设置字体大小
        canvas.drawText("这是字符串",10,450,paint);//向View中绘制字符串,后两个参数为字符串所占矩形的左下角x,y
        RectF rectF = new RectF(10,530,210,730);//创建一个矩形对象
        canvas.drawArc(rectF,0,45,true,paint);//根据矩形对象的大小和位置绘制弧形,给出起始角度和终止角度,顺时针
        canvas.drawLine(350,10,550,650,paint);//绘制直线,前四个参数分别为起点的x,y坐标,和终点的x,y坐标
        RectF rectF1 = new RectF(450,550,650,750);
        canvas.drawOval(rectF1,paint);//根据矩形画圆
    }
}

接下来在布局文件.xml的线性布局中添加自定义的View即可

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <包名.MyView
        android:id="@+id/myView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

效果如图
在这里插入图片描述

2.贴图的使用

基本图形的绘制往往不能满足应用开发的需求,同样,通过一个贴图的例子来实现图片的绘制

public class MyView extends View {
    Bitmap bitmap;
    Paint paint;
//构造器
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.initBitmap();//调用初始化图片的方法
    }

    private void initBitmap() {
         paint = new Paint();//创建画笔
         bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img);//获取需要绘制的图片
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setAntiAlias(true);//打开抗锯齿
        paint.setColor(Color.WHITE);
        paint.setTextSize(15);
        canvas.drawBitmap(bitmap,10,10,paint);绘制图片
        canvas.save();
        Matrix m1 = new Matrix();创建Matrix对象
        m1.setTranslate(500,10);平移矩阵,分别为x,y上的平移量
        Matrix m2 = new Matrix();
        m2.setRotate(15);以一定的角度旋转矩阵
        Matrix m3 = new Matrix();
        m3.setConcat(m1,m2);//设置m3为当前m1与m2的乘积
        m1.setScale(0.8f,0.8f);//设置缩放,分别为x,y的缩放倍数,当前m1的set方法会把上一个set方法效果清除掉,Matrix的set方法都是如此
        m2.setConcat(m3,m1);
        canvas.drawBitmap(bitmap,m2,paint);//绘制图片
        canvas.restore();//恢复画布状态
        canvas.save();//保存画布状态
        paint.setAlpha(180);//设置透明度
        m1.setTranslate(200,100);
        m2.setScale(1.3f,1.3f);
        m3.setConcat(m1,m2);
        canvas.drawBitmap(bitmap,m3,paint);
        paint.reset();
        paint.setTextSize(40);
        paint.setColor(0xffFFFFFF);
        canvas.drawText("图片的宽度:"+bitmap.getWidth(),20,380,paint);
        canvas.drawText("图片的高度:"+bitmap.getHeight(),20,430,paint);
        paint.reset();

    }
}

同样使用相应xml布局添加自定义View,相应效果图如下所示
在这里插入图片描述

3.裁剪功能

Canvas类提供了裁剪功能,可以将图片裁剪成特殊的形状
常用的裁剪方法:

方法含义
public boolean clipPath(Path path)根据给定的路径裁剪一定的图形
public boolean clipRect(int left,int top,int right,int bottom)根据给定的坐标裁剪出矩形,left和top为矩形左上顶点的坐标,right和bottom为右下顶点的坐标
public boolean clipRect(float left,float top,float right,float bottom,Region.Op op)修改指定的矩形,left和top为矩形左上顶点的坐标,right和bottom为右下顶点的坐标,op指定了运算种类

通过Path,Rect以及Region的不同组合,Android可以裁剪出很多不同形状的区域,其中Path提供各种基本几何图形,Rect提供矩形的定义方法,Region支持区域的多种逻辑运算,Region.Op定义了Region支持的区域间的运算种类
如下表:

逻辑运算含义
DIFFERENCE求A和B的差集范围,即A-B,只有在此方位内绘制的内容才会被显示
REVERSE_DIFFERENCE求B和A的差集范围,即B-A,只有在此方位内绘制的内容才会被显示
REPLACE无论A和B的集合状况如何,B的范围将全部进行显示,如果B和A有交集,则覆盖交集范围
INITERSECTA和B的交集范围,只有在此范围内绘制的内容才会被显示
UNIONA和B的并集范围,即两者所包括的范围内绘制的内容才会被显示
XOPA和B的补集范围,即A除去B以外的范围,只有在此范围内绘制的内容才会被显示

一个简单的裁剪实例实现

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    MainActivity activity;
    Paint paint;
    Path mPath;
    Path mPath1;
    public MySurfaceView(Context context) {
        super(context);
        this.activity = (MainActivity) context;初始化acitivity对象
        this.getHolder().addCallback(this);//设置回调接口
        paint = new Paint();
        paint.setAntiAlias(true);
         //设置路径
        mPath = new Path();
        mPath.moveTo(350,20);
        mPath.lineTo(520,20);
        mPath.lineTo(500,170);
        mPath.lineTo(330,170);
        mPath.lineTo(350,20);

        //设置路径
        mPath1=new Path();
        mPath1.moveTo(170, 50);
        mPath1.lineTo(260, 50);
        mPath1.lineTo(240, 120);
        mPath1.lineTo(150, 120);
        mPath1.lineTo(170, 50);
    }
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.drawARGB(128,128,128,128);//设置画布灰色
        //canvas.drawARGB(255,122,255,0);//设置画布绿色
        canvas.save();
        canvas.clipRect(30, 20,280, 250);//裁剪一个矩形
        canvas.drawColor(Color.WHITE);//画布设置为白色
        paint.setColor(Color.RED);
        canvas.drawCircle(85, 75, 50, paint);//绘制红色圆形
        paint.setColor(Color.BLUE);
        canvas.drawRect(170,150, 260, 240, paint);//绘制蓝色矩形
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(mPath1, paint);//绘制黑色平行四边形边框
        canvas.restore();//恢复至前的保存状态

        canvas.save();//保存当前状态
        canvas.clipPath(mPath);//根据路径裁剪出平行四边形
        Bitmap bm= BitmapFactory.decodeResource(activity.getResources(), R.drawable.tubiao);
        canvas.drawBitmap(bm, 10, 20, paint);//贴图
        canvas.restore();
        canvas.save();
        canvas.clipRect(30, 300, 180, 450);//绘制矩形
        canvas.clipRect(55, 325, 155, 425, Region.Op.DIFFERENCE);//裁剪出回字形
        canvas.drawBitmap(bm, 33, 130, paint);//贴图
        canvas.restore();

        canvas.save();
        mPath.reset();
        mPath.addCircle(470, 479, 240, Path.Direction.CCW);
        canvas.clipPath(mPath, Region.Op.REPLACE);//根据路径剪裁出圆形
        canvas.drawBitmap(bm, 130, 150, paint);
        canvas.restore();

        canvas.save();
        canvas.clipRect(80, 790, 600, 960);//绘制矩形
        canvas.clipRect(270, 790, 430, 1200, Region.Op.UNION);//连接两个矩形
        canvas.drawColor(Color.RED);//超出图片的部分绘制成红色
        canvas.drawBitmap(bm, 110, 450, paint);
        canvas.restore();




    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {//创建时调用
        Canvas canvas=holder.lockCanvas();
        try{
            synchronized(holder){
                onDraw(canvas);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(canvas!=null){//当画布不为空,解锁表示绘制完毕
                holder.unlockCanvasAndPost(canvas);
            }
        }
    }



    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {、、改变时调用

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {//销毁是调用

    }
}

在对应的Acitivity:

  MySurfaceView view;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view=new MySurfaceView(this);
        setContentView(view);
    }

效果如下图:
在这里插入图片描述


版权声明:本文为liuxiangsheng911原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。