第10章 自定义控件

第 10 章 自定义控件

bilibili学习地址
github代码地址
本章介绍App开发中的一些自定义控件技术,主要包括:视图是如何从无到有构建出来的、如何改造已有的控件变出新控件、如何通过持续绘制实现简单动画。然后结合本章所学的知识,演示了一个实战项目“广告轮播”的设计与实现。

10.1 视图的构建过程

本节介绍了一个视图的构建过程,包括:如何编写视图的构造方法, 4 种构造方法之间有什么区别;如何测量实体的实际尺寸,包含文本、图像、线性视图的测量办法;如何利用画笔绘制视图的界面,并说明onDraw方法与dispatchDraw方法的先后执行顺序。

10.1.1 视图的构造方法

Android自带的控件往往外观欠佳,开发者常常需要修改某些属性,比如按钮控件Button就有好几个问题,其一字号太小,其二文字颜色太浅,其三字母默认大写。于是XML文件中的每个Button节点都得添加textSize、textColor、textAllCaps 3个属性,以便定制按钮的字号、文字颜色和大小写开关,就像下面这样:

<Buttonandroid:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello World"android:textAllCaps="false" android:textColor="#000000" android:textSize="20sp"/>

如果只是一两个按钮控件倒还好办,倘若App的许多页面都有很多Button,为了统一按钮风格,就得给全部Button节点都加上这些属性。要是哪天产品大姐心血来潮,命令所有按钮统统换成另一种风格,如此多的Button节点只好逐个修改过去,令人苦不堪言。为此可以考虑把按钮样式提炼出来,将统一的按钮风格定义在某个地方,每个Button节点引用统一样式便行。为此打开res/values目录下的styles.xml,

在resources节点内部补充如下所示的风格配置定义:

<style name="CommonButton"><item name="android:textAllCaps">false</item> <item name="android:textColor">#000000</item> <item name="android:textSize">20sp</item> 
</style>

接着回到XML布局文件中,给Button节点添加形如“style=“@style/样式名称””的引用说明,表示当前控件将覆盖指定的属性样式,添加样式引用后的Button节点如下所示:

(完整代码见chapter10\src\main\res\layout\activity_custom_button.xml)

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是来自style的Button" 
style="@style/CommonButton"/>

运行测试App,打开按钮界面如图10-1所示,对比默认的按钮控件,可见通过style引用的按钮果然变了

个模样。以后若要统一更换所有按钮的样式,只需修改styles.xml中的样式配置即可。

然而样式引用仍有不足之处,因为只有Button节点添加了style属性才奏效,要是忘了添加style属性就不管用了,而且样式引用只能修改已有的属性,不能添加新属性,也不能添加新方法。若想更灵活地定制控件外观,就要通过自定义控件实现了。

自定义控件听起来很复杂的样子,其实并不高深,不管控件还是布局,它们本质上都是一个Java类,也拥有自身的构造方法。以视图基类View为例,它有 4 个构造方法,分别是:

( 1 )带一个参数的构造方法public View(Context context),在Java代码中通过new关键字创建视图对

象时,会调用这个构造方法。

( 2 )带两个参数的构造方法public View(Context context, AttributeSet attrs),在XML文件中添加视图节点时,会调用这个构造方法。

( 3 )带 3 个参数的构造方法public View(Context context, AttributeSet attrs, int defStyleAttr),采取默认的样式属性时,会调用这个构造方法。如果defStyleAttr填 0 ,则表示没有默认的样式。

( 4 )带 4 个参数的构造方法public View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes),采取默认的样式资源时,会调用这个构造方法。如果defStyleRes填 0 ,则表示无样式资源。

以上的 4 种构造方法中,前两种必须实现,否则要么不能在代码中创建视图对象,要么不能在XML文件中添加视图节点;至于后两种构造方法,则与styles.xml中的样式配置有关。先看带 3 个参数的构造方法,第 3 个参数defStyleAttr的意思是指定默认的样式属性,这个样式属性在res/values下面的attrs.xml中配置,如果values目录下没有attrs.xml就创建该文件,并填入以下的样式属性配置:

<declare-styleable name="CustomButton"><attr name="customButtonStyle" format="reference" /> 
</declare-styleable>

