大家好,欢迎来到IT知识分享网。
前言:
本文主要讲述自定义View中Paint、Canvas以及Path的使用,不牵扯到PathMeasure和Matrix,提供画一些常见的点、线、面、矩形、圆、椭圆以及不规则图形。
另外需注意:Android的坐标系和数学中的坐标系是有区别的,Android的坐标系是以屏幕的左上角为坐标原点,垂直向下是Y轴的正方向,切勿和数学坐标系混淆。
先上图形:
一、自定义View常用方法
1.构造方法
自定义View的构造方法有四种,分别是一参二参三参四参,三参四参很少用,主要讲解下一参和二参的区别;
一参:在code中初始化自定义View的时候调用较多;
二参:在xml中使用自定义View时会调用;
2.onDraw:提供画布(Canvas),用来画界面
3.onMeasure:测量屏幕尺寸,常用方法是getSize和getMode,例(获取屏幕宽度):MeasureSpec.getSize(widthMeasureSpec);
4.onSizeChanged:在View size发生变化时调用,可以获取old view的size和更新后view的size
二、Paint的使用
1.初始化
paint = new Paint();
paint.setColor(Color.RED);//设置颜色
paint.setStyle(Paint.Style.FILL);//设置paint的类型(包含FILL、STROKE和FILL_AND_STROKE三种)
paint.setStrokeWidth(10F);//设置线宽
2.画常见图形
//点
canvas.drawPoint(50, 100, paint);
//一组点
canvas.drawPoints(new float[]{
100, 100,
150, 100,
200, 100
}, paint);
//线
canvas.drawLine(250, 100, 300, 100, paint);
//矩形
canvas.drawRect(new Rect(350, 50, 500, 150), paint);
//圆角矩形
canvas.drawRoundRect(new RectF(550, 50, 700, 150), 5, 5, paint);
//椭圆
canvas.drawOval(new RectF(750, 50, 900, 150), paint);
//圆
canvas.drawCircle(1000, 100, 50, paint);
//圆弧
canvas.drawArc(new RectF(1100, 50, 1200, 150), 180, 90, true, paint);
//空心圆
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(100, 250, 50, paint);
//饼状图
paint.setStyle(Paint.Style.FILL);
RectF rectF = new RectF(250, 200, 350, 300);
canvas.drawArc(rectF, 0, 60, true, paint);
paint.setColor(Color.GRAY);
canvas.drawArc(rectF, 60, 150, true, paint);
paint.setColor(Color.GREEN);
canvas.drawArc(rectF, 210, 90, true, paint);
paint.setColor(Color.YELLOW);
canvas.drawArc(rectF, 300, 60, true, paint);
//图片
//canvas.drawPicture();
//canvas.drawBitmap();
//文字
//canvas.drawText();
3.实例
通过以上方法,基本可以满足一些规则图形的需求,例如扇形图表、折线图等,另外也可结合Handler的使用通过invalidate()方法实现动态的效果;
如下就是简单实现圆柱注水效果的code:
//画动态水柱
canvas.drawRoundRect(new RectF(100, 600, 200, 1000), 50, 50, paint);
paint.setColor(Color.GREEN);
//下
canvas.drawArc(new RectF(110, 900, 190, 990), 90 – waterAngle, 2 * waterAngle, false, paint);
//中
canvas.drawRect(new RectF(110, waterHeight, 190, 950), paint);
//上
if (waterAngle02 == 0) {
canvas.drawArc(new RectF(110, 610, 190, 700), -waterAngle02, 0, false, paint);
} else {
canvas.drawArc(new RectF(110, 610, 190, 700), -waterAngle02, (2 * waterAngle02) + 180, false, paint);
}
if (waterAngle < 90) {
mHandler.sendEmptyMessage(2);//画下半圆
} else {
if (waterHeight > 650) {
mHandler.sendEmptyMessage(1);//画中间
} else if (waterAngle02 < 90) {
Log.e(“MyView”, “waterAngle02:” + waterAngle02);
mHandler.sendEmptyMessage(3);//画上半圆
}
}
//动态水柱
private float waterAngle = 0;
private float waterAngle02 = 0;
private int waterHeight = 950;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
if (waterHeight > 645) {
waterHeight–;
mHandler.sendEmptyMessageDelayed(1, 2000);
invalidate();
}
} else if (msg.what == 2) {
if (waterAngle < 90) {
waterAngle++;
mHandler.sendEmptyMessageDelayed(2, 2000);
invalidate();
}
} else if (msg.what == 3) {
if (waterAngle02 < 90) {
waterAngle02++;
mHandler.sendEmptyMessageDelayed(2, 2000);
invalidate();
}
}
}
};
三、Canvas的使用
画布的使用主要为了更加快捷的确定坐标系的位置,类比我们现实中的画板,如果你想画出来一个倒在地上的金字塔,不如在作画前先将画板向右旋转90度,然后画一个正常的金字塔,完成作品后,再将画纸向左旋转回来,就能达到想要的效果。以下介绍几种画布常见的操作方法:
1.平移:canvas.translate(150, 0);//将画布向右平移150
2.旋转:canvas.rotate(30, 100, 100);//将画布围绕点(100, 100)旋转30度
3.缩放:canvas.scale(2f, 2f, 100, 100);//将画布以点(100, 100)放大两倍
四、Path的使用
canvas除了有draw点draw线draw矩形等方法,还可以drawPath(Path path, Paint paint);
虽然都是要paint来画,但是drawPath不同的是可以画很多不规则图形,形状取决于path;
1.首先path也可以画规则图形,方法基本类似canvas中画基本图形的方法
2.特别介绍path中不同于canvas画基本图形的几个方法
path.lineTo():在路径上添加一个点
path.moveTo():移动到下次lineTo的起点
path.setLastPoint():设置上次操作的最后一个点的位置
path.close():封闭路径
path.quadTo():用来画贝塞尔曲线(大部分复杂的自定义View都会用到贝塞尔曲线)
3.简单的贝塞尔曲线的使用
为了实现根据touch点来绘制指定的贝塞尔曲线:
public class BezierView extends View {
private Paint mPaint;
private int centerX, centerY;
private PointF start, end, control;
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.STROKE);
start = new PointF(0, 0);
end = new PointF(0, 0);
control = new PointF(0, 0);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path path = new Path();
path.moveTo(start.x, start.y);
path.quadTo(control.x, control.y, end.x, end.y);
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = h / 2;
start.x = centerX – 200;
start.y = centerY;
end.x = centerX + 200;
end.y = centerY;
control.x = centerX;
control.y = centerY – 100;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
control.x = event.getX();
control.y = event.getY();
invalidate();
return true;
}
}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/153541.html