Android:创建自定义View

点击查看创建自定义view官网文档

一、简介

设计良好的自定义视图与任何其他精心设计的类一样。它通过一个简单的接口封装一组特定的功能,高效使用 CPU 和内存,诸如此类。除了是一个精心设计的类之外,自定义视图还必须执行以下操作:

  • 符合 Android 标准。
  • 提供适用于 Android XML 布局的自定义可设置样式属性。
  • 发送无障碍事件。
  • 与多种 Android 平台兼容。

Android 框架提供了一组基类和 XML 标记,以帮助您创建满足上述所有要求的视图。接下来将讨论如何使用 Android 框架创建视图类的核心功能。

您可以在自定义视图组件中找到更多信息。

二、子类化视图

Android 框架中定义的所有视图类都会扩展 View。您的自定义视图还可以直接扩展 View,或者您可以通过扩展某个现有视图子类(如 Button)来节省时间。

如需允许 Android Studio 与视图交互,您必须至少提供一个接受 Context 和 AttributeSet 对象作为参数的构造函数。此构造函数允许布局编辑器创建和编辑视图的实例。

class PieChart : View {constructor(context: Context) : super(context)constructor(context: Context, attrs: AttributeSet) : super(context, attrs)constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
}

三、定义自定义属性

如需向界面添加内置 View,请在 XML 元素中指定,并使用元素属性控制其外观和行为。您还可以使用 XML 添加自定义视图并为其设置样式如需在自定义视图中启用此行为,请执行以下操作:

  • 在 资源元素中为视图定义自定义属性。
  • 为 XML 布局中的属性指定值。
  • 在运行时检索属性值。
  • 将检索到的属性值应用于您的视图。

本部分将介绍如何定义自定义属性并指定其值。下一部分将介绍在运行时检索和应用值。

如需定义自定义属性,请向项目添加 资源。通常的做法是将这些资源放在 res/values/attrs.xml 文件中。下面是一个 attrs.xml 文件示例:

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="PieChart"><attr name="showText" format="boolean" /><attr name="labelPosition" format="enum"><enum name="left" value="0"/><enum name="right" value="1"/></attr></declare-styleable>
</resources>

为避免必须重复冗长的命名空间 URI,该示例使用了 xmlns 指令。此指令将别名 custom 分配给命名空间 http://schemas.android.com/apk/res/com.example.customviews。 您可以为命名空间选择所需的任何别名。

注意将自定义视图添加到布局的 XML 标记的名称。它是自定义视图类的完全限定名称。如果您的视图类是内部类,请使用视图外部类的名称进一步限定它。 例如,PieChart 类有一个名为 PieView 的内部类。如需使用此类中的自定义属性,请使用 com.example.customviews.charting.PieChart$PieView 标记。

四、应用自定义属性

通过 XML 布局创建视图时,XML 标记中的所有属性都会从资源包中读取,并作为 AttributeSet 传递到视图的构造函数中。 虽然可以直接从 AttributeSet 读取值,但这样做有一些弊端:

  • 系统不会解析属性值中的资源引用。
  • 因此不会应用样式。

请改为将 AttributeSet 传递给 obtainStyledAttributes()。 此方法会传回一个 TypedArray 数组,其中包含已解除引用并设置了样式的值。

Android 资源编译器做了大量工作,以便您更轻松地调用 obtainStyledAttributes()。对于 res/ 目录中的每个 <declare-styleable> 资源,生成的 R.java 会同时定义属性 ID 数组和一组常量(用于定义数组中每个属性的索引)。您可以使用预定义的常量从 TypedArray 中读取属性。以下代码展示了 PieChart 类如何读取其属性:

init {context.theme.obtainStyledAttributes(attrs,R.styleable.PieChart,0, 0).apply {try {mShowText = getBoolean(R.styleable.PieChart_showText, false)textPos = getInteger(R.styleable.PieChart_labelPosition, 0)} finally {recycle()}}
}

请注意,TypedArray 对象是共享资源,必须在使用后回收。

请注意,setShowText 会调用 invalidate() 和 requestLayout()。这些调用对于确保视图可靠运行至关重要。在对视图属性进行任何可能会改变其外观的更改后,您需要使该视图失效,以便系统知道需要重新绘制该视图。同样,如果属性的变化方式可能会影响视图的大小或形状,您需要请求新的布局。忘记这些方法调用可能会导致难以发现的 bug。

自定义视图还必须支持事件监听器来传达重要事件。例如,PieChart 公开了一个名为 OnCurrentItemChanged 的自定义事件,以通知监听器用户旋转了饼图以将焦点放在新的饼图切片上。

