类View

来源:互联网 发布:win7 java 编辑:程序博客网 时间:2024/06/06 14:09

类概述

这个类代表了用户接口组件的最基本的构建。一个视图在屏幕上占有一块矩形区域并且负责绘画和事件处理。视图是最基本的部件类,它常常被用来创建可交互的UI组件(按钮、文本域等)。ViewGroup子类是最基本的布局类,它是一种无形的容器,这个容器不仅可以包含其他视图或者其他容器,同时还可以定义其他容器或视图的布局属性。

开发入门

有关这个使用这个类开发你的应用程序的用户接口信息,请参阅用户接口开发者入门文档。

使用View

在一个窗口中的所有view都被按一定顺序排列在一个单独的树结构中。你或者可以中源代码中增加View,或者被指定在一个或更多个XML布局文件中指定。在Android API中,有许多View特定的子类。它们有的充当控制角色,有的能够显示文本、图片或者其他的内容。

首先你要创建一个视图树,你希望执行的有代表性的公共方法:

  • 设置属性:例如设置TextView的文本,这个可用的属性和在不同的View子类之中设置改变它们的方法。需要注意的是在构建时就知道的属性值能被设置到XML布局文件里。
 设置焦点:Andriod框架按照用户输入作出的响应方式来处理移动焦点的。为了促使焦点能够被一个指定的View获得。请调用requestFocus()方法。
  • 创建监听器:所有视图允许设置监听到客户端,当一些感兴趣的事情发生在一个视图上时这个监听将会被通知。例如,当视图得到或失去焦点时你对所有视图设置的监听都会收到通知。你能够使用setOnFocusChangeListener(android.view.View.OnFocusChangeListener)方法注册一个监听。其他的视图子类会提供更多的特定视图的特有的监听。例如,当一个按钮被单击时,这个按钮产生一个监听通知客户端。
  • 设置可见性:你可以使用setVisibility(int)方法隐藏或显示视图。
注意:android框架负责测量,定线和绘制视图。你不应该调用在视图上执行自己的这些操作,除非你实际上是在实现一个ViewGroup中的方法。

实现自定义视图

为了实现一个自定义视图,通常你将会重写一些android框架调用的标准方法。你不必重写所有方法。实际上,你仅仅需要重写onDraw(android.graphics.Canvas)方法。

唯一标识

所有的视图都可以定义个整型的ID。这些ID被分配到XML布局文件中的视图中,并且这个ID常常被用来在视图树中查找指定的视图。通常的模式是:
  • 在xml布局文件中定义一个按钮并且分配一个唯一ID。
<Button     android:id="@+id/my_button"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:text="@string/my_button_text"/>
  • 在Activity的onCreate方法中查找这个按钮
Button myButton = (Button) findViewById(R.id.my_button);
视图ID在整个视图树中可以不必唯一,但是在你正在查询的部分视图树中确保视图ID唯一是一个好的实践。

视图的位置

一个视图的几何结构是一个矩形。一个视图有一个位置,这个位置用一对左上坐标表示,还有两个尺寸,这个尺寸用宽和高表示。这个位置和尺寸的单位是像素。
可以通过调用getLeft()getTop()方法来获取视图的位置。前者返回的是左侧或者代表矩形视图的X轴坐标。后者返回的是顶部或者代表矩形视图的Y轴坐标。这个些方法返回的都是相对于它父视图的位置坐标。例如,当getLeft()方法返回值是20时,意思是说这个视图位于它的直接父视图的左侧边缘的右面20像素。
另外,为了避免不必要的计算,视图类还提供了比较便利的方法,即是getRight()和getBottom()方法。这些方法的返回值是代表视图的矩形右边缘和下边缘的坐标。例如,调用getRight()方法类似计算:getLeft() + getWidth()(有关更多的宽度信息请查阅视图的大小章)。

视图的大小和内边距以及外边距

视图的大小用宽度和高度来表示。一个视图实际上处理两对宽高值。
这第一对宽高是测量的宽和测试量的高。这个尺寸定义了在它的直接父视图里当前视图的大小(查看更多布局的细节描述)。
你可以通过调用getMeasuredWidth() 和 getMeasuredHeight()方法来获得这个视图的测量尺寸。
这第二对宽高是简单的宽高,或者有时也叫做绘制的宽和高。这个尺寸定义了在布局后并开始绘制时该视图在屏幕中的大小。这对尺寸值有时是和测量的宽高值相同,有时不同。这对宽高值是通过分别调用getWidth() 和 getHeight()来获取的。
为了测量一个视图的尺寸,你需要考虑到它的内边距。这个内边距是指视图的左、上、右、下部分,单位是像素。内边距是用来定义视图的内容偏移了多少像素。例如,左侧内边距为2意思是将视图的内容要移到该视图左边缘右侧2像素的位置。你可以使用setPadding(int, int, int, int)setPaddingRelative(int, int, int, int) 方法来设置视图的内边距,也可以使用getPaddingLeft(),getPaddingTop(),getPaddingRight(),getPaddingBottom(),getPaddingStart(),getPaddingEnd()方法来获取该视图的内边距值。
视图可以定义内边距的值,但是它不能定义外边距的值。然而视图容器可以定义外边距的值。外边距会涉及到ViewGroup和ViewGroup.MarginLayoutParams信息。

布局

布局包含两个途径的过程:一个测量途径和一个布局途径。这个测量途径已经实现了measure(int, int)方法并且对视图树从上到下遍历一遍。在递归期间,每一个视图会沿着视图树增加尺寸说明。在测量过程结束时,每一个视图会存储它的测量值。这个布局途径要实现layout(int, int, int, int)方法并且也对视图树从上到下遍历一遍。在布局期间,每一个父视图负责使用在测量过程中对每一个子视图计算的大小来定位它的所有子视图。

当一个视图的measure()方法执行结束并有返回值时,它的getMeasuredWidth()和getMeasuredHeight()的值必须被设置,一个视图的测量的宽度值和测量的高度值必须要遵守这个视图的父视图强加于自己的约束。这样就会保证在测量途径结束后,所有的父视图都可以接受它的所有的子视图测量值。一个父视图在它的孩子上也许会多次调用measure()方法。例如,父视图也许会用未指定的尺寸来测量一次它的每一个子视图,目的是为了找出所有子视图想要的范围,如果这个父视图的所有孩子未约束大小总和太大或者太小,那么父视图会再次用实际的数调用measure()方法。

这个测量途径使用2个类(类View.MeasureSpec和LayoutParams)来相处传递尺寸。View.MeasureSpec类是被视图用来告诉他们的父视图怎样测量和定位自己。这个基本的LayoutParams类仅仅用来确定这个视图想要多大的宽和高。对于视图宽高的每一种尺寸,可以指定下列尺寸之一:
  • 一个精确的数字
  • MATCH_PARENT,意思是这个视图的宽高和它的父视图的宽高一样大小(最小内边距)。

  • WRAP_CONTENT,意思是这个视图的宽高仅仅能够包裹住它的内容即可(增加内边距)。

MeasureSpecs 常常被用来作为测量的必要条件。一个测量细则可以使用下列3种模式之一:

  • UNSPECIFIED:这种模式常被父视图用来确定子视图渴望的尺寸大小。例如,LinearLayout调用measure()方法,在它的一个子视图上设置其高度为UNSPECIFIED,设置其宽度为精确值240像素,那么这个子视图的高度将会是和宽度值相等都为240像素。

  • EXACTLY:这种模式常被父视图强加给子视图一个精确的大小。这个子视图必须使用这个大小并且确保该视图的所有子节点都在这个大小之内。

  • AT_MOST:这个模式常被父视图用来强加最大的大小到这个子视图上。子视图必须确保它和它的所有子节点都在这个大小之内。

为了初始化一个布局,需要调用requestLayout()方法。当一个父视图认为它不再适合它当前的边界,子视图就会调用这个方法来重新布局。

图像

图像通过遍历整个视图树并且记录任意你需要更新的视图图像指令而被处理。这处理之后,整个视图树的图像指令将会发布到屏幕上并修剪最近损坏的区域。
这个视图树主要按顺序记录并绘制图像,父视图在它们的子视图之前绘制,兄弟姐妹按它们各自出现的顺序绘制。如果你为一个视图设置背景图像,那么这个视图将会在回调onDraw()方法之前绘制这个背景。这个视图的子视图绘制顺序将会在视图容器中被定义子视图绘制顺序的对象覆写,并随着setZ(float)方法定义Z值。
为了促使一个视图被绘制,需要调用invalidate()。

事件处理和事件线程

基本的绘制视图循环是:
  1. 当一个事件发生时,anroid系统会将这个事件分发给合适的视图。这个视图会处理这个事件并且通知每一个监听器。
  2. 如果在处理这个事件的过程中,视图的边界需要改变,则该视图将会调用requestLayout()方法。
  3. 类似的,如果在处理事件过程中,视图的外观需要改变,则该视图会调用invalidate()方法。
  4. 如果requestLayout()方法和 invalidate()方法有一个被调用,那么android框架用合适的方法来测量、布局、绘制这个视图树。
注意:整个视图树是在一个单独的线程内。当调用任意视图的方法时,你必须要在这个UI线程中。如果你想要在其他的线程中工作同时想要在这个线程中更新UI的状态,那么你应该使用Handler类。

滚动

android框架提供了对视图内部滚动它们的内容的支持。这包括保持X和Y坐标滚动偏移的轨迹,它与绘制滚动条的机制一样。有关滚动条的更多细节,请看scrollBy(int, int),scrollTo(int, int) 和 awakenScrollBars()。

标签

不像IDs,标签不是用来作为视图的唯一标识的。
0 0
原创粉丝点击