以上的配置内容表明了属性名称为customButtonStyle,属性格式为引用类型reference,也就是实际样式在别的地方定义,这个地方便是styles.xml中定义的样式配置。可是customButtonStyle怎样与styles.xml里的CommonButton样式关联起来呢?每当开发者创建新项目时,AndroidManifest.xml的application节点都设置了主题属性,通常为android:theme=“@style/AppTheme”,这个默认主题来自于styles.xml的AppTheme,打开styles.xml发现文件开头的AppTheme配置定义如下所示:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item>
</style>

原来App的默认主题源自Theme.AppCompat.Light.DarkActionBar,其中的Light表示这是亮色主题, DarkActionBar表示顶部标题栏是暗色的,内部的 3 个color项指定了该主题采用的部分颜色。现在给AppTheme添加一项customButtonStyle,并指定该项的样式为@style/CommonButton,修改后的

AppTheme配置示例如下:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item>
</style>

接着到Java代码包中编写自定义的按钮控件,控件代码如下所示,注意在defStyleAttr处填上默认的样式

属性R.attr.customButtonStyle。

(完整代码见chapter10\src\main\java\com\example\chapter10\widget\CustomButton.java)

public class CustomButton extends Button {private final static String TAG = "CustomButton";public CustomButton(Context context) {super(context);}public CustomButton(Context context, AttributeSet attrs) {this(context, attrs, R.attr.customButtonStyle);}public CustomButton(Context context, AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr);} 
}

然后打开测试界面的XML布局文件activity_custom_button.xml,添加如下所示的自定义控件节点

CustomButton:

(完整代码见chapter10\src\main\res\layout\activity_custom_button.xml)

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

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

相关文章

开始使用HBuilderX开发网页

1 给我一个用hbuilderx的理由 首先看一个截图&#xff1a; 现在技术更新太快了&#xff0c;大家伙儿也都用windows10甚至了11了&#xff0c;而我们还在使用熟悉的windows7&#xff0c;这对于编程桌面端没问题的&#xff0c;但是网络编程真实够费劲的了&#xff0c;或者用pytho…

ffmpeg视频滤镜:添加边框-drawbox

滤镜介绍 drawbox 官网链接 > FFmpeg Filters Documentation 这个滤镜会给视频添加一个边框。 滤镜使用 参数 x <string> ..FV.....T. set horizontal position of the left box edge (default "0")y <string&…

单向数据流在 React 中的作用

文章目录 单向数据流在 React 中的作用什么是单向数据流&#xff1f;单向数据流的优势如何实现单向数据流1. 父组件传递 props2. 状态提升 结论 单向数据流在 React 中的作用 什么是单向数据流&#xff1f; 单向数据流是指数据在应用程序中只按照一个方向流动。在 React 中&a…

uniapp学习(008-2 图片模块和分享模块)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第93p-第p103的内容 文章目录 详情页图片问题storage缓存图片网络消耗问题使用计算属性获取详细信息 保存壁纸到…

双十一宠物空气净化器决胜局,希喂、安德迈哪款性价比更高?

秋天到了&#xff0c;新一轮的猫咪换毛季又来了。尽管每天下班很累&#xff0c;但也不得不花上不少时间清理。有时候想偷懒&#xff0c;但身体是第一个反对的。要知道&#xff0c;长期堆积的猫毛除了会破坏家中的干净整洁外&#xff0c;浮毛还会随呼吸进入我们体内&#xff0c;…

工程项目智能化管理平台,SpringBoot框架智慧工地源码,实现工程建设施工可视化、智能化的全过程闭环管理。

智慧工地管理系统的建设以“1个可扩展性平台2个应用端3方数据融合N个智能设备”为原则。以“智、保、安、全”为导向&#xff0c;与工程建设管理信息系统、综合安防平台深度集成&#xff0c;构建统一的标准化工地平台&#xff0c;实现现场人员、车辆、项目、安全、进度等方面的…

springboot 自定义错误页面

自定义错误页面 背景&#xff1a;当我们访问应用程序不存在的接口路径或者参数传递不规范时&#xff0c;springboot 默认提示 如下页面 该页面对用户不友好&#xff0c;我们可以自定义展示错误页来改善。 优化后的简洁效果&#xff0c;可对 html 页面进一步美化&#xff0c;…

SpringBoot 集成RabbitMQ 实现钉钉日报定时发送功能

文章目录 一、RabbitMq 下载安装二、开发步骤&#xff1a;1.MAVEN 配置2. RabbitMqConfig 配置3. RabbitMqUtil 工具类4. DailyDelaySendConsumer 消费者监听5. 测试延迟发送 一、RabbitMq 下载安装 官网&#xff1a;https://www.rabbitmq.com/docs 二、开发步骤&#xff1a;…

