[Android]自定义view - 详解

news/2025/9/23 13:13:36/文章来源:https://www.cnblogs.com/lxjshuju/p/19107008

目录

为什么需要自定义view?

View的绘制流程

自定义View

OnMeasure

代码部分

三种测量模式

1. EXACTLY

2. AT_MOST

3. UNSPECIFIED

重写OnDraw方法

自定义属性


为什么需要自定义view?

Android 提供了大量现成控件,但当你需要实现独特的视觉表现、复杂的动画或者当前现成的控件已经没有办法去满足你的需求时,这时可以自定义view来完成我们所期望的需求;

View的绘制流程

  1. onMwasure:测量View宽高

  2. onLayout: 计算View的位置并布局

  3. onDraw: 绘制View

自定义View

这里有两个我们必须重写的方法:

public xxview(Context context) {
super(context);
}
public xxview(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}

第二个方法中有一个参数:AttributeSet

  • 你在布局文件里写 <com.example.xxView ... /> 并设置属性时,系统会把这些属性打包成一个 AttributeSet 对象传给构造函数;

  • 我们可以通过它,拿到在 XML 中声明的属性,从而在代码里初始化 View 的样式;

总结来说,就是拿到XML文件中的属性并且设立初始值;

OnMeasure

前文提到:这个方法用来测量自定义view的宽高尺寸;

那么为什么需要测量宽高尺寸呢?不是应该都在XML文件中定义过了么?

但其实,我们在XML文件中有三种定义,分别是wrap_content,match_parent还有精确值;前两者并没有指定具体的大小,所以这个时候需要我们手动去处理和设置尺寸;

当然,在View类中提供的onMeasure方法中,也有设置,但是如果你在XML文件中写的是wrap_content,那么最后显示的效果是充满父布局的,为什么会这样?稍后会有解答...

重写OnMeasure方法:

代码部分

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int wigth = xxonmeasure(100, widthMeasureSpec);
int height = xxonmeasure(200, heightMeasureSpec);
setMeasuredDimension(wigth,height);
}
protected int xxonmeasure(int defaultsize,int measureSpec) {
int size = defaultsize;
int mode = MeasureSpec.getMode(measureSpec);
int sizes= MeasureSpec.getSize(measureSpec);
switch (mode){
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY: {
size = sizes;
break;
}
case  MeasureSpec.UNSPECIFIED:{
size= defaultsize;
break;
}
}
return size;
}

在了解这些之前,我们先来看看测量模式:

三种测量模式

1. EXACTLY

  1. 含义:父容器已经指定了 确切的大小;

  2. 什么情况下:子 View 的 layout_width / layout_height 是具体值或者是 match_parent

  3. 那为什么match_parent是精确模式呢?因为父容器的大小已经确定,所以自然当前的情况也已经确定了;因为尺寸大小的确定是自上而下的;

2. AT_MOST

  1. 含义:父容器指定了一个 最大的值;

  2. 什么情况下:子 View 的 layout_width / layout_height 是 wrap_content

  3. 为什么?因为当前view设定的是包含当前内容即可,没有办法确定具体的值,我们只能获取到父容器的值,知道最大限制,所以此时我们的模式就是知道它的最大值;

3. UNSPECIFIED

  1. 含义:父容器对 View 的大小没有限制;

  2. 什么情况下:View 自己决定大小,比如ScrollView 的子元素高度可能是无限制的,能撑多大就多大;

  3. 这种情况比较少见;

在onMeasure方法中,有两个我们不太熟悉的参数: int widthMeasureSpec, int heightMeasureSpec

widthMeasureSpe包含是测量模式和测量的大小,其实准确来说是父view提供的参考大小,最终的大小我们需要自己处理的;

那么一个Int型的数据为什么能包含测量模式和大小呢?一个Int占用32个bit,三种测量模式只需要两个bit,所以前两个bit存的是测量模式,后30存的是测量的大小;我们可以直接用封装好的方法去获取:

  1. 获取模式

int mode = MeasureSpec.getMode(measureSpec);

  1. 获取大小 int sizes= MeasureSpec.getSize(measureSpec);

setMeasuredDimension(wigth,height);这行代码是设置确定好最终的尺寸;

