Fork me on GitHub

Android的View知识

Android View

颜色

ARGB888

A 透明度 0(0x00)透明 255(0xff)不透明

R 红色 0(0x00)无色 255(0xff)红色

G 绿色 0(0x00)无色 255(0xff)绿色

B 蓝色 0(0x00)无色 255(0xff)蓝色

流程

  • 构造函数
  • 测量大小(onMeasure)
  • 确定View的大小(onSizeChanged)
  • 确定子View的布局位置(onLayout 自定义ViewGroup中需要)
  • 绘制内容(onDraw)
  • 对外提供操作方法和监听回调

Paint

画笔介绍

  • 创建Paint
Paint mPaint = new Paint()
  • 设置属性
//设置画笔的模式
mPaint.setStyle(args);
//设置画笔的颜色
mPaint.setColor(Color.BLUE);
//设置描边宽度
mPaint.setStrokeWidth(20f)
args的取值:
Paint.Style.STROKE 描边
Paint.Style.Fill 填充
Paint.Style.Fill_AND_STROKE 描边回家填充

Canvas

操作类型 相关API 备注
绘制颜色 drawColor, drawRGB, drawARGB 使用单一颜色填充整个画布
绘制基本形状 drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧
绘制图片 drawBitmap, drawPicture 绘制位图和图片
绘制文本 drawText, drawPosText, drawTextOnPath 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字
绘制路径 drawPath 绘制路径,绘制贝塞尔曲线时也需要用到该函数
顶点操作 drawVertices, drawBitmapMesh 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用
画布剪裁 clipPath, clipRect 设置画布的显示区域
画布快照 save, restore, saveLayerXxx, restoreToCount, getSaveCount 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数
画布变换 translate, scale, rotate, skew 依次为 位移、缩放、 旋转、错切
Matrix(矩阵) getMatrix, setMatrix, concat 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。

Picture

Picture的简介

相关方法 简介
public int getWidth () 获取宽度
public int getHeight () 获取高度
public Canvas beginRecording (int width, int height) 开始录制 (返回一个Canvas,在Canvas中所有的绘制都会存储在Picture中)
public void endRecording () 结束录制
public void draw (Canvas canvas) 将Picture中内容绘制到Canvas中
public static Picture createFromStream (InputStream stream) (已废弃)通过输入流创建一个Picture
public void writeToStream (OutputStream stream) (已废弃)将Picture中内容写出到输出流中

Picture的使用

  1. 使用Picture提供的draw方法绘制
  2. 使用Canvas提供的drawPicture方法绘制
  3. 将Picture包装成PictureDrawable,使用PictureDrawable的draw进行绘制
    区别:
  4. 使用Picture的draw会对Canvas造成影响而且可操作性比较弱,影响Canvas的状态(Matrix,Clip)

Bitmap

Bitmap获取方式

序号 获取方式 备注
1 通过Bitmap创建 复制一个已有的Bitmap(新Bitmap状态和原有的一致) 或者 创建一个空白的Bitmap(内容可改变)
2 通过BitmapDrawable获取 从资源文件 内存卡 网络等地方获取一张图片并转换为内容不可变的Bitmap
3 通过BitmapFactory获取 从资源文件 内存卡 网络等地方获取一张图片并转换为内容不可变的Bitmap

BitmapFactory的使用

  • 资源文件(drawable/mipmap/raw):
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap);
  • 资源文件(assets):
Bitmap bitmap=null;
try {
    InputStream is = mContext.getAssets().open("bitmap.png");
    bitmap = BitmapFactory.decodeStream(is);
    is.close();
} catch (IOException e) {
    e.printStackTrace();
}
  • 内存卡文件:
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");
  • 网络文件:
// is代表网络下载中获取的字节流
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

绘制Bitmap的常用方法

// 第一种
public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)

// 第二种
public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)

// 第三种
public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

Path常用方法表