低代码统一待办:提升任务管理效率的新模式

低代码平台的魔力 低代码平台通过图形化用户界面和简化开发流程&#xff0c;让用户无需具备深厚的编程知识也能快速构建应用程序。这种技术不仅加速了应用开发速度&#xff0c;还大幅降低了开发成本和复杂度&#xff0c;适合各种规模的企业。 构建统一待办系统的优势 集中化管…

itertools模块的combinations很牛

在 Python 中&#xff0c;combinations 是 itertools 模块提供的一个非常有用的函数&#xff0c;用于生成给定序列的所有可能的组合&#xff08;不考虑顺序&#xff09;。combinations 函数可以生成从长度为 r 的所有子集&#xff0c;其中 r 是一个指定的正整数&#xff0c;表示…

React中管理state的方式

使用useState 使用useReducer 既然已经有了useState&#xff0c;为什么还需要useReducer呢&#xff1f; 那么useReducer是如何将解决这些问题的呢&#xff1f; reducer是如何更新state的呢&#xff1f; reducer的工作方式非常类似JavaScript中的reduce方法&#xff0c;随着时…

CSS网页布局综合练习(涵盖大多CSS知识点)

该综合练习就是为这个学校静态网页设置CSS样式&#xff0c;使其变成下面的模样 其基本骨架代码为&#xff1a; <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content…

放大器的保护机制

在工作中&#xff0c;使用功率放大器或高压放大器这类精密仪器时&#xff0c;为了保护设备不受伤害&#xff0c;确保设备的稳定性和安全性&#xff0c;在设备上需要设置保护机制。保护机制起着至关重要的作用&#xff0c;可以防止设备因过流、过压、过热等因素而受损。放大器的…

JavaSE笔记4】API、包、String类、Object类

目录 一、API 二、包 2.导入不同包下的同名程序 三、String 1. String类是什么&#xff1f; 2. 如何创建String对象?(常用的四种方法&#xff09; 3. String API a. 遍历字符串 b. 判断字符串内容是否相等&#xff1a; c. 截取子串 d. 替换部分内容 e. 匹配子串 f. 匹配开头字…

「C/C++」C/C++ 之 判断语句

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

nrm的使用

在安装nrm之前&#xff0c;要先完成node.js的安装。 1、nrm的介绍 ‌nrm&#xff08;npm registry manager&#xff09;是一个npm源管理器&#xff0c;允许用户在不同npm源之间快速切换。 关于npm和nvm的介绍&#xff0c;详见文章nvm的使用-CSDN博客。 解释&#xff1a;比如…

芯片上音频相关的验证

通常芯片设计公司&#xff08;比如QUALCOMM&#xff09;把芯片设计好后交由芯片制造商&#xff08;比如台积电&#xff09;去生产&#xff0c;俗称流片。芯片设计公司由ASIC部门负责设计芯片。ASIC设计的芯片只有经过充分的验证&#xff08;这里说的验证是FPGA&#xff08;现场…

【论文分享】通过太阳轨迹和街景图像测量不同街道网络方向的太阳辐射及其时空分布

本次我们给大家带来一篇SCI论文的全文翻译。该论文利用街景数据和太阳轨迹模拟技术&#xff0c;揭示了不同方向街道上的太阳辐射在时空上的差异&#xff0c;为城市的可持续发展提供了更有针对性的策略。 【论文题目】 Measuring solar radiation and spatio-temporal distrib…

基于springboot+vue实现的公考知识学习平台 (源码+L文+ppt)4-103

4.1 系统功能结构设计 根据对公考知识学习平台的具体需求分析&#xff0c;把系统可以划分为几个不同的功能模块&#xff1a;管理员可以对系统首页、个人中心、用户管理、讲师管理、在线咨询管理、学习资料管理、讲座信息管理、讲座预约管理、学习论坛、练习自测管理、试题管理…

LabVIEW程序员的真实工作状态是怎样的?

LabVIEW程序员的工作状态通常涉及以下几个方面&#xff1a; 1. 项目开发与设计 需求分析&#xff1a;与客户或团队成员沟通&#xff0c;明确项目需求&#xff0c;制定开发计划。 系统设计&#xff1a;根据需求进行系统架构设计&#xff0c;包括硬件选型和软件模块划分。 2.…