现在重新阅读代码,去理解写的逻辑;

switch (mode){
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY: {
size = sizes;
break;
}
case  MeasureSpec.UNSPECIFIED:{
size= defaultsize;
break;
}
}

这里如果模式是MeasureSpec.AT_MOST,那么 size = sizes;就是说最终的大小是父容器的大小,当前你可以根据你自己想要的效果去设置不同的值;

重写OnDraw方法

用 canvas画板,我们还可以绘制其他的图形,颜色等,这里绘制了圆形;

@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
int r = getMeasuredWidth() / 2;
int X = getLeft() + r;
int Y = getTop() + r;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
canvas.drawCircle(X, Y, r, paint);
}

canvas.drawCircle(X, Y, r, paint); 前两个参数是圆的横纵坐标,第三个参数是半径,第四个参数是对颜色等外观方面的设置

自定义属性

在valus下:申明我们的属性,format是说明类型,比如这里的类型就是尺寸类型比如sp,dp;

然后在XML文件里面去定义值;

在构造方法里去设置默认值;

public xxview(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.xxview);
int  defalutSize = a.getDimensionPixelSize(R.styleable.xxview_defaultsize, 100);
a.recycle();
}

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.xxview);:用来从 XML 中解析你自定义的属性集合 xxview;

a.getDimensionPixelSize(R.styleable.xxview_defaultsize, 100);这里获取的就是 XML 里 <xxview app:defaultsize="150dp" /> 的值,如果 XML 没有写这个属性,就用 第二个参数 100 当默认值;

a.recycle();回收这个对象;

本次分享到此结束;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912647.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GPT入门】第58课 感性认识Imdeploy介绍与实践 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

怎么为网站做外链企业网站建设的服务类型有哪些

欧洲证券与市场管理局&#xff08;ESMA&#xff09;宣布&#xff0c;欧洲监管机构&#xff08;EBA、EIOPA和ESMA - 即ESA的联合上诉委员会&#xff09;一致决定驳回迪拜商品清算公司&#xff08;DCCC&#xff09;对ESMA提起的上诉&#xff0c;并因此确认ESMA决定撤销其认可。DC…

网站meta模板网站关键词seo推广公司哪家好

Problem: 蓝桥杯 完全二叉树的权值 文章目录 思路解题方法前缀和双指针 复杂度前缀和Code双指针Code 思路 这个问题是关于完全二叉树的权值。完全二叉树的特性是&#xff0c;除了最后一层外&#xff0c;其他各层的节点数都达到最大&#xff0c;且最后一层从左向右连续。在这个问…

广西桂林网站建设搭建集团网站

主要针对英文文献 1 基本环境 连字符 不同长度的"-"表示不同含义。 一个"-"长度的连字符用于词中两个"-"长度的连字符常用于制定范围三个"-"长度的连字符是破折号数学中的负数要用数学环境下的-得到 强调 在正式文章中, 通常不…

北京网站搜索优化WordPress对接阿里云cdn

一、LeetCode 491.递增子序列 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0491.%E9%80%92%E5%A2%9E%E5%AD%90%E5%BA%8F%E5%88%97.html 状态&#xff1a;已解决 1.思路 这道题看似和90题差不多&#xff0c;都是求子集并且有重复元素&#xff0c;但实则…

广州网站建设小程序开发做积分网站

目录 一、选择题二、编程题1、字符串中找出连续最长的数字串2、数组中出现次数超过一半的数字 一、选择题 1、以下程序的输出结果是&#xff08;&#xff09; #include <stdio.h> int main() {char a[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, * p;int i;i 8;p a i;p…

照片管理网站模板下载wordpress官网入口中文

目的&#xff1a;在 ipad 上安装 ipa 文件 首先需要在 mac 端安装 itools pro 下载地址&#xff1a;https://www.thinkskysoft.com/itools/ 然后下载 ipa > 需要有签名的&#xff0c;不然安装不了 然后用数据线连接 ipad 和 mac&#xff0c;应用 -> 安装

兰州网站建设推广报价温州网站开发多少钱