公开属性和事件是很容易忘记的,尤其是当您是自定义视图的唯一用户时。花点时间仔细定义视图界面可以降低未来的维护成本。一种好的做法是始终公开任何会影响自定义视图的可见外观或行为的属性。

五、在设计时充分考虑无障碍功能

您的自定义视图必须支持众多用户。包括妨碍他们看到或使用触摸屏的残障用户。如需为残障用户提供支持,请执行以下操作:

  • 使用 android:contentDescription 属性为输入字段添加标签。
  • 根据需要调用 sendAccessibilityEvent() 来发送无障碍事件。
  • 支持备用控制器,例如方向键或轨迹球。

如需详细了解如何创建易于访问的视图,请参阅 让应用使用起来更没有障碍。

六、PieChart.kt代码

在这里插入图片描述

class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs) {private var mShowText: Boolean = falseprivate var textPos: Int = 0init {context.theme.obtainStyledAttributes(attrs,R.styleable.PieChart,0, 0).apply {try {mShowText = getBoolean(R.styleable.PieChart_showText, false)textPos = getInteger(R.styleable.PieChart_labelPosition, 0)} finally {recycle()}}}fun isShowText(): Boolean {return mShowText}fun setShowText(showText: Boolean) {mShowText = showTextinvalidate()requestLayout()}
}

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

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

相关文章

LinuxShell编程2——shell搭建Discuzz论坛网站

