自定义控件视图篇(一)测量与布局

在自定义控件的开发过程中,"视图篇"的测量与布局是非常关键的步骤,这直接决定了控件的尺寸、位置以及子视图的排列方式。下面我将详细介绍测量和布局的过程,以及如何在自定义控件中正确实现这些步骤。

视图的测量 (onMeasure)

在 Android 中,每个视图都会经历测量过程来确定其尺寸。这个过程发生在 onMeasure() 方法中。系统会调用此方法并传入两个参数:MeasureSpecs。这两个参数分别代表了水平方向和垂直方向上的约束。

MeasureSpec 包含三个部分:

  • MeasureSpec.UNSPECIFIED:没有指定大小,视图可以自由扩展。
  • MeasureSpec.EXACTLY:视图应该严格遵守给定的大小。
  • MeasureSpec.AT_MOST:视图不应超过给定的大小,但可以更小。

MeasureSpec 的值由 MeasureSpec.getSize()MeasureSpec.getMode() 方法获取。在 onMeasure() 中,你需要根据这些约束计算出你的视图的理想尺寸,并调用 setMeasuredDimension() 方法来设置视图的宽高。

视图的布局 (onLayout)

一旦视图被测量,下一步就是布局。onLayout() 方法负责决定视图内部元素的位置。当视图的大小改变或者其父视图调用了 requestLayout() 方法时,onLayout() 方法会被调用。

onLayout() 方法中,你需要遍历所有的子视图,并使用 layout() 方法来确定它们的位置。layout() 方法接收四个参数:左边界、上边界、右边界和下边界。

实现自定义视图的测量和布局

下面是一个简单的自定义视图类,实现了测量和布局的基本逻辑:

Java

1public class CustomView extends View {
2
3    public CustomView(Context context) {
4        super(context);
5    }
6
7    public CustomView(Context context, AttributeSet attrs) {
8        super(context, attrs);
9    }
10
11    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
12        super(context, attrs, defStyleAttr);
13    }
14
15    @Override
16    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
17        // 计算理想宽度和高度
18        int idealWidth = ...; // 你的宽度计算逻辑
19        int idealHeight = ...; // 你的高度计算逻辑
20
21        // 获取宽度和高度的测量模式
22        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
23        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
24
25        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
26        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
27
28        // 根据测量模式和理想尺寸计算最终尺寸
29        int finalWidth = 0;
30        int finalHeight = 0;
31
32        if (widthMode == MeasureSpec.EXACTLY) {
33            finalWidth = widthSize;
34        } else {
35            finalWidth = idealWidth;
36        }
37
38        if (heightMode == MeasureSpec.EXACTLY) {
39            finalHeight = heightSize;
40        } else {
41            finalHeight = idealHeight;
42        }
43
44        setMeasuredDimension(finalWidth, finalHeight);
45    }
46
47    @Override
48    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
49        // 布局子视图
50        for (int i = 0; i < getChildCount(); i++) {
51            View child = getChildAt(i);
52            // 计算子视图的位置
53            int childLeft = ...; // 子视图左边界
54            int childTop = ...; // 子视图上边界
55            int childRight = ...; // 子视图右边界
56            int childBottom = ...; // 子视图下边界
57            child.layout(childLeft, childTop, childRight, childBottom);
58        }
59    }
60}

注意事项

  • 在 onMeasure() 中,务必考虑到 MeasureSpec 模式,不要忽略父视图给出的约束。
  • 在 onLayout() 中,确保子视图的坐标计算正确,避免重叠或超出边界。
  • 考虑到性能问题,避免在 onMeasure() 和 onLayout() 中执行复杂的计算或操作,因为它们可能会频繁被调用。

通过正确实现测量和布局,你可以创建出复杂而精确的自定义控件,满足各种不同的需求。

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

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

相关文章

2021版本的idea热部署的详细步骤

背景&#xff1a;我是自己用的是2021版本的idea,然后发现跟2023版本的热部署不太一样&#xff0c;所以&#xff0c;今天自己出一期这样的文章吧&#xff01;&#xff01;&#xff01;其他人配置的时候根据自己的情况&#xff0c;来阅读吧&#xff01; 第一步&#xff1a;方式一…

