Android官方开发文档Training系列课程中文版:创建自定义View之View的创建

简介: 原文地址:http://android.xsoftlab.net/training/custom-views/index.html引言Android框架含有大量的View类,这些类用来显示各式各样的数据,并可以直接与用户交互。

原文地址:http://android.xsoftlab.net/training/custom-views/index.html

引言

Android框架含有大量的View类,这些类用来显示各式各样的数据,并可以直接与用户交互。但是某些时候,APP有一项很特殊的需求,但是框架中的View还不能满足这样的需求,这时就需要根据需要自己创建一个全新的View类了。这节课程将会学习如何创建这样的自定义View。

创建View类

一个设计良好的自定义View与其它任何设计良好的View类都很相似。它封装了一系列特殊的功能,并将简单易用的接口暴露了出来。它高效、合理的使用了CPU及内存等资源。除了要实现上面这些特点之外,自定义View还需要:

  • 遵循Android标准。
  • 提供可以工作于Android XML布局中的自定义样式属性。
  • 发送可访问事件。
  • Android平台的兼容性。

Android框架提供了一系列的基础类及XML标签来辅助你创建符合以上标准的View。这节课将会学习如何使用Android框架来创建自定义View的核心功能。

创建View的子类

Android中的所有View类都继承于View。自定义View可以直接继承View,也可以继承View子类(比如Button)。

为了使Android Developer Tools可以与你的View产生交互,应当至少提供一个含有Context与AttributeSet作为参数的构造方法。这个构造方法可以使布局编辑器创建或编辑View的实例。

class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

定义自定义属性

如果要往UI中添加View,你需要以XML元素的形式指定该View,并通过元素属性控制View的行为与外貌。定义良好的自定义View还可以通过XML添加、设计这些样式。为了使自定义View拥有以下这些行为,你必须:

  • 在< declare-styleable >资源元素中定义自定义View的属性。
  • 在XML布局中指定属性的值。
  • 在运行时接收属性值。
  • 将接收到的属性值应用到View中。

这部分将会学习如何定义属性及如何指定它们的值。下部分会学习在运行时如何处理接收并使用这些值。

要定义自定义属性,需要在工程中添加< 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的风格实体。风格实体的名字按照惯例与对应的自定义View的类名相一致。尽管不是必须要遵循这项惯例,但很多受欢迎的代码编辑者都喜欢依照这项命名惯例来提供实现声明。

一旦定义了自定义属性,你就可以像内置属性那样在XML文件中使用它们。唯一的不同就是,自定义属性属于不同的命名空间。它们不属于标准的http://schemas.android.com/apk/res/android命名空间,而属于http://schemas.android.com/apk/res/[your package name]。举个例子,下面是如何使用自定义属性的示例:

<?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/com.example.customviews">
 <com.example.customviews.charting.PieChart
     custom:showText="true"
     custom:labelPosition="left" />
</LinearLayout>

为了避免重复定义命名空间,示例中使用了xmls指令。该指定使http://schemas.android.com/apk/res/com.example.customviews命名空间与custom别名产生了关联。你可以为命名空间使用任何你想使用的名称。

注意,这里在布局中引用的自定义View采用的是自定义View的权限定名。如果View类是个内部类,还必须通过外部类的类名进一步限定。举个例子, PieChart含有一个名叫PieView的内部类。如果要为这个类使用自定义属性,你应该使用标签:com.example.customviews.charting.PieChart$PieView.

应用自定义属性

当一个View从XML布局中被创建后,XML标签中的所有属性都会被读取,并通过View的构造方法以AttributeSet的形式传递到View中。尽管它可能是直接从AttributeSet中读取数据的,但是它还是有一些缺点:

  • 资源所引用的属性值不能够被解析
  • 不支持Style

相反的,可以将AttributeSet传给obtainStyledAttributes()方法。该方法会返回一个TypedArray对象,它内部包含了被间接引用的数组值。

Android资源编译器为了使使用obtainStyledAttributes()方法更加简便做了大量的工作。在资源目录中的每一个资源都会在R.java中定义相应的属性id。你可以使用这预定义的常量去TypedArray中读取属性。下面是PieChart类如何读取属性的示例:

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);
       mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
   } finally {
       a.recycle();
   }
}

注意TypedArray是一个共享资源,必须在使用完之后对其进行回收。

添加属性及事件

Attributes是控制View的外观与行为的一种强大的方式,但是它只有在View初始化的时候才会被读取。如果要提供动态的行为,则需要暴露相应的get,set方法。下面的代码展示了PieChart是如何暴露名为showText的属性方法的:

public boolean isShowText() {
   return mShowText;
}
public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

注意在setShowText中调用了invalidate()方法与requestLayout()方法。这些方法可以确保View的行为更改生效。在更改完成属性之后不得不重新绘制该View,这样才能使View的外观生效。这样系统才会知道该View需要重新绘制。同样的,如果新属性值可能会引起尺寸或者形状的更改还需要请求新的布局。忘记调用这些方法会引起很难发现的Bug.

自定义View还应当支持事件监听器,以便与重要的事件交互。比如,PieChart暴露一个名为OnCurrentItemChanged的自定义事件,用来通知监听器用户旋转了饼图。

很容易忘记暴露属性和事件,尤其你是唯一一个自定义View的用户。在定义View接口时多花点心思可以在将来维护的时候少花点时间和精力。一个良好的习惯就是总是暴露任何成员属性的外观与行为的属性方法。

可访问性

自定义View应当支持更宽泛的用户。这其中包括视力有缺陷的残疾人。为了支持这部分用户的使用,应当:

  • 使用android:contentDescription属性标识你的输入字段
  • 在适当的时候通过sendAccessibilityEvent()方法发送可访问事件
  • 支持更多的控制器,比如D-pad及轨迹球

有关更多信息请参见 Making Applications Accessible


阅读完本篇文章之后,可以继续阅读下一篇文章:Android官方开发文档Training系列课程中文版:创建自定义View之View的绘制

目录
相关文章
|
Android开发 UED 计算机视觉
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
本文介绍了一款受游戏“金铲铲之战”启发的Android自定义View——线条等待动画的实现过程。通过将布局分为10份,利用`onSizeChanged`测量最小长度,并借助画笔绘制动态线条,实现渐变伸缩效果。动画逻辑通过四个变量控制线条的增长与回退,最终形成流畅的等待动画。代码中详细展示了画笔初始化、线条绘制及动画更新的核心步骤,并提供完整源码供参考。此动画适用于加载场景,提升用户体验。
787 5
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
|
Android开发
Android自定义view之利用PathEffect实现动态效果
本文介绍如何在Android自定义View中利用`PathEffect`实现动态效果。通过改变偏移量,结合`PathEffect`的子类(如`CornerPathEffect`、`DashPathEffect`、`PathDashPathEffect`等)实现路径绘制的动态变化。文章详细解析了各子类的功能与参数,并通过案例代码展示了如何使用`ComposePathEffect`组合效果,以及通过修改偏移量实现动画。最终效果为一个菱形图案沿路径运动,源码附于文末供参考。
284 0
|
XML Java Android开发
Android自定义view之网易云推荐歌单界面
本文详细介绍了如何通过自定义View实现网易云音乐推荐歌单界面的效果。首先,作者自定义了一个圆角图片控件`MellowImageView`,用于绘制圆角矩形图片。接着,通过将布局放入`HorizontalScrollView`中,实现了左右滑动功能,并使用`ViewFlipper`添加图片切换动画效果。文章提供了完整的代码示例,包括XML布局、动画文件和Java代码,最终展示了实现效果。此教程适合想了解自定义View和动画效果的开发者。
561 65
Android自定义view之网易云推荐歌单界面
|
XML 前端开发 Android开发
一篇文章带你走近Android自定义view
这是一篇关于Android自定义View的全面教程,涵盖从基础到进阶的知识点。文章首先讲解了自定义View的必要性及简单实现(如通过三个构造函数解决焦点问题),接着深入探讨Canvas绘图、自定义属性设置、动画实现等内容。还提供了具体案例,如跑马灯、折线图、太极图等。此外,文章详细解析了View绘制流程(measure、layout、draw)和事件分发机制。最后延伸至SurfaceView、GLSurfaceView、SVG动画等高级主题,并附带GitHub案例供实践。适合希望深入理解Android自定义View的开发者学习参考。
1021 84
|
前端开发 Android开发 UED
讲讲Android为自定义view提供的SurfaceView
本文详细介绍了Android中自定义View时使用SurfaceView的必要性和实现方式。首先分析了在复杂绘制逻辑和高频界面更新场景下,传统View可能引发卡顿的问题,进而引出SurfaceView作为解决方案。文章通过Android官方Demo展示了SurfaceView的基本用法,包括实现`SurfaceHolder.Callback2`接口、与Activity生命周期绑定、子线程中使用`lockCanvas()`和`unlockCanvasAndPost()`方法完成绘图操作。
388 3
|
Android开发 开发者
Android自定义view之围棋动画(化繁为简)
本文介绍了Android自定义View的动画实现,通过两个案例拓展动态效果。第一个案例基于`drawArc`方法实现单次动画,借助布尔值控制动画流程。第二个案例以围棋动画为例,从简单的小球直线运动到双向变速运动,最终实现循环动画效果。代码结构清晰,逻辑简明,展示了如何化繁为简实现复杂动画,帮助读者拓展动态效果设计思路。文末提供完整源码,适合初学者和进阶开发者学习参考。
266 0
Android自定义view之围棋动画(化繁为简)
|
Java Android开发 开发者
Android自定义view之围棋动画
本文详细介绍了在Android中自定义View实现围棋动画的过程。从测量宽高、绘制棋盘背景,到创建固定棋子及动态棋子,最后通过属性动画实现棋子的移动效果。文章还讲解了如何通过自定义属性调整棋子和棋盘的颜色及动画时长,并优化视觉效果,如添加渐变色让白子更明显。最终效果既可作为围棋动画展示,也可用作加载等待动画。代码完整,适合进阶开发者学习参考。
351 0
|
10月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1798 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1148 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1221 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡

热门文章

最新文章