【Android】自定义控件

本文介绍App开发经常涉及的自定义控件相关技术,主要包括自定义视图的过程与步骤、自定义动画的原理与实现、自定义对话框的概念与示例、自定义通知栏的用法与定制,另外介绍四大组件之一的服务Service的生命周期与启停方式。

自定义视图

自定义视图的编码主要由3部分组成:
(1)重写构造函数,初始化该视图的自有属性。
(2)重写测量函数onMeasure,计算该视图的宽与高(一般只有复杂视图才重写该函数)。
(3)重写绘图函数onLayout、onDraw、dispatchDraw,视情况重写3个中的一个或多个。
一般要重写3个构造函数。前面在演示新控件CustomPagerTab时,示例代码给出了3个构造函数(实际只实现了两个),分别是:
(1)只带一个参数的public CustomPagerTab (Context context)。在代码中声明对象时采用该构造函数。
(2)带两个参数的public CustomPagerTab (Context context,AttributeSet attrs)。在布局文件中引用自定义视图时采用该构造函数。

总结一下onLayout、onDraw、dispatchDraw三个函数的区别:
(1)onLayout只能调整子视图的位置,而onDraw和dispatchDraw允许绘制新图形。
(2)onDraw的调用在绘制子视图之前,而dispatchDraw的调用在绘制子视图之后。
(3)onLayout若想立即显示位置调整后的视图,则要调用requestLayout方法;onDraw和dispatchDraw若想立即显示图形绘制后的视图,则要调用invalidate方法。

自定义动画

Runnable接口可声明一连串任务,定义了接下来要做的事情。简单地说,Runnable接口就是一个代码片段。实现Runnable接口只需重写run函数,在该方法内部存放要运行的任务代码。run函数无须显式调用,在启动Runnable实例时就会调用对象的run方法。
尽管基本视图View提供了post与postDelayed方法用于启动Runnable任务,不过实际开发中经常利用Handler启动任务。下面是Handler处理Runnable任务的常见方法说明:
post:立即启动Runnable任务。
postDelayed:延迟若干时间后启动Runnable任务。
postAtTime:在指定时间启动Runnable任务。
removeCallbacks:移除指定的Runnable任务。
计时器是Runnable的一个简单应用,与动画的实现原理相关,如电影每秒播放20帧画面,连起来就是会动的视频,动画的渲染与之同理。

自定义对话框

App界面附着在窗口Window上。大至整个活动页面,小至Toast的提示窗,还有对话框Dialog,都建立在窗口上。如果想熟练掌握对话框,就必须先了解窗口。读者也许对窗口的概念不甚理解,下面从Window的5个常用方法开始介绍。

  • setContentView:设置内容视图。这个方法是不是很熟悉?我们每天打交道的Activity第一句就是setContentView,查看源码后发现内部原来调用了同名方法getWindow().setContentView。

  • setLayout:设置内容视图的宽、高尺寸。

  • setGravity:设置内容视图的对齐方式。

  • setBackgroundDrawable:设置内容视图的背景。

  • findViewById:根据资源ID获取该视图的对象。这个方法每个Activity代码都要用许多遍。查看Activity源码后可以发现该方法也是调用Window的同名方法getWindow().findViewById。
    原来,窗口默默地做了许多事情,只是一般人不知道罢了。熟悉了Window的概念和用法后,再来看看Dialog的工作机制,在屏幕上显示对话框主要有3个步骤:
    步骤01 构造一个对话框对象并指定该对话框的样式。
    步骤02 获取该对话框依赖的窗口对象,设置内容视图并指定窗口的尺寸。
    步骤03 完成相关属性设置,显示对话框。
    下面来看具体的对话框操作方法。

  • Dialog构造函数:可定义对话框的主题样式(样式在styles.xml中定义),如是否有标题、是否为半透明、对话框的背景是什么等。

  • getWindow:获取对话框的窗口对象。该方法是自定义对话框的关键,首先获取对话框所在的窗口对象,然后往这个窗口添加定制视图。

  • show:显示对话框。

  • isShowing:判断对话框是否显示。

  • hide:隐藏对话框。

  • dismiss:关闭对话框。

  • setCancelable:设置对话框是否可取消。

  • setCanceledOnTouchOutside:点击对话框外部区域是否自动关闭对话框。默认会自动关闭。

  • setOnShowListener:设置对话框的显示监听器。需实现OnShowListener接口的onShow方法。

  • setOnDismissListener:设置对话框的消失监听器。需实现OnDismissListener接口的onDismiss方法。

