自定义视图组件

说明

Android提供了用于构建UI的基础上,基本布局类一个复杂和强大的组件化模式:View和 ViewGroup。首先,该平台包含各种预构建的View和ViewGroup子类 - 分别称为小部件和布局 - 可用于构建UI。

可用的widget的部分名单包括Button, TextView, EditText, ListView, CheckBox, RadioButton, Gallery, Spinner,和多个专用 AutoCompleteTextView, ImageSwitcher和 TextSwitcher。

在现有的布局LinearLayout, FrameLayout,RelativeLayout,等。有关更多示例,请参阅常见布局对象。

如果没有预构建的小部件或布局满足您的需求,您可以创建自己的View子类。如果您只需对现有的窗口小部件或布局进行微调,则可以简单地对窗口小部件或布局进行子类化并覆盖其方法。

创建您自己的View子类可以精确控制屏幕元素的外观和功能。为了让您了解使用自定义视图获得的控制权,以下是您可以对它们执行的一些示例:

您可以创建完全自定义渲染的视图类型,例如使用2D图形渲染的“音量控制”旋钮,其类似于模拟电子控制。
您可以将一组视图组件组合到一个新的单个组件中,也许可以制作类似ComboBox(弹出列表和自由输入文本字段的组合),双窗格选择器控件(带有列表的左窗格和右窗格每个地方你可以重新分配哪个项目在哪个列表中),等等。
您可以覆盖EditText组件在屏幕上呈现的方式(记事本教程使用此效果,创建一个记事本页面)。
您可以捕获按键等其他事件并以某种自定义的方式处理它们(例如游戏)。
下面的部分将介绍如何创建自定义视图并在您的应用程序中使用它们。有关详细的参考信息,请参阅View课程。

基本方法

以下是开始创建自己的View组件所需知道的高级概述:

View用自己的班级 扩展现有的班级或子班级。
覆盖超类的一些方法。这些超类方法重写下手“ on”,例如onDraw(), onMeasure()和 onKeyDown()。这是类似on…的事件,Activity 或者ListActivity 是你改写生命周期和其他功能挂钩。
使用你的新扩展类。一旦完成,您的新扩展类可以用来代替它所基于的视图。
提示: 扩展类可以在使用它们的活动中定义为内部类。这很有用,因为它控制对它们的访问,但不是必需的(也许你想创建一个新的公共视图,以便在你的应用程序中使用)。

完全定制的组件

完全自定义的组件可用于创建出现的图形组件,但不管您希望如何。也许是一个图形化的VU表,看起来像一个古老的模拟仪表,或一个长长的文字视图,弹跳球沿着单词移动,所以你可以与卡拉OK机一起唱歌。无论哪种方式,无论您如何组合它们,都需要内置组件不会执行的操作。

幸运的是,您可以轻松创建以您喜欢的任何方式显示和行为的组件,可能仅受您的想象力,屏幕大小以及可用的处理能力的限制(请记住,最终,您的应用程序可能必须运行在显着减少比你的桌面工作站更强大)。

要创建完全定制的组件:

  1. 不出所料,您可以扩展的最通用的视图View,所以您通常会首先扩展它以创建新的超级组件。
  2. 您可以提供一个构造函数,它可以从XML获取属性和参数,还可以使用您自己的这些属性和参数(可能是VU表的颜色和范围,或针的宽度和阻尼等)
  3. 您可能想要在组件类中创建自己的事件侦听器,属性访问器和修饰符,以及可能更复杂的行为。
    4.** 您几乎肯定会想要重写onMeasure(),onDraw()如果您希望组件显示某些内容,也可能需要重写。虽然两者都具有默认行为,但默认设置onDraw()不会执行任何操作,默认设置 onMeasure()将始终设置为100x100的大小 - 这可能不是您想要的。
    5 其他on…方法也可以根据需要重写。

扩展onDraw()和onMeasure()

该onDraw()方法为您提供了一个Canvas 你可以实现你想要的任何东西:2D图形,其他标准或自定义组件,样式文本或任何你能想到的东西。

注意: 这不适用于3D图形。如果你想使用3D图形,你必须扩展SurfaceView 而不是视图,并从一个单独的线程中绘制。有关详细信息,请参阅GLSurfaceViewActivity示例。