MyBatis是如何分页的及原理

MyBatis 是一种持久层框架&#xff0c;支持通过配置文件和注解将 SQL 映射为 Java 对象。在实际开发中&#xff0c;查询数据时经常需要进行分页处理。 MyBatis 也提供了支持分页的方案&#xff0c;其主要思路是使用 Limit 偏移量和限制个数&#xff0c;来获取指定数量的数据。下…

音视频入门基础:H.264专题(10)——FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析

一、引言 FFmpeg源码对AnnexB包装的H.264码流解码过程中&#xff0c;通过ff_h2645_extract_rbsp函数拿到该H.264码流中的某个NALU的NALU Header RBSP后&#xff08;具体可以参考&#xff1a;《FFmpeg源码&#xff1a;ff_h2645_extract_rbsp函数分析》&#xff09;&#xff0c…

【沐风老师】3DMAX建筑体块生成插件BuildingBlocks使用方法详解

BuildingBlocks建筑体块生成插件使用方法详解 听说你还在手动建配景楼&#xff1f;有了BuildingBlocks这个插件&#xff0c;一分钟搞定喔&#xff01; 3DMAX建筑体块生成插件BuildingBlocks&#xff0c;用于快速自定义街道及生成配景楼区块。 【适用版本】 3dMax2019及更高版…

空间分析在3D应用中的革命:提升投资回报与业务价值

在3D应用的浪潮中&#xff0c;空间分析技术正成为提升用户体验、优化业务决策和解决复杂问题的关键工具。本文将深入探讨空间分析如何通过提供深度用户行为洞察和数据可视化&#xff0c;增强3D应用的实际效益和市场竞争力。 一、空间分析的概念与背景 Tony Bevilacqua&#x…

分布式I/O从站的认知

为什么需要分布式I/O从站&#xff1f; 当PLC与控制机构距离过远时&#xff0c;远距离会带来信号干扰&#xff0c;分布式I/O从站只需要一个网络线缆连接。 ET200分布式I/O从站家族 体积紧凑、功能强大。 ET200SP ET200M ET200S ET200iSP ET200 AL ET200pro ET200 eco PN 通讯协议…

DSSM双塔特征交互

传统的DSSM双塔无法在早期进行user和item侧的特征交互&#xff0c;这在一定程度上降低了模型性能。我们想要对双塔模型进行细粒度的特征交互&#xff0c;同时又不失双塔模型离线建向量索引的解耦性。下面介绍两篇这方面的工作。 美团-Dual Augmented Two-tower 在user和item的特…

1. CSS Grid 网格布局教程

CSS Grid 网格布局教程 一、概述 网格布局&#xff08;Grid&#xff09;是最强大的 CSS 布局方案。 它将网页划分成一个个网格&#xff0c;可以任意组合不同的网格&#xff0c;做出各种各样的布局。以前&#xff0c;只能通过复杂的 CSS 框架达到的效果&#xff0c;现在浏览器…

linux工具应用_VERDI

verdi 1. 基础知识1.1 verdi介绍1.2 fsdb文件2. fsdb dump2.1 1st step-设置环境变量LD_LIBRARY_PATH2.2 2nd step-xrun仿真命令2.3 3rd step-仿真过程中调用fsdb函数dump波形2.3.1 在testbench、top.sv中调用fsdb函数2.3.2 在tcl脚本中用xrun的dump指令(同样要调用fsdb函数)2.…

Scrapy crawl spider 停止工作

Scrapy是一个用于爬取网站数据的流行框架&#xff0c;有时爬虫可能会停止工作&#xff0c;这通常是由多种原因引起的。以下是一些常见问题及其解决方法&#xff1a; 1、问题背景 用户在使用 Scrapy 0.16.2 版本进行网络爬取时遇到问题&#xff0c;具体表现为爬虫在运行一段时间…

Android 开发中 C++ 和Java 日志调试

