Android 自定义View

embedded/2024/10/21 1:34:30/

我们所有的试图都是起源于自定义View,包括ViewGroup也是继承于它,可以说它是视图组件之父。
我们可以从它的大致流程来分为四个部分:
构造方法,onMeasure,onLayout,onDraw

构造方法:

它主要有四个构造方法
分别为:

  • View(Context context)
  • public View(Context context, @Nullable AttributeSet attrs)
  • public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
  • public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)

关于attrs,defSyleAttr,defStyleRes介绍,源码中是这样说的
(一) attrs
attrs是一个int值,通过它一系列xml中一系列属性值的一个
它的作用:

  • 可以通过它来获取布局文件资源id值
    在这里插入图片描述
  • 在saveAttributeData中会默认先加载系统默认的属性值跟id,然后通过attrs加载已解析的可样式属性,比如说layout_marginTop,系统会给它一个默认的值,如果我们在xml当中进行修改,然后会将原值进行替换。
    在这里插入图片描述
    在这里插入图片描述
    (二)defStyleAttr
    Framework中源文件参数的介绍:

defStyleAttr An attribute in the current theme that contains a reference to a style resource that supplies default values for the view. Can be 0 to not look for defaults.

(三)defStyleRes介绍

defStyleRes A resource identifier of a style resource that supplies default values for the view, used only if defStyleAttr is 0 or can not be found in the theme. Can be 0 to not look for defaults

这两个参数在saveAttributeDataForStyleable中有参与但是看不到具体的内容在这里插入图片描述

onMeasure

它最终会调到
MeasureSpec:
MeasureSpec是一个32位的int值,高2位代表SpecMode,低30位代表SpecSize,SpecMode是指测量模式,SpecSize是指某种测量模式下的规格大小。

  • EXACTLY 父容器已经检测出View所需要的精确大小,这时候View的最终大小就是SpecSize所指定的值。对应于LauoutParams中的match_parent和具体数值这两种模式。
  • AT_MOST 父容器指定了一个可用大小即SpecSize,View的大小不能大于这个值,对应于LayoutParams中的wrap_content
  • UNSPECIFIED 父容器不对View有任何限制,要多大给多大,常用于系统内部,平常工作中不常见

普通View的MeasureSpec的创建规则:
在这里插入图片描述
onMeasure会调到setMeasureDimension方法
在这里插入图片描述
它会设置View 宽/高的测量值,因此只需要看getDefaultSize方法
在这里插入图片描述从这个方法来看,View的宽高由specSize决定,再结合MeasureSpec的创建规则表,得出结论:
直接继承View的自定义控件需要重写onMeasure方法并设置wrap_content时的自身大小,否则在布局中使用wrap_content就相当于使用match_parent。因为 View使用wrap,它的specMode是AT_MOST模式,宽高等于specSize,这情况下specSize为parentSize,而parentSize是父容器可使用的大小。

解决方法:

java">        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {setMeasuredDimension(mWidth, mHeight);} else if (widthSpecMode == MeasureSpec.AT_MOST) {setMeasuredDimension(mWidth, heightMeasureSpec);} else if (widthSpecMode == MeasureSpec.AT_MOST) {setMeasuredDimension(widthMeasureSpec, mHeight);}

onLayout

onLayout主要是视图位置的确定

onDraw

View的回值过程遵循如下几步:

  1. 绘制背景 background.draw
  2. 绘制自己 onDraw
  3. 绘制child dispatchDraw
  4. 绘制装饰 onDrawScrollBars

常见Canvas方法:
在这里插入图片描述
Paint常用方法:

java">paint.setStrokeWidth(0);//设置画笔宽度0  ,单位px  默认一个像素
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);//描边 
paint.setStrokeWidth(10);//画笔宽度 10,单位px
paint.setAntiAlias(true);//抗锯齿功能
paint.setAlpha(); //设置画笔透明度
paint.setARGB();// 设置透明度 和 颜色
paint.setStyle()//设置画笔样式

注意:

  • 尽量不要在View中使用Handler
  • View中如果由线程或者动画,需要及时停止,可以在View#onDetachedFromWindow操作
  • 有嵌套滑动情形时,需要处理好滑动冲突

http://www.ppmy.cn/embedded/50758.html

相关文章

Python学习笔记15:进阶篇(四)文件的读写。

文件操作 学习编程操作中,我觉得文件操作是必不可少的一部分。不管是读书的时候学习的c,c,工作的前学的java,现在学的Python,没学过的php和go,都有文件操作的模块以及库的支持,重要性毫无疑问。…

把Vue项目从Window系统迁移到Mac系统的方案

不能启动vue ui 直接运行,会报错如下: failed to load config from /Users/xiaochen/IdeaProjects/ChatViewer-frontend/vite.config.tserror when starting dev server: Error: You installed esbuild for another platform than the one youre curre…

【谷歌】实用的搜索技巧

1、使用正确的谷歌网址 我们知道https://www.google.com是谷歌的网址。但根据国家,用户可能会被重定向到 google.fr(法国)或google.co.in(印度)。 最主要的URL——google.com是为美国用户准备的(或是针对全世界所有用户的唯一URL))。当你在谷歌上搜索时,了解这一点是相…

计算机网络知识点汇总(三)

1.2 计算机网络体系结构与参考模型 1.2.1 计算机网络分层结构 计算机网络的各层及其协议的集合称为网络的体系结构(Architecture)。换言之,计算机网络的体系结构就是这个计算机网络及其所应完成的功能的精确定义。要强调的是,这些功能究竟是用何种硬件…

最新版Cisco Packet Tracer思科模拟器Windows版本64位下载

Cisco Packet Tracer是思科公司推出的一款网络仿真工具,主要用于网络教学、培训和实验。它提供了一个真实的网络环境模拟平台,让用户可以设计、构建和调试网络,以及进行实时互动,从而帮助用户理解和实践网络技术。 通过 Cisco Pa…

【教程】hexo 更换主题后,部署在 Github Page 无 CSS 样式

目录 前言环境hexo 更换主题解决部署到 Github Page 后无 CSS 样式的问题 前言 最近更换了 hexo 的主题后,重新部署到 Github Page 上发现不显示 CSS 样式,但在本地启动时又是正常的效果。此外,检查资源请求,发现多个 .css 文件请…

用python把docx批量转为pdf

为保证转换质量,本文的方法是通过脚本和com技术调用office自带的程序进行转换的,因此需要电脑已经装有office。如果希望不装office也能用,则需要研究OpenXML技术,后面实在闲的慌(退休)再搞。 安装所需库 …

OpenCV--滤波器(一)

低通滤波器 代码和笔记 代码和笔记 import cv2 import numpy as np""" 滤波器--用于图像处理的重要工具,它们可以根据图像中像素的邻域信息来修改像素值,以实现去噪、模糊、锐化、边缘检测等效果。低通滤波器(Low-pass Filte…