远程视图RemoteViews

前面介绍Notification的常用方法时提到setContent方法可以在设置定制的通知栏视图RemoteViews时取代Builder的默认视图模板。这表示通知栏允许自定义,并且自定义通知栏需要采用远程视图RemoteViews。
与活动页面相比,如果说对话框是一个小型页面,远程视图就是一个小型且简化的页面。简化的意思是功能减少了,限制变多了。虽然RemoteViews与Activity一样有自己的布局文件,但是RemoteViews的使用权限小了很多。两者的区别主要有:
(1)RemoteViews主要用于通知栏部件和桌面部件,而Activity用于页面。
(2)RemoteViews只支持少数几种控件,如TextView、ImageView、Button、ImageButton、ProgressBar、Chronometer(计时器)和AnalogClock(模拟时钟)。
(3)RemoteViews不可直接获取和设置控件信息,只能通过该对象的set方法修改控件信息。
下面来看远程视图的常用方法。

  • 构造函数:创建一个RemoteViews对象。第一个参数是包名,第二个参数是布局文件id。
  • setViewVisibility:设置指定控件是否可见。
  • setViewPadding:设置指定控件的间距。
  • setTextViewText:设置指定TextView或Button控件的文字内容。
  • setTextViewTextSize:设置指定TextView或Button控件的文字大小。
  • setTextColor:设置指定TextView或Button控件的文字颜色。
  • setTextViewCompoundDrawables:设置指定TextView或Button控件的文字周围图标。
  • setImageViewResource:设置ImageView或ImgaeButton控件的资源编号。
  • setImageViewBitmap:设置ImageView或ImgaeButton控件的位图对象。
  • setChronometer:设置计时器信息。
  • setProgressBar:设置进度条信息,包括最大值与当前进度。
  • setOnClickPendingIntent:设置指定控件的点击响应动作。
服务Service基础

本节介绍为何使用服务Service和如何使用服务,包括服务的生命周期和在3种启停方式下的生命周期过程,有普通启停、立即绑定和延迟绑定。另外,还介绍了怎样结合通知推送Notification实现把服务推送到前台的功能。

Service的生命周期

服务Service是Android的四大组件之一,常用在看不见页面的高级场合,如第5章定时器用到了系统的闹钟服务,6.4节通知推送用到了系统的通知服务。既然Android有系统服务,App也可以有自己的服务。Service与Activity相比,不同之处在于没有对应的页面,相同之处在于有生命周期。要想用好服务,就要探究其生命周期。
下面是Service与生命周期有关的方法说明。

  • onCreate:创建服务。
  • onStart:开始服务,Android 2.0以下版本使用,现已废弃。
  • onStartCommand:开始服务,Android 2.0及以上版本使用。该函数的返回值说明见表6-5。
    在这里插入图片描述
  • onDestroy:销毁服务。
  • onBind:绑定服务。
  • onRebind:重新绑定。该方法只有当上次onUnbind返回true的时候才能被调用。
  • onUnbind:解除绑定。返回值为true表示允许再次绑定,再绑定时调用onRebind方法;返回值为false表示只能绑定一次,不能再次绑定,默认为false。
    Service分好几种生命周期方法。原因是服务存在多种启停方式,如普通启停、立即绑定、延迟绑定,每种启停方式都对应不同的周期方法。下面分别叙述3种启停方式及其生命周期说明。
1. 普通启停

普通启停是最简单的用法。下面是该方式的服务代码:
在这里插入图片描述

在Acitivity代码中,启停服务也很简单,调用startService方法即可启动服务,调用stopService方法即可停止服务。当然,也可以在Intent对象中传递参数信息。示例的调用代码如下:
在这里插入图片描述
普通启停方式的服务生命周期可通过打印日志观察,也可在页面上直接显示日志。启动服务依次调用了onCreate与onStartCommand方法,如图6-30所示。停止服务调用了onDestroy方法。
在这里插入图片描述
停止服务调用了onDestroy方法,如图6-31所示。
在这里插入图片描述

2. 立即绑定

绑定方式的服务定义有所不同,因为绑定的服务可能运行于另一个进程,所以必须定义一个Binder对象用来进行进程间的通信。下面是一个绑定方式的服务代码:
在这里插入图片描述