1.简介 在实际工作中&#xff0c;我们经常会听到数据库的性能和稳定性等等&#xff0c;这些有时候也需要测试工程师去评估和测试&#xff0c;上一篇文章主要介绍了jmeter连接和创建数据库测试计划的过程,在文中通过示例和代码非常详细地介绍给大家&#xff0c;希望对各位小伙伴…

不定高元素动画实现方案(下)

最近接了一个需求,需要实现一个列表,列表可展开收起,展开收起需要有一个动画效果,而列表个数不定且每项内容高度也不固定,所以是一个不定高的收起展开效果,于是特意抽时间尝试了一些动画实现方案,特此记录前情 …

Zabbix7 监控USG6300E 并发IPv4会话数 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

商城网站开发 多少钱哪个网站可以接任务做兼职

文章目录 1 untiy和网页相互通信2 打开新页面&#xff08;同标签页和新标签页&#xff09;3 获取网页的URL4 解析Url内的参数5 后处理与色彩空间问题 1 untiy和网页相互通信 看这个文章 2 打开新页面&#xff08;同标签页和新标签页&#xff09; 先看本文untiy和网页相互通信…

网站推广专员面试少儿编程加盟店8

此项目模板是使用Create React App构建的&#xff0c;它提供了一种简单的方法来启动React项目而无需构建配置。 使用Create-React-App构建的项目包括对ES6语法的支持&#xff0c;以及几种非官方/尚未最终形式的Javascript语法 先看效果 这个例子可以帮助你深入理解在 Redux 中 …

网站开发实训教程jsp网站开发介绍

需要使用到 Pretty Json插件。 一、安装方法 sublime 下&#xff0c;按快捷键 Comand control p&#xff0c; 输入install Package,然后回车 等几秒钟&#xff0c;加载启动进程完毕后弹出的页面中输入pretty json, 然后回车 等待几秒钟&#xff0c;可以查看Sublime 最下面的…

做自我介绍的网站的图片素材龙岩淘宝设计

Description Input 第一行为两个整数n, m。第二行有n个整数&#xff0c;为a1&#xff0c;a2, …, an。 Output 包含n行&#xff0c;每行m个1~nm的正整数&#xff0c;各不相同&#xff0c;以空格分开。如果有多解&#xff0c;输出任意一组解&#xff1b;如果无解&#xff0c;输出…

深圳知名网站设计公司排名郑州市城乡建设局官网

RBD Exploded View&#xff08;与Exploded View SOP类似&#xff09;从中心炸开几何体&#xff0c;以更好查看被破碎和约束的碎块&#xff1b; 可视化高精度和低精度几何体的不同&#xff0c;Show Proxy Geometry显示代理几何体&#xff1b; Show Constraints显示约束&#xff…

淮安软件园有做网站的吗软件定制开发的发展前景

文章速览 1、添加节点核心代码示例 2、展开节点核心代码示例注意 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区&#xff01; 谢谢~ 1、添加节点 核心代码 TreeView.Nodes.Add()示例 foreach (var item in content){…

丘受网站谁做的网球吧东莞网站推广优化网上推广公司

绝对路径使用&#xff1a; 在项目中build文件夹下的webpack.base.conf.js的 使用如下&#xff1a; import mock from /mock/mock.js; html 相对路径使用 1. 当需要引用 同一目录下的文件&#xff0c;直接输入文档, 如下 <img src”bg.jpg” /> 2、当需要引用下一级目录…

做网站接电话一般要会什么镇江建筑公司排名最新

目录 一 用户账号与组账号 ①Linux中每个用户账号是通过 UID来唯一标识的 账户类型UID号描述特点超级管理员0权限受到限制的用户程序用户 1-499 &#xff08;CentOS 6以前&#xff09; 1-999 &#xff08;CentOS 7以后&#xff09; 不登录的用户&#xff0c;系统默认的情况拥…

网站建设的目标客户网站建设主流语言

pytdx 分笔 数据 https://rainx.gitbooks.io/pytdx/content/pytdx_hq.html 「 通达信 」的基本使用及常用设置 https://zhuanlan.zhihu.com/p/558652417 通达信功能介绍&#xff1a;还没用过“超级盘口”&#xff1f;你损失大了&#xff01; https://baijiahao.baidu.com/s?i…

F010 Vue+Flask豆瓣图书推荐大素材可视化平台系统源码

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …