设计良好的自定义视图与任何其他精心设计的类一样。它封装了 一组特定的 简单的接口,高效地使用 CPU 和内存,诸如此类。在 不仅仅是 类,则自定义视图必须执行以下操作:
- 符合 Android 标准。
- 提供适用于 Android XML 布局的自定义可设置样式属性。
- 发送无障碍事件。
- 与多种 Android 平台兼容。
Android 框架提供了一组基类和 XML 标记,以帮助您创建 符合所有这些条件 要求。本课将介绍如何使用 Android 框架来创建核心 视图功能 类。
您可在 自定义视图组件中的信息。
子类化视图
Android 框架中定义的所有视图类扩展了
View
。您的
自定义视图
直接扩展 View
,也可以
节省时间
现有视图
子类,例如 Button
。
要允许 Android Studio 与视图交互,您必须至少提供一个构造函数,用于接受
Context
和 AttributeSet
对象作为参数。
此构造函数允许布局编辑器创建和编辑视图的实例。
Kotlin
class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)
Java
class PieChart extends View { public PieChart(Context context, AttributeSet attrs) { super(context, attrs); } }
定义自定义属性
如需向界面添加内置 View
,请在 XML 元素中指定,然后
控制其
元素属性对外观和行为的影响。您还可以添加自定义
使用 XML 来创建视图接收者
在自定义视图中启用此行为,请执行以下操作:
- 在
<declare-styleable>
资源元素中为视图定义自定义属性。 - 为 XML 布局中的属性指定值。
- 在运行时检索属性值。
- 将检索到的属性值应用于您的视图。
本部分介绍如何定义自定义属性并指定其值。 下一部分将介绍 在运行时检索和应用值。
如需定义自定义属性,请向项目添加 <declare-styleable>
资源。通常的做法是将这些资源
res/values/attrs.xml
文件。以下是
attrs.xml
文件示例:
<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>
此代码声明了两个自定义属性:showText
和 labelPosition
。
属于某个可设定样式的
实体名称为 PieChart
。按照惯例,可设置样式实体的名称与
命名为
类名称
定义了自定义视图虽然没有必要遵循此惯例
许多热门代码
编辑器依赖此命名惯例提供语句补全。
定义自定义属性后,您可以像内置属性一样在布局 XML 文件中使用它们
属性。唯一
区别在于自定义属性属于不同的命名空间。而非归属感
http://schemas.android.com/apk/res/android
命名空间时,它们就属于 http://schemas.android.com/apk/res/[your package name]
。例如,下面展示了如何使用
属性的定义
PieChart
:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto"> <com.example.customviews.charting.PieChart custom:showText="true" custom:labelPosition="left" /> </LinearLayout>
为了避免必须重复冗长的命名空间 URI,该示例使用
xmlns
指令。此指令会将别名 custom
分配给
命名空间 http://schemas.android.com/apk/res/com.example.customviews
。
您可以为命名空间选择所需的任何别名。
注意将自定义视图添加到布局的 XML 标记的名称。这是
是
自定义视图类。如果您的视图类是内部类,请进一步限定它
替换为视图外部类的名称。
例如,
PieChart
类有一个名为 PieView
的内部类。要使用
自定义属性。
使用标记 com.example.customviews.charting.PieChart$PieView
。
应用自定义属性
从 XML 布局创建视图时,系统会读取 XML 标记中的所有属性
从资源
bundle 并将其作为
AttributeSet
。
虽然
可以直接从 AttributeSet
读取值,这样做
但具有以下缺点:
- 系统不会解析属性值中的资源引用。
- 因此不会应用样式。
请改为将 AttributeSet
传递给
obtainStyledAttributes()
。
此方法会回传一个
TypedArray
数组
值
已解除引用并设置了样式
Android 资源编译器会做很多工作,
obtainStyledAttributes()
。针对每个<declare-styleable>
资源位于 res/
目录中,则生成的 R.java
会同时定义一个属性数组,
和一组
常量定义数组中每个属性的索引。您可以使用预定义的
要读取的常量
TypedArray
中的属性。具体方法如下
PieChart
类
读取其属性:
Kotlin
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() } } }
Java
public PieChart(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0); try { mShowText = a.getBoolean(R.styleable.PieChart_showText, false); textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0); } finally { a.recycle(); } }
请注意,TypedArray
对象
是共享资源
而且必须在使用后回收
添加属性和事件
属性是控制视图行为和外观的有效方式,但是
则只能读取
在视图初始化时触发。如需提供动态行为,请公开一个属性 getter 并
setter 对
自定义属性。以下代码段展示了 PieChart
如何公开属性
名为 showText
:
Kotlin
fun isShowText(): Boolean { return mShowText } fun setShowText(showText: Boolean) { mShowText = showText invalidate() requestLayout() }
Java
public boolean isShowText() { return mShowText; } public void setShowText(boolean showText) { mShowText = showText; invalidate(); requestLayout(); }
请注意,setShowText
会调用 invalidate()
和 requestLayout()
。这些通话至关重要
以确保 View 能够可靠运行。您需要
在视图属性发生更改(可能更改其视图)后,使视图失效
确保
系统知道需要重新绘制同样,如果存在以下情况,您需要请求新布局:
更改属性的方式
可能会影响视图尺寸或形状忘记这些方法调用可能会导致
难以找到
bug。
自定义视图还必须支持事件监听器来传达重要事件。对于
实例,PieChart
公开一个名为 OnCurrentItemChanged
的自定义事件,以通知监听器
用户旋转了
饼图,重点显示新的饼图切片。
公开属性和事件很容易忘记,尤其是当您是唯一用户时 自定义视图的效果 花时间仔细定义视图界面可减少未来的维护工作 费用。 一种好的做法是始终公开任何会影响 显示或行为 自定义视图
在设计时充分考虑无障碍功能
您的自定义视图必须支持众多用户。这包括使用 残疾、 来防止他们看到或使用触摸屏。为了给残障用户提供支持, 执行以下操作:
- 使用
android:contentDescription
为输入字段添加标签 属性。 - 通过调用
sendAccessibilityEvent()
发送无障碍事件 。 - 支持备用控制器,例如方向键或轨迹球。
如需详细了解如何创建可访问的视图,请参阅 <ph type="x-smartling-placeholder"></ph> 让应用使用起来更没有障碍。