在 C 中添加堆栈日志 先在 Android.bp 中 添加 ‘libutilscallstack’ shared_libs:["liblog"," libutilscallstack"]在想要打印堆栈的代码中添加 #include <utils/CallStack.h> using android::CallStack;// 在函数中添加 int VisualizerLib_Crea…

生物素结合金纳米粒子(Bt@Au-NPs ) biotin-conjugated Au-NPs

一、定义与特点 定义&#xff1a;生物素结合金纳米粒子&#xff0c;简称BtAu-NPs或biotin-conjugated Au-NPs&#xff0c;是指通过特定的化学反应或物理方法将生物素修饰到金纳米粒子表面&#xff0c;形成稳定的纳米复合材料。 特点&#xff1a; 高稳定性&#xff1a;生物素的修…

重构功能带来的配套改造查找思路

最近在重构项目中的一个基础配置功能&#xff0c;这个功能因为后续的业务变化和最初的缺陷设计导致非常难维护和扩展&#xff0c;使用起来也比较费劲&#xff0c;所以决定花一段时间来对它进行重构&#xff0c;去除一些用不到的设计&#xff0c;简化了使用方式和配置方式&#…

RabbitMQ 迁移

文章目录 1. 导出配置2. 导入配置3. 导出和导入定义&#xff08;如果不需要消息&#xff09;导出定义导入定义 注意事项参考文档 要将 RabbitMQ 的配置&#xff08;包括vhost、exchange等&#xff09;从一个实例迁移到另一个实例&#xff0c;您可以遵循以下步骤&#xff1a; 1.…

【VUE基础】VUE3第七节—Vue Router路由基础

Vue Router 是 Vue 官方的客户端路由解决方案。 客户端路由的作用是在单页应用 (SPA) 中将浏览器的 URL 和用户看到的内容绑定起来。当用户在应用中浏览不同页面时&#xff0c;URL 会随之更新&#xff0c;但页面不需要从服务器重新加载。 Vue Router 基于 Vue 的组件系统构建&…

LabVIEW在半导体自动化测试中的应用

半导体制造的复杂性和精密度要求极高&#xff0c;每一个生产步骤都需要严格的控制和监测。自动化测试设备在半导体制造中起到了关键作用&#xff0c;通过精密测量和数据分析&#xff0c;确保产品质量和生产效率。本文介绍如何使用LabVIEW结合研华硬件&#xff0c;开发一个用于半…

C语言编程3:运算符,运算符的基本用法

C语言3&#x1f525;&#xff1a;运算符&#xff0c;运算符的基本用法 一、运算符&#x1f33f; &#x1f387;1.1 定义 运算符是指进行运算的动作&#xff0c;比如加法运算符"“&#xff0c;减法运算符”-" 算子是指参与运算的值&#xff0c;这个值可能是常数&a…

自动化测试高级控件交互方法:TouchAction、触屏操作、点按,双击,滑动,手势解锁!

在自动化测试领域中&#xff0c;TouchAction 是一种非常强大的工具&#xff0c;它允许我们模拟用户在设备屏幕上的各种触摸事件。这种模拟不仅限于简单的点击操作&#xff0c;还包括滑动、长按、多点触控等复杂的手势。 点按与双击 点按和双击是触屏设备上最基本的操作之一。…

使用 Qt 和 ECharts 进行数据可视化

文章目录 示例图表预览折线图散点图柱状图使用 Qt 和 ECharts 进行数据可视化一、准备工作1. 安装 Qt2. 准备 ECharts二、在 Qt 中使用 ECharts1. 创建 Qt 项目2. 配置项目文件3. 在 UI 中添加 WebEngineView4. 加载 ECharts三、创建折线图、散点图和柱状图1. 折线图2. 散点图3…

Jupyter Notebook的安装教程

以下是一个详细的 Jupyter Notebook 安装教程&#xff0c;适用于大多数操作系统&#xff1a; Windows 系统 1. 安装 Python 访问 Python 官网&#xff0c;下载并安装适合你系统的 Python 版本。在安装过程中&#xff0c;确保勾选“Add Python 3.x to PATH”选项&#xff0c;…