目录 一、环境准备 ①准备一台虚拟机 ②初始化虚拟机 1、关闭防火墙 2、关闭selinux 3、配置yum源 4、修改主机名 二、搭建LAMP环境 ①安装httpd(阿帕奇apache&#xff09;服务器 查看是否安装过httpd 启动httpd 设置开机启动 查看状态 安装网络工具 测试 ②安装…

【CUDA】thrust进行前缀和的操作

接上篇文章&#xff0c;可以发现使用CUDA提供的API进行前缀和扫描时&#xff0c;第一次运行的时间不如共享内存访问&#xff0c;猜测是使用到了全局内存。 首先看调用逻辑&#xff1a; thrust::inclusive_scan(thrust::device, d_x, d_x N, d_x);第一个参数指定了设备&#x…

Spark和Hadoop作业之间的区别

Spark和Hadoop是两种广泛使用的大数据处理框架&#xff0c;各自有着不同的设计理念和使用场景。以下是它们之间的主要区别&#xff1a; 架构和处理模式 计算模型&#xff1a; Hadoop&#xff1a;基于MapReduce编程模型。任务分为Map和Reduce两个阶段&#xff0c;处理批量数据较…

安全加固:Eureka服务实例安全组配置全攻略

安全加固&#xff1a;Eureka服务实例安全组配置全攻略 在微服务架构中&#xff0c;服务的安全性是保障系统稳定性和数据完整性的关键。Eureka作为Netflix开源的服务发现框架&#xff0c;不仅提供服务注册与发现功能&#xff0c;还可以通过配置服务实例安全组来增强安全性。本文…

深入了解 Oracle 版本命名中的 i、g 及 c

深入了解 Oracle 版本命名中的 i、g 及 c 在 Oracle 数据库的版本命名中&#xff0c;经常会看到版本号码后面跟着一些特定的字母&#xff0c;如 “i”、“g” 和 “c”。这些字母代表了 Oracle 数据库版本的特定发行类型或更新。在本文中&#xff0c;我们将深入探讨这些字母的…

STM32 - FLASH 笔记

STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&#xff0c;通过闪存存储器接口&#xff08;外设&#xff09;可以对程序存储器和选项字节进行擦除和编程 读写FLASH的用途&#xff1a; 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 通过在程序…

java设计模式(十五)命令模式(Command Pattern)

1、模式介绍&#xff1a; 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;其主要目的是将请求封装成一个对象&#xff0c;从而允许使用不同的请求、队列或者日志来参数化其他对象。这种模式使得命令的请求者和实现者解耦。 2、应用场景&…

【ARM】MDK-服务器与客户端不同网段内出现卡顿问题

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录不同网段之间的请求发送情况以及MDK网络版license文件内设置的影响。 2、 问题场景 客户使用很久的MDK网络版&#xff0c;在获取授权时都会出现4-7秒的卡顿&#xff0c;无法对keil进行任何操作&#xff0c;彻底…

Java 中如何实现接口和抽象类,它们的主要区别是什么?

在Java编程中&#xff0c;接口&#xff08;Interface&#xff09;和抽象类&#xff08;Abstract Class&#xff09;是实现抽象化的两种重要手段&#xff0c;它们帮助我们设计更灵活、可扩展的代码结构。 下面&#xff0c;我将从定义、实现方式、主要区别以及应用场景等方面&am…

力扣第七题——整数反转

题目介绍 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 示例 1&#xff1…

ChatGPT Mac App 发布!

2024 年 6 月&#xff0c;OpenAI 的大语言模型 ChatGPT 的 Mac 客户端与 ChatGPT-4o 一起发布了。ChatGPT Mac 户端可以让用户直接在 Mac 电脑上使用 ChatGPT 进行对话。它提供了一个简单易用的用户界面&#xff0c;用户可以在其中输入文本或语音指令&#xff0c;并接收模型生成…

心跳检测的艺术:Eureka服务发现中的智能配置

心跳检测的艺术&#xff1a;Eureka服务发现中的智能配置 在微服务架构中&#xff0c;服务发现是确保服务之间可以相互通信的关键机制。Eureka作为Netflix开源的服务发现框架&#xff0c;提供了一种简单而高效的服务注册与发现机制。然而&#xff0c;为了维持服务的可用性和稳定…

python基础知识点(蓝桥杯python科目个人复习计划68)

做一下算法赛题目。 第一题&#xff1a;银色情人节 题目描述&#xff1a; 七月的阳光炙热灿烂&#xff0c;智慧的火花闪耀天际。7.14银色情人节&#xff0c;是传递爱意的美好时光。 分享甜蜜&#xff0c;珍藏浪漫。正是彼此的真心相伴&#xff0c;才有了我们温馨美满的情感。…

vue检测页面手指滑动距离,执行回调函数,使用混入的语法,多个组件都可以使用

mixin.ts 定义滑动距离的变量和检测触摸开始的方法&#xff0c;滑动方法&#xff0c;并导出两个方法 sendTranslateX.value > 250 && sendTranslateY.value < -100是向上滑动&#xff0c;满足距离后执行回调函数func&#xff0c;并在一秒内不再触发&#xff0c;一…

【重走编程路】设计模式概述(七) -- 外观模式、组合模式、享元模式

文章目录 前言10. 外观模式&#xff08;Facade&#xff09;定义解决方案为什么使用外观模式应用场景优缺点 11. 组合模式&#xff08;Composite&#xff09;定义解决方案应用场景优缺点 12. 享元模式&#xff08;Flyweight&#xff09;定义解决方案应用场景优缺点 前言 结构型…

【Python百日进阶-Web开发-音频】Day702 - librosa安装及模块一览表

文章目录 一、Librosa简介与安装1.1 Librosa是什么1.2 Librosa官网 二、Librosa安装2.1 安装Librosa 三、安装ffmpeg3.1 ffmpeg官网下载3.2 ffmpeg安装3.2.1 解压3.2.2 添加环境变量3.2.3 测试ffmpeg是否安装成功 四、Librosa 库模块一览4.1 库函数结构4.2 Audio processing&am…

C++相关概念和易错语法(21)(虚函数、协变、析构函数的重写)

多态的核心是虚函数&#xff0c;本文从虚函数出发&#xff0c;根据原理慢慢推进得到结论&#xff0c;进而理解多态 1.虚函数 先看一下下面的代码&#xff0c;想想什么导致了这个结果 #include <iostream> using namespace std;class A { public:virtual void test(){co…

x264 编码过程中视频相关数据流转分析

介绍 x264编码器的编码过程是一个复杂且多阶段的流程,涉及多个步骤,每个步骤都对视频数据进行特定的处理。以下是x264编码过程的一般数据流和关键步骤的分析: 输入帧处理: 输入原始视频帧到编码器。帧可能首先被转换到内部颜色空间(如YUV420P)。分析与预处理: 进行宏块级…

元服务体验-服务发现

服务发现&#xff0c;无论线上或线下的方式都可以发现元服务。 线上&#xff1a;基于用户意图。从精准意图的搜索、用户事件触发的推荐到主动探索等场景。用户可以在设备的负一屏、全局搜索、应用市场、桌面等场景发现元服务。 线下&#xff1a;用户在 HarmonyOS Connect标签…

华为HCIP Datacom H12-821 卷39

1.填空题 请2001 :0DB8:0000:C030:0000: 000: 09A0:CDEF地址进行压缩。() (若答案中存在字母&#xff0c;请采用大写格式) 参考答案&#xff1a;2001 :DB8:0:C030: :9A0:CDEF 解析&#xff1a; IPv6地址的表示方法 IPv6地址总长度为128比特&#xff0c;通常分为8组&#xff0c…