public class

View

extends  Object

implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource

Class Overview


这个类代表了构建用户交互组件的基本单元。一个View是一块绘制和接收用户事件的位于屏幕上的长方形区域。它是widgets的基础(widgets指用户交互组件)。而子类ViewGroup则是布局的基础(布局:用于容纳其他Views,并定义他们的布局属性)。

Developer Guides 开发向导

想要知道更多,参阅User Interface开发向导。

Using Views 使用

所有处于窗口中的view都被安排在一颗树上(即只有一个根节点)。你可以从代码或者特定的XML布局文件中来添加views。这儿有很多特殊view的子类,他们具有控制或者显示文本,图片及其他内容的能力。

一旦你创建views的树,你可能希望实现几个典型的通用操作:

设置属性:可在构建时用XML定义。

设置焦点:调用requestFocus()

设置监听器:可通知获得或者失去焦点。子类具有更多监听事件

设置可见性:使用setVisibility(int)设置可见性


注意:安卓框架对测量,布局和绘制图形负责。你不应该调用这些方法来执行相应的行为,除非你确实实现了ViewGroup。

Implementing a Custom View   实现自定义的View

实现自己的View,覆盖下面框架的几个回调方法即可。你不需要重写所有的方法。事实上,你可用从重写onDraw(android.graphics.Canvas)开始

Category Methods Description
Creation

Constructors

构造体

有一种从代码创建或者从布局文件膨胀时调用,另一种是粘贴及应用布局文件中定义的属性。

onFinishInflate()

当其子类完成膨胀时调用.

Layout onMeasure(int, int)

当决定view和它的孩子的尺寸时调用.

onLayout(boolean, int, int, int, int) Called when this view should assign a size and position to all of its children.
onSizeChanged(int, int, int, int) Called when the size of this view has changed.
Drawing onDraw(android.graphics.Canvas) Called when the view should render its content.

Event processing

事件

处理

onKeyDown(int, KeyEvent) Called when a new hardware key event occurs.
onKeyUp(int, KeyEvent) Called when a hardware key up event occurs.
onTrackballEvent(MotionEvent) Called when a trackball motion event occurs.
onTouchEvent(MotionEvent) Called when a touch screen motion event occurs.

Focus

焦点

onFocusChanged(boolean, int, android.graphics.Rect) Called when the view gains or loses focus.
onWindowFocusChanged(boolean) Called when the window containing the view gains or loses focus.

Attaching

依附

onAttachedToWindow() Called when the view is attached to a window.
onDetachedFromWindow() Called when the view is detached from its window.
onWindowVisibilityChanged(int) Called when the visibility of the window containing the view has changed.

IDs

Views有很多整形id与其相关。这些id被分配到XML布局文件中,用于寻找特定的view。通用模式如下:

  • 定义一个布局文件并赋予其唯一ID
          android:id="@+id/my_button"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:text="@string/my_button_text"/> 
  • 在Activity中的onCreate回调方法中找到这个button.
          Button myButton = (Button) findViewById(R.id.my_button); 

视图的ID并不需要在整个树中唯一,但是最佳实践是让它在你搜索的那一部分树上唯一。


Position 位置

View是长方体,它为坐标指的是距离左/上 距离,计量单位是像素。

一种可能的检索view位置的方式是调用 和 方法。前者返回 左(X),后者返回 上(Y)。返回值都是相对于父容器的。举个例子,当getLeft()返回20,它意味着它距离它的直接父容器左边的距离为20。

额外的,一些便利类可以让你减少计算,例如getRight() 和 getBottom()

Size, padding and margins  尺寸,填充 和 边缘

The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.

尺寸代表了宽度和高度,这儿有两种标准:

第一种被称做:测量宽度和测量高度。这些尺寸定义了views想在它的父容器中有多大。通过调用getMeasuredWidth() and getMeasuredHeight()取得这些尺寸。

第二种就是 宽度和高度,也叫做 绘制宽度 和绘制高度。这些尺寸定义了,在布局完成后绘制时,实际绘制在屏幕上的实际尺寸。通过调用 getWidth() and getHeight()获得这些尺寸。

 For instance, a left padding of 2 will push the view's content by 2 pixels to the right of the left edge. Padding can be set using the setPadding(int, int, int, int) or setPaddingRelative(int, int, int, int) method and queried by calling getPaddingLeft()getPaddingTop()getPaddingRight()getPaddingBottom()getPaddingStart()getPaddingEnd().