作用 相关方法 备注
移动起点 moveTo 移动下一次操作的起点位置
设置终点 setLastPoint 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同
连接直线 lineTo 添加上一个点到当前点之间的直线到Path
闭合路径 close 连接第一个点连接到最后一个点,形成一个闭合区域
添加内容 addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别)
是否为空 isEmpty 判断Path是否为空
是否为矩形 isRect 判断path是否是一个矩形
替换路径 set 用新的路径替换到当前路径所有内容
偏移路径 offset 对当前路径之前的操作进行偏移(不会影响之后的操作)
贝塞尔曲线 quadTo, cubicTo 分别为二次和三次贝塞尔曲线的方法
rXxx方法 rMoveTo, rLineTo, rQuadTo, rCubicTo 不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
填充模式 setFillType, getFillType, isInverseFillType, toggleInverseFillType 设置,获取,判断和切换填充模式
提示方法 incReserve 提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)
布尔操作(API19) op 对两个Path进行布尔运算(即取交集、并集等操作)
计算边界 computeBounds 计算Path的边界
重置路径 reset, rewind 清除Path中的内容reset不保留内部数据结构,但会保留FillType.rewind会保留内部的数据结构,但不保留FillType
矩阵操作 transform 矩阵变换

View的Visibility值

  1. 0 -- VISIBLE 可见
  2. 4 -- INVISIBLE 不可见但是占用布局空间
  3. 8 -- GONE 不可见也不占用布局空间

自定义View分类

  1. 自定义ViewGroup

自定义ViewGroup一般是利用现有的组件根据特定的布局方式来组成新的组件,大多继承自ViewGroup或各种Layout,包含有子View。

  1. 自定义View

在没有现成的View,需要自己实现的时候,就使用自定义View,一般继承自View,SurfaceView或其他的View,不包含子View。

自定义View主要的函数

1. 构造函数

public void XView(Context context) {}
public void XView(Context context, AttributeSet attrs) {}
public void XView(Context context, AttributeSet attrs, int defStyleAttr) {}

2. 测量函数(onMeasure)

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthsize  MeasureSpec.getSize(widthMeasureSpec);      //取出宽度的确切数值
    int widthmode  MeasureSpec.getMode(widthMeasureSpec);      //取出宽度的测量模式
    
    int heightsize  MeasureSpec.getSize(heightMeasureSpec);    //取出高度的确切数值
    int heightmode  MeasureSpec.getMode(heightMeasureSpec);    //取出高度的测量模式
}

测量模式分三种:在int类型的32位二进制位中,31-30这两位表示测量模式,29~0这三十位表示宽和高的实际值

模式 数值 描述
UNSPECIFIED 00 默认值,父控件没有给子view任何限制,子View可以设置为任意大小。
EXACTLY 01 表示父控件已经确切的指定了子View的大小。
AT_MOST 10 表示子View具体大小没有尺寸限制,但是存在上限,上限一般为父View大小。

注:对View的宽高进行修改了,不要调用 super.onMeasure( widthMeasureSpec, heightMeasureSpec); 要调用 setMeasuredDimension( widthsize, heightsize);

3. 确定View大小(onSizeChanged)

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
}

4. 确定View布局位置(onLayout)

确定布局的函数是onLayout,它用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。

child.layout(l, t, r, b);

ps:getLeft();
   getTop();
名称 说明 函数
l View左侧距父View左侧的距离 getLeft()
t View顶部距父View顶部的距离 getTop()
r View右侧距父View左侧的距离 getRight()
b View底部距父View顶部的距离 getBottom()

5. 绘制内容(onDraw)

onDraw是实际绘制的部分,也就是我们真正关心的部分,使用的是Canvas绘图

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}

6. 对外提供操作方法和监听回调

控制View或监听View某些状态。

7.事件分发

public boolean dispatchTouchEvent(MotionEvent ev){
	//默认为false,不消费当前事件 
	boolean consume=false; 
	if(onInterceptTouchEvent(ev)){ 
	//调用onTouchEvent(ev)方法,处理事件 
	 consume=onTouchEvent(ev); 
	}else{ 
	//调用子元素的dispatchTouchEvent(ev)方法,进行事件分发 
	 consume=child.dispatchTouchEvent(ev); 
	}
}

用来进行事件的分发。View/ViewGroup接收到触控事件最先调起的就是这个方法,然后在这个方法中判断是否处理拦截或者将事件分发给子元素

public boolean onInterceptTouchEvent(MotionEvent ev)

用来进行事件的拦截。ViewGroup中调用(View中没有此方法),在这个方法中判断是将事件交给ViewGroup处理或者将它传递给子元素,一般在这个方法中处理事件冲突。

public boolean onTouchEvent(MotionEvent event)
用来进行事件的处理。最后每个事件都会在这里被处理。

posted @ 2021-06-15 14:18  KevinAt2022  阅读(103)  评论(0)    收藏  举报