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有交集,则覆盖交集范围 |
INITERSECT | A和B的交集范围,只有在此范围内绘制的内容才会被显示 |
UNION | A和B的并集范围,即两者所包括的范围内绘制的内容才会被显示 |
XOP | A和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版权协议,转载请附上原文出处链接和本声明。