onMeasure()是多一点参与。onMeasure() 是组件与其容器之间呈现合约的关键部分。onMeasure()应该被覆盖以有效和精确地报告其包含部分的测量结果。根据父级(传递给onMeasure()方法)的限制要求以及要求setMeasuredDimension()在计算出已计算的宽度和高度后调用该方法的要求,这会稍微复杂一些。如果您未能通过重写的onMeasure()方法调用此方法,则结果将在测量时发生异常。

在很高的层面上,实施onMeasure()看起来像这样:

重写的onMeasure()方法被称为宽度和高度测量规范(widthMeasureSpec和 heightMeasureSpec参数,都是代表尺寸的整数代码),应将其视为对您应该生成的宽度和高度测量的限制的要求。参考文档View.onMeasure(int, int)(参考文档在解释整个测量操作方面也做了很好的工作)中可以找到完整参考这些规范可能需要的限制类型。
您的组件的onMeasure()方法应计算渲染组件所需的测量宽度和高度。它应该尽量保持传入的规格,尽管它可以选择超过它们(在这种情况下,父母可以选择做什么,包括剪裁,滚动,抛出异常,或要求onMeasure()再次尝试,也许与不同测量规格)。
一旦计算宽度和高度,setMeasuredDimension(int width, int height)必须使用计算的测量值调用该方法。不这样做将导致抛出异常。

以下是框架调用视图的一些其他标准方法的摘要:

复合控制

如果您不想创建完全自定义的组件,而是希望将由一组现有控件组成的可重用组件组合在一起,则创建复合组件(或复合控件)可能适合帐单。简而言之,这将更多的原子控制(或视图)汇集到一组可以被视为单一事物的逻辑组中。例如,组合框可以被认为是单行EditText字段和附加PopupList的相邻按钮的组合。如果按下按钮并从列表中选择某项,它将填充EditText字段,但用户也可以直接在EditText中输入某些内容(如果他们喜欢的话)。

在Android中,实际上有两种其他视图可以轻松实现此目的:Spinner而且 AutoCompleteTextView,不管怎样,组合框的概念都是一个易于理解的示例。

要创建复合组件:

通常的出发点是某种布局,所以创建一个扩展布局的类。也许在组合框的情况下,我们可能会使用水平方向的LinearLayout。请记住,其他布局可以嵌套在内部,因此复合组件可以是任意复杂和结构化的。请注意,就像使用Activity一样,您可以使用声明式(基于XML)方法来创建包含的组件,也可以通过代码将它们嵌套在程序中。
在新类的构造函数中,接受超类所需的任何参数,并首先将它们传递给超类构造函数。然后,您可以设置其他视图以在新组件中使用; 这是您创建EditText字段和PopupList的位置。请注意,您也可以将自己的属性和参数引入可以由您的构造函数拖出并使用的XML。
您还可以为包含的视图可能生成的事件创建侦听器,例如,用于List Item的侦听器方法单击Listener以在进行列表选择时更新EditText的内容。
您也可以使用访问器和修饰符创建自己的属性,例如,允许在组件中初始设置EditText值,并在需要时查询其内容。
在扩展布局的情况下,您不需要重写 onDraw()和onMeasure()方法,因为布局将具有可能工作得很好的默认行为。但是,如果需要,仍可以覆盖它们。
您可以重写其他on…方法,例如 onKeyDown(),可能在按某个键时从组合框的弹出列表中选择某些默认值。
总而言之,使用布局作为自定义控件的基础具有许多优点,其中包括:

您可以像使用活动屏幕一样使用声明性XML文件指定布局,也可以通过编程创建视图并将它们嵌入到代码中的布局中。
在onDraw()与onMeasure()方法(再加上大部分的其他on…方法)将可能有合适的行为,所以你不必重写它们。
最后,您可以非常快速地构建任意复杂的复合视图,并将它们重新使用,就好像它们是单个组件一样。

修改现有的视图类型

有一个更简单的选项来创建自定义视图,在某些情况下很有用。如果有一个组件与您想要的非常相似,那么您可以简单地扩展该组件,并覆盖您想要更改的行为。你可以用完全自定义的组件完成所有的事情,但是通过从View层次结构中的更专业化的类开始,你也可以获得许多免费的行为,可能完全是你想要的。

例如,SDK包含示例中的NotePad应用程序。这展示了使用Android平台的许多方面,其中包括扩展EditText视图以制作记事本。这不是一个完美的例子,用于这样做的API可能会从这个早期的预览中改变,但它确实证明了原则。

如果您还没有这样做,请将NotePad示例导入到Android Studio中(或者使用提供的链接查看源代码)。在定义特定的外观 MyEditText在NoteEditor.java 文件。

这里需要注意一些问题

1、定义
该类使用以下行定义:
public static class MyEditText extends EditText
它被定义为NoteEditor 活动内的一个内部类,但是它是公开的,所以 如果需要的话,它可以NoteEditor.MyEditText在NoteEditor课外从外部访问 。
这static意味着它不会生成所谓的“合成方法”,允许它从父类访问数据,这意味着它实际上表现为一个单独的类,而不是与强相关的东西NoteEditor。如果它们不需要从外部类访问状态,保持生成的类很小,并允许从其他类轻松使用,则这是创建内部类的更简洁的方法。
它扩展了EditText,这是我们在这种情况下选择定制的视图。当我们完成后,新班级将能够取代普通EditText视图。
2、类初始化
一如既往,超级被称为第一。此外,这不是默认的构造函数,而是一个参数化的构造函数。当从XML布局文件膨胀时,EditText由这些参数创建,因此,我们的构造函数需要将它们接受并传递给超类构造函数。
3、重写的方法
在这个例子中,只有一种方法被重写: onDraw()- 但是当你创建自己的自定义组件时,可能很容易需要其他方法。
对于NotePad示例,重写该onDraw()方法允许我们在EditText视图画布上绘制蓝色线条(画布被传递到重写的onDraw()方法)。在方法结束之前调用super.onDraw()方法。应该调用超类方法,但在这种情况下,我们在绘制完想要包含的行后最后执行它。
4、使用自定义组件
我们现在有我们的自定义组件,但我们如何使用它?在记事本实施例中,定制组件直接从所述声明性布局中使用,所以看看note_editor.xml中 res/layout的文件夹。

<view class = “com.android.notepad.NoteEditor $ MyEditText” id :“@ + id / note” android:layout_width = “fill_parent” android:layout_height = “fill_parent” android:background = “ @ android :drawable / empty” android:padding = “10dip” android:scrollbars = “vertical” android:fadingEdge = “vertical” />

自定义组件是作为XML中的通用视图创建的,并且该类是使用完整软件包指定的。还请注意,我们定义的内部类是使用NoteEditor$MyEditText标记来引用的,该 标记是用Java编程语言引用内部类的标准方法。
如果您的自定义视图组件未定义为内部类,则可以替代地使用XML元素名称声明视图组件,并排除该class属性。例如:

<com.android.notepad.MyEditText id = “@ + id / note”   ... />

请注意,MyEditText该类现在是一个单独的类文件。当这个类嵌套在NoteEditor类中时,这种技术将无法工作。
定义中的其他属性和参数是传递给自定义组件构造函数的参数,然后传递给EditText构造函数,因此它们与您将用于EditText视图的参数相同。请注意,也可以添加您自己的参数,我们将在下面再次介绍这一点。
这就是它的全部。无可否认,这是一个简单的例子,但这就是要点 - 创建自定义组件只是像你需要的那样复杂。

一个更复杂的组件可能会覆盖更多的on…方法,并引入一些自己的帮助方法,实质上可以自定义其属性和行为。唯一的限制是你的想象力和你需要的组件。

参考文章
https://developer.android.google.cn/guide/topics/ui/custom-components.html#modifying

Android自定义控件学习(三)----- 自定义视图组件相关推荐

  1. Android自定义控件学习(五)-------自定义绘图

    自定义视图中最重要的部分是它的外观.根据您的应用需求,自定义绘图可以很容易或复杂. 本课包含一些最常见的操作 覆盖onDraw() 绘制自定义视图中最重要的步骤是重写该onDraw()方法.参数to ...

  2. Android自定义控件学习(七)-------优化视图

    优化视图 既然您的设计良好,可以响应手势和状态之间的转换,请确保视图运行速度很快.为了避免在播放过程中感觉呆滞或断断续续的用户界面,请确保动画一直以每秒60帧的速度运行. 少,少频繁 为了加速你的视图 ...

  3. Android自定义控件学习(六)-------使视图互动

    使视图互动 绘制用户界面只是创建自定义视图的一部分.您还需要使您的视图以与您模拟的真实世界动作非常相似的方式响应用户输入.对象应始终以与真实对象相同的方式进行操作.例如,图像不应该立即跳出存在,并在其 ...

  4. Android自定义控件学习(四)------创建一个视图类

    创建一个视图类 精心设计的自定义视图与其他精心设计的类非常相似.它使用易于使用的界面封装了一组特定的功能,它可以高效地使用CPU和内存,等等.不过,作为一个设计良好的设计,自定义视图应该: 符合And ...

  5. Android自定义控件学习(一)-----属性

    Android中XML的命名空间.自定义属性 命名空间(namespace) XML 命名空间提供避免元素命名冲突的方法. 打个比方,A学校有名学生叫做林小明,B学校也有名学生叫林小明,那我们如何识别 ...

  6. Android自定义控件面试题,自定义View面试总结

    本着针对面试,不负责任的态度,写下<面试总结>系列.本系列记录面试过程中各个知识点,而不是入门系列,如果有不懂的自行学习. 自定义View三种方式,组合现有控件,继承现有控件,继承View ...

  7. Android自定义控件学习(二)-----自定义attr Style styleable以及其应用

    相信每一位从事Android开发的猿都遇到过需要自己去自定义View的需求,如果想通过xml指定一些我们自己需要的参数,就需要自己声明一个styleable,并在里面自己定义一些attr属性,这个过程 ...

  8. 修改meta标签 查看源码没效果怎么办_Spring 源码学习(三)-自定义标签

    又来填坑啦,上一篇讲完默认标签的解析,这篇笔记记录一下自定义标签的解析吧. 我们知道,Spring 源码的核心模块是 Spring-core 和 Spring-beans,在此基础上衍生出其他模块,例 ...

  9. Android 自定义控件起步:自定义TextView

    转载至:http://blog.csdn.net/lmj623565791/article/details/24252901 不过对原作进行了相关细节优化,所以才有此文.. 首先我们看一下我们要达到的 ...

最新文章

  1. 7-1 查找书籍(20 分)(程序设计天梯赛模拟练习题)
  2. R语言dplyr包使用bind_rows函数纵向合并两个dataframe(行生长)、使用bind_cols函数横向合并两个dataframe(列生长)
  3. asp.net core 教程(七)-异常处理、静态文件
  4. 糊涂虫 php,糊涂虫 hat folgende Bedeutung
  5. mysql调试索引_10 分钟让你明白 MySQL 是如何利用索引的?
  6. html打地鼠游戏设计报告,有趣的Axure案例:打地鼠游戏的设计
  7. 超简单的话解释C#事件-源码示例
  8. php图文消息带代码详细注释,微信发送图文消息代码整理
  9. 19.7 主动模式和被动模式 19.8 添加监控主机 19.9 添加自定义模板 19.10 处理图形中的乱码 19.11 自动发现...
  10. 【 HRBUST - 1055】Single(模拟,dp,打表)(总结)
  11. poj 2031Building a Space Station(几何判断+Kruskal最小生成树)
  12. Visual C++ 时尚编程百例016(字体)
  13. 信号signal()、alarm()、信号集函数、sigprocmask()
  14. FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()
  15. sql 2005性能调优
  16. win10总是2分钟就自动睡眠怎么办 win10系统自动休眠bug怎么解决(转)
  17. cad一键卸载工具叫什么_autodesk卸载工具一键卸载或安装CAD,3dmax 如何彻底卸载CAD系列软件 | 「讲文兄博客」...
  18. 计算机机房安全消防管理制度,机房消防安全管理制度
  19. 直面程序人生,始于当下,奔赴未来!
  20. 计算机无法启动故障树,发动机无法启动的故障树分析及诊断方法.docx

热门文章

  1. 搭建redis主从结构
  2. 点亮两个发光管用c语言编辑,第二个试验:用单片机点亮一个闪烁的发光管-----51单片机汇编语言试验教程 - CSDN博客...
  3. OpenShift 4 - Pod的亲和性/反亲和性
  4. JavaScript PopUp生成器
  5. ASP.NET Core 和 Blazor 更新
  6. HTML布局是外边距咋表示,布局 页面设置百分比 子元素如何设置外边距?
  7. php百度鹰眼,Android 百度鹰眼里程计算简单实列
  8. redis 缓存预热_Redis异常问题解决方案:缓存雪崩、预热、穿透、击穿、降解方案分析...
  9. 晶体封装越小esr越大_晶振
  10. html语言笔记,HTML/HTML5 笔记