这个服务在绑定时会打印日志“绑定服务开始旅程!”,在解除绑定时会打印日志“绑定服务结束旅程!”。在Activity中,绑定/解绑服务的做法与普通方式不同,首先要定义一个ServiceConnection的服务连接对象,然后调用bindService方法或unbindService方法进行绑定或解绑操作,具体的示例代码如下:
在这里插入图片描述

接下来,继续观察立即绑定方式的生命周期,该方式的服务周期日志如图6-32和图6-33所示。其中,图6-32所示为立即绑定时的界面,此时依次调用onCreate和onBind方法;图6-33所示为立即解绑时的界面,此时依次调用onUnbind和onDestroy方法。
在这里插入图片描述

3. 延迟绑定

延迟绑定与立即绑定的区别在于:延迟绑定是在页面上先通过startService方法启动服务,然后通过bindService方法绑定已存在的服务。这样一来,因为启动操作在先,所以解绑操作只能撤销绑定操作,而不能撤销启动操作。由于解绑服务不能停止服务,因此存在再次绑定服务的可能。
下面观察延迟绑定的日志,验证一下实际结果是否符合之前的猜想。依次查看“启动服务→绑定服务→解绑服务”的运行日志,如图6-34所示;依次查看“绑定服务→解绑服务→停止服务”的运行日志,如图6-35所示。
在这里插入图片描述

图6-35 再次绑定的日志
从日志中可以看到,延迟绑定与立即绑定两种方式的生命周期区别在于:
(1)延迟绑定的首次绑定操作只调用onBind方法,再次绑定只调用onRebind方法(是否允许再次绑定要看上次onUnbind方法的返回值)。
(2)延迟绑定的解绑操作只调用onUnbind方法。

推送服务到前台

服务没有自己的布局文件,也就意味着无法直接在页面上展示,要想了解服务的运行情况,要么通过打印日志,要么获取某个页面的静态对象,然后在该页面上显示运行结果。然而活动页面有自身的生命周期,极有可能发生服务尚在运行但页面早已退出的情况,所以该方式不可靠。幸好,服务不只能在外部进行启停或绑定,还能在内部模拟启停,当然仅是模拟而已。
服务内部的启停方法也有对应的两个函数。

  • startForeground:把当前服务切换到前台运行。第一个参数表示通知的编号,第二个参数表示Notification对象,意味着切换到前台就是展示到通知栏。
  • stopForeground:停止前台运行。参数为true表示清除通知,参数为false表示不清除。
    注意,从Android 9.0开始,要想在服务中正常调用startForeground方法,还需修改AndroidManifest.xml,添加如下所示的前台服务权限配置:
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【AIGC】VoiceControl for ChatGPT指南:轻松开启ChatGPT语音对话模式

博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯安装VoiceControl for ChatGPT插件💯如何使用VoiceControl for ChatGPT进行语音输入VoiceControl for ChatGPT快捷键注意点 💯VoiceControl for C…

毕业设计_基于springboot+layui+mybatisPlus的中小型仓库物流管理系统源码+SQL+教程+可运行】41004

毕业设计_基于springbootlayuimybatisPlus的中小型仓库物流管理系统源码SQL教程可运行】41004 下载地址: https://download.csdn.net/download/qq_24428851/89843203 技术栈 后端:springboot、mybatis-plus、shiro 前端:layUI 存储&…

贴吧软件怎么切换ip

在网络使用中,有时我们需要切换IP地址来满足特定的需求,比如需要切换贴吧软件IP以进行不同的操作。本文将介绍几种贴吧切换IP地址的方法,帮助用户更好地管理自己的网络身份和访问权限。 1、更换网络环境‌ 通过连接到不同的Wi-Fi网络或使用移…

15分钟学 Python 第37天 :Python 爬虫入门(三)

Day 38 : Python爬虫入门大纲 章节1:Python爬虫概述 1.1 什么是爬虫? 网页爬虫(Web Crawler)是一种自动访问互联网上网页并提取数据的程序。爬虫的作用包括搜索引擎索引内容、市场调查、数据分析等。 1.2 爬虫的工作原理 发起…

1c语言基础

1.关键字 一、数据类型关键字 A基本数据类型(5个) void:声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果char:字符型类型数据,属于整型数据的一种int:整型数据&#x…

[SAP ABAP] 数据元素添加参数ID(Parameter ID)