在绘制尺寸时,view是将填充也计算在内了的。填充以像素表示,具有左、上、右、下四个部分。填充使得view的内容能够以指定的像素进行偏移。举个例子,左边2的填充意味着view的内容向右边移动了2个像素。你可以使用下面这些方法:

 setPadding(int, int, int, int) , setPaddingRelative(int, int, int,int) , 

 getPaddingLeft()getPaddingTop(),

  getPaddingRight()getPaddingBottom()getPaddingStart()getPaddingEnd().


尽管view定义了填充,但是没有对 边缘(margins) 提供任何支持,它被放在了 ViewGroup 和ViewGroup.MarginLayoutParams中了。

Layout 布局

布局有两个过程:测量和布局。测量实现了measure(int, int),它自顶向下的遍历了view树。在递归过程中,每个view被分配了特定的尺寸。在测量完成后,每个view将存储他的测量值。第二步在 中,它也是自顶向下的.在这一步中,每个父容器都使用在上一步得到的值来计算子view的位置。

在view完成了measure方法返回后,getMeasuredWidth()  和getMeasuredHeight()值必须被设置。一个view的测量宽度和测量高度值必须遵循父view的限制。这可以保证,在测量后,所有的父亲都能够接受子View的测量。父View可能不止一次调用子的measure()。举个例子,父view可能测量子View使用的是不确定的尺寸,来找出它想要多大,然后再一次使用实际值调用measure(),如果所有子类未加限制的尺寸过大或者太小

测量经过两个类计算尺寸。View.MeasureSpec类用于告知父类他们想怎样被测量和定位。基本的LayoutParams类只是描述他们想要的高度和宽度。对于每一个维度:可以指定为以下几个值:

  • 确切的数字
  • MATCH_PARENT,这意味着它们想和父容器一样大(减去padding)
  • WRAP_CONTENT,这意味着他们只想和他们包含的内容一样大(加上padding)

有不同的LayoutParams子类对应着不同的ViewGroup的子类。举个例子,绝对布局拥有可以添加X和Y的布局子类。

测量空间(MeasureSpecs)用于自上而下的推送需求。测量空间可以是下面三种的一种:

  • 未指定的(UNSPECIFIED):这用于父容器绝对子类视图尺寸。举个例子,线性布局可能通过调用 子类的measure()方法,通过设定高度为UNSPECIFIED以及240确切的宽度来发觉子类在给予240像素宽度时,子视图需要的高度。
  • 确切的(EXACTLY):这用于父容器强加一个确切的数给其子类。子类必须使用这个尺寸,这保证了所有其子孙视图都会适配这个值。
  • 最大的(AT_MOST):这用于父容器强加一个最大值给其子类。子类必须保证自己和子孙视图适配这个值。

为了初始化布局,调用requestLayout() 。这个方法典型的应用是视图认为自身不在适配当前的边界。

Drawing 绘制

绘制是通过遍历和将视图插入到无效区域(未被使用区域)来完成的。由于树的遍历是有顺序的,这意味着父节点会先绘制前面的,然后才是它的兄弟。如果你给一个VIEW设定了背景drawable,那view将会在为你先绘制,然后才调用它的onDraw() 方法。

注意:在非无效区域的视图是不会被框架所绘制的。

为了强制完成绘制工作,调用invalidate().

Event Handling and Threading  事件处理和线程

一个view基本的周期如下:

1. 一个事件到来并被分配给合适的view。这个view将事件通知给任何注册的监听者。

2. 在处理事件中,视图的边界可能需要改变,调用requestLayout() 。  

3. 相似的,如果在处理事件过程中需要更新界面,调用invalidate() 。

4. 如果requestLayout()或者invalidate()被调用了,框架将会处理 测量,布局和绘制工作。

注意:整个视图树是单一的线程。当你调用任何视图的方法时,你总是处于UI线程中。如果你在工作线程中想要更新视图的状态,你应该使用Handler。


Focus Handling   焦点处理

框架将会例行的响应用户输入的响应。这包含了当视图移除或者隐藏起来,新的视图出现时等改变。视图在方法isFocusable()中表明了他们想要获得焦点的意愿。去改变一个视图的焦点,调用setFocusable(boolean),而不管它是否能够获得焦点。当在触屏模式下,视图表明他们是否愿意通过isFocusableInTouchMode() 获得焦点,或者通过 setFocusableInTouchMode(boolean)改变焦点。 

