2018 Android 自定义View 1-1.md

2018 Android 自定义View 1-1

看了扔物线 大神的视频自己总结笔记

最近决定在吧基础知识系统巩固一下,涉及到的内容有

  • 自定义View
  • 数据结构
  • 算法
  • 线程
  • 网络

那么先从自定义View开始

先说一下View的坐标系

View的位置是通过view.getxxx()函数进行获取(以Top为例):

getTop();//获取子View左上角距父View顶部的距离 
getLeft();//获取子View左上角距父View左侧的距离 
getBottom(); //获取子View右下角距父View顶部的距离
getRight(); //获取子View右下角距父View左侧的距离

与MotionEvent中get…()和getRaw…()的区别

//get() :触摸点相对于其所在组件坐标系的坐标
event.getX();       
event.getY();
//getRaw() :触摸点相对于屏认坐标系的坐标
event.getRawX();    
event.getRawY();

分为三个点 【绘制】 【布局】 【触摸反馈】

绘制:

就是接管【系统的绘制】过程, 由【自己】来完成。

  • 最长使用的是onDraw 方法,自定义就在在onDraw中写上自己的代码
  • onDraw()中的主要绘制参数是 Canvas
  • 例如 下图使用Canvas 绘制了一个 红色的圆。

Canvas 的常用方法 都是以 drawxxx 开头的

Canvas 可以实现多种图形 如:

方法中有很多参数,其中Paint 参数负责,图形的 颜色 粗细 阴影等;

绘制还有两个辅助类、

图像裁剪 和 图像几何变换

  • 裁剪 的方法都是 clip 开头的

  • 几何变换: 图像的缩放 位置移动 等

上面的内容就可以帮助我们 绘制出想要的 图形了。

onDraw + 裁剪 + 几何变化

但是还有一点就是绘制顺序 (view之间的遮盖关系)

那么除了 主要的onDraw 方法外,还需要了解其他的绘制方法

  • 前景绘制 onDrawForeground
  • 背景绘制 drawBackground
  • 整体绘制方法 invalidate

他们都自己的先后步骤。

  • 后绘制的会遮盖 先绘制的。

总结


#Paint的具体使用

常用方法

Paint.setStyle(Style style) 设置绘制模式
Paint.setColor(int color) 设置颜色
Paint.setStrokeWidth(float width) 设置线条宽度
Paint.setTextSize(float textSize) 设置文字大小
Paint.setAntiAlias(boolean aa) 设置抗锯齿开关
paint.setStrokeCap(Paint.Cap.SQUARE); 设置点的形状

#Canvas具体使用

常用方法

    canvas.drawCircle(300,300,200,paint);  绘制圆形
    canvas.drawText("测试文字1",300,200,paint); 绘制文字
    canvas.drawColor(Color.BLACK); 绘制颜色
    canvas.drawPoint(); 绘制点
    canvas.drawPoints(); 绘制对个点
    canvas.drawOval(); 绘制椭圆
    canvas.drawRoundRect(100, 100, 500, 300, 50, 50, paint); 绘制圆角矩形
    canvas.drawLines(100, 100, 500, 300, 50, 50, paint); 绘制线
    canvas.drawArc(200, 100, 800, 500, -110, 100, true, paint); // 绘制扇形
    canvas.drawArc(200, 100, 800, 500, 20, 140, false, paint); // 绘制弧形  

	float[] points = {0, 0, 50, 50, 50, 100, 100, 50, 100, 100, 150, 50, 150, 100};  
	// 绘制四个点:(50, 50) (50, 100) (100, 50) (100, 100)
	canvas.drawPoints(points, 2 /* 跳过两个数,即前两个 0 */,  
      8 /* 一共绘制 8 个数(4 个点)*/, paint);

drawPath 复杂的图形使用

如:心形 图案

public class PathView extends View {

Paint paint = new Paint();
Path path = new Path(); // 初始化 Path 对象

{
  // 使用 path 对图形进行描述(这段描述代码不必看懂)
  path.addArc(200, 200, 400, 400, -225, 225);
  path.arcTo(400, 200, 600, 400, -180, 225, false);
  path.lineTo(400, 542);
}

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);

  canvas.drawPath(path, paint); // 绘制出 path 描述的图形(心形),大功告成
 }

}


Path 的具体使用 (分两类)

Path 可以描述

、二次曲线、三次曲线、圆、椭圆、弧形、矩形、圆角矩形。把这些图形结合起来,就可以描述出很多复杂的图形。下面我就说一下具体的怎么把这些图形描述出来。

方法第一类: 直接描述路径 (又分为两组)

  • 第一组

    path.addCircle(100,100,80,Direction);添加圆形
    // 参数 4 Path.Direction.CW 顺时针 ; Path.Direction.CCW 逆时针

    path.addOval(float left, float top, float right, float bottom, Direction dir) / addOval(RectF oval, Direction dir) 添加椭圆

    path.addRect(float left, float top, float right, float bottom, Direction dir) / addRect(RectF rect, Direction dir) 添加矩形

    path.addRoundRect(RectF rect, float rx, float ry, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Direction dir) / addRoundRect(RectF rect, float[] radii, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float[] radii, Direction dir) 添加圆角矩形

    path.addPath(Path path) 添加另一个 Path

第二组 xxxTo() – 画线(直线或者曲线)

  • 直线

      	path.lineTo(100, 100); // 由当前位置 (0, 0) 向 (100, 100) 画一条直线  
    
      	path.rLineTo(100, 0); // 由当前位置 (100, 100) 向正右方 100 像素的位置画一条直线  
    

  • 曲线 (贝赛尔曲线自行百度了解)

     	quadTo(float x1, float y1, float x2, float y2) /
    
     	rQuadTo(float dx1, float dy1, float dx2, float dy2) 
    
     	画二次贝塞尔曲线
     	
    
     	cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
    
         rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 
    
     	画三次贝塞尔曲线
    
     	
     	path.moveTo(200, 100); // 移动到目标位置  
     	path.rMoveTo(200, 100); 
    
  • path.arcTo(100, 100, 300, 300, -90, 90, true); // 强制移动到弧形起点(无痕迹)

  • path.addArc(100, 100, 300, 300, -90, 90); “addArc简化版arcTo 它自带foreMoveTO = true属性”

  • close() 和 lineTo(起点坐标) 是完全等价的。 “闭合图形”

方法第二类:辅助的设置或计算

Path.setFillType(Path.FillType ft) 设置填充方式

EVEN_ODD
WINDING (默认值)

-------讲上面两种效果反转----------

INVERSE_EVEN_ODD
INVERSE_WINDING

所以理解了 EVEN_ODD 和 WINDING 也就明白了后面两种

上图:

练习效果图

发布了26 篇原创文章 · 获赞 6 · 访问量 7803

猜你喜欢

转载自blog.csdn.net/weixin_37558974/article/details/82848830