学生表(ZDBT_STU_437) 示例:为学生表ZDBT_STU_437中的数据元素ZDE_STUID_437创建Parameter ID 1.使用事务码SM30维护TPARA表 新建参数ID并输入简短描述 点击保存按钮,选择指定的包即可生成参数ID 2.参数ID和数据元素绑定 使用SE11对学生表(ZDBT_STU_…

自动驾驶系列—颠覆未来驾驶:深入解析自动驾驶线控转向系统技术

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

终于知道神秘的蓝莓真身了

黑森林实验室(Black Forest Labs,简称 BFL)是一家初创公司,由流行的 Stable Diffusion AI 图像生成模型的创建者创立,该模型是许多 AI 图像生成应用程序和服务(如 Midjourney)的基础。 这意味着…

模拟实现string

1.代码理解 1.substr 断言指定的位置在字符的长度之内,_size-len是剩余字符的长度(pos后面的),如果输入len是大于pos后面的字符长度则默认为pos后面全部的字符去拷贝,再建立一个sub去储存,通过循环把pos后面的字符接收到sub里面。 string …

新闻推荐系统:Spring Boot的创新应用

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…

win11远程连接MySQL(linux版),不需安装docker容器

不想安装虚拟机,想在Windows 11上运行Linux。 在win11的搜索框内,搜索"启用或关闭",出现了“启用或关闭Windows功能”,双击打开。 勾选"适用于Linux的Windows子系统",“虚拟机平台”&#xff0c…

yolov8/9/10/11模型在食品图像商标检测中的应用【代码+数据集+python环境+GUI系统】

yolov8/9/10/11模型在食品图像商标检测中的应用【代码数据集python环境GUI系统】 背景意义 准确的食品商标检测能确保消费者购买到的食品来源可靠、信息真实。消费者可以通过商标了解食品的生产厂家、生产日期、成分等关键信息,从而判断食品的安全性和质量。如果商…

Linux系统字符命令关机方法对比

一、相同点:都可以达到关机或重启系统的目的。 二、不同点:命令内部的工作过程不同。 1、shutdown 安全的关机命令:系统管理员会通知所有登录的用户系统将要关闭且 login 指令会被冻结,即新的用户不能再登录。根据使用的参数不同…

YOLO11改进|注意力机制篇|引入HAT超分辨率重建模块

目录 一、HAttention注意力机制1.1HAttention注意力介绍1.2HAT核心代码 二、添加HAT注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、HAttention注意力机制 1.1HAttention注意力介绍 HAT模型 通过结合卷积特征提取与多尺度注意…

C++系列-二叉搜索树

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 二叉搜索树 二叉搜索树又称二叉排序树,它或者是一颗空树,或者是具有以下性质的树 若它的左子树不为空,则左子树上的所有节点的值都小于根节点…

【ubuntu】apt是什么

目录 1.apt简介 2.常用apt指令 2.1安装 2.2更新列表 2.3更新已经安装的软件包 2.4搜索软件包 2.5显示软件包信息 2.6移除软件包 2.7清理无用的安装包 2.8清理无用的依赖项 3.apt和apt-get 3.1区别 3.2 总结 1.apt简介 apt的全称是advanced package …

7c结构体

文章目录 一、结构体的设计二、结构体变量的初始化2.1结构体在内存表示;**2.2**结构体类型声明和 结构体变量的定义和初始化只声明结构体类型声明类型的同时定义变量p1用已有结构体类型定义结构体变量p2*定义变量的同时赋初值。*匿名声明结构体类型 2.3 结构体嵌套及…

Ubuntu安装Hadoop3.4

1、创建Hadoop用户 sudo adduser hadoop 将Hadoop加进sudo用户组,赋予更高权限: sudo usermod -G sudo hadoop 3、安装JDK(略) 查看JDK安装路径:which java 和 ls -al 3、配置SSH免密登录 在Hadoop分布式集群环境中,各个机器之间的通信通常需要使用SSH的方式进行连…

MIT6.824--入门介绍

分布式系统的定义 分布式系统是指将多部各自拥有内存与时钟等硬件设备的独立的计算机系统以网络汇集起来,彼此之间仅仅通过网络消息传递进行通信和协调,共同对外提供服务,但对于系统的用户来说,就像是一台计算机在提供服务一样。…

Python+Matplotlib可视化初等函数示例

import numpy as np import matplotlib.pyplot as pltplt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] Falsefig, axs plt.subplots(2, 3, figsize(15, 10))# 1. 幂函数 x np.linspace(-2, 2, 200) axs[0, 0].plot(x, x**2, labely x^2) axs[0,…