焦点移动是基于给定方向的最近邻居算法。在很少的情况下,算法和开发者想要的效果不一致。在这些情况下,你才需要显示的在XML布局文件中覆盖这些属性。

 nextFocusDown nextFocusLeft nextFocusRight nextFocusUp 


为了让特殊的VIEW获得焦点,调用requestFocus()。

Touch Mode 触摸模式

用户经由类似D-pad的直接案件导航到用户接口,这有必要聚焦到用户所见的输入控件上。如果设备有触摸能力,那么,所有的用户都以触摸方式完成交互,那么高亮或者给予特定视图焦点就不再有必要。这种模式也就是“触摸模式”。

对于具有触摸能力的设备,一旦用户触摸屏幕,设备即进入触摸模式。从这一点往后,只有isFocusableInTouchMode()为真的视图才会继续拥有焦点,例如编辑小部件。其他的视图是可触摸的,例如按钮,在被触摸时,将不会获得焦点。他们仅仅是响应用户的点击行为。

Any time a user hits a directional key, such as a D-pad direction, the view device will exit touch mode, and find a view to take focus, so that the user may resume interacting with the user interface without touching the screen again.

任何用户直接的按键,例如直接 D-pad,视图设备将会推出点击模式,然后发现一个View来获得焦点,然后用户可以恢复交互直到用户再次点击。

触摸模式可在活动间传播。调用isInTouchMode()来观察设备当前是否处于触摸模式。

Scrolling 滚动

框架对于需要滚动内部内容的视图提供基本的支持。这包含了跟踪X和Y的滚动偏移,以便绘制滚动条的位置。更多细节见 scrollBy(int, int)scrollTo(int, int), 和 awakenScrollBars()

Tags 标记

不同于ID,标记并不用于标识视图。标记用于为VIEW添加额外的信息片段。他们最常用于作为view自身便利的数据存储,而无需放在额外的数据结构中。

Properties 属性

View类曝光了ALPHA属性,作为几种平台相关的属性,例如TRANSLATION_X 和 TRANSLATION_Y。和他们的属性既可以以属性方式,也可以用 setter/getter方法。

Animation 动画

自安卓3.0开始,更好使用动画的方式是使用android.animation 包中的API。这些基于动画的类改变了视图实际的属性,例如透明度和偏移X(alpha and translationX)。

Security 安全

有时候确认一个行为是用户完全的行为是有毕业的,例如权限的确认,执行一次购买,或者点击广告。不幸的是,恶意程序可能尝试欺骗用户无意识的执行这些行为。作为一种补救措施,框架提供一种可用语提交视图访问敏感功能的点击过滤机制。

为了使用点击过滤,调用setFilterTouchesWhenObscured(boolean) 或者设置 。当能够使用时,框架将会放弃 。作为结果,当有Toast,对话框或者窗口出现在视图窗口的上方时,视图将不会接受点击事件。

对于更多细力度的安全控制,考虑覆盖onFilterTouchEventForSecurity(MotionEvent) 方法来实现你自己的安全策略。参考:FLAG_WINDOW_IS_OBSCURED


更多相关文章

  1. Android(安卓)浅析 ContentProvider (四) 启动原理
  2. Android实现机制(二)——View绘制机制
  3. Android(安卓)Camera 三 CameraService 和 Client 链接到 HAL
  4. Android横竖屏切换重载问题与小结
  5. 三.如何创建窗口模式的Activity
  6. Android自定义Dialog二次调用报错解决方法:The specified child a
  7. Android(安卓)JsBridge源码学习
  8. Android类参考---Fragment
  9. Android(安卓)Material Design之CoordinatorLayout全面使用介绍

随机推荐

  1. 关于android 1.6全部的权限介绍
  2. QMUI android 框架 git下载项目运行报错
  3. Android(安卓)新的锁屏接口的实现
  4. 编译android 7.0 出现Try increasing hea
  5. android 开源组件合集-UI篇(2013-11-07更
  6. android 源码开发 关于编译等小知识点总
  7. android emulator创建avd命令
  8. Android(安卓)4.0 wifi 和 Ethernet 的实
  9. Android(安卓)Adb指令
  10. android onGestureListener的方法