android.view.View

认识几个基础类
android.os.Parcel 传送消息用的包裹类,用来读写基本类型的数据
android.os.Parcelable 接口,用来实现对象与Parcel之间的转换
android.graphics.drawable.Drawable  


android.view.View
View
 extends Object
 implements Drawable.CallbackKeyEvent.CallbackAccessibilityEventSource


Using Views-使用view


窗口中所有的view被组织成一棵单一的树.你可以通过编码或通过指定在一个或多个XML layout文件中的view的树来添加view.view有各种子类来显示文字,图片或其它内容.

 

当你创建了一棵view的树,通常可能要执行以下的几种操作:

  • 设置属性: 例如给TextView设置文字.各个子类可设置的属性和方法各不相同. 注意一点,在创建时可以确定的属性可以在XML布局文件中设置.
  • 设置焦点: 框架会根据用户的输入自动转换焦点.如果要设置一个view的焦点,调用requestFocus().
  • 设置监听器: view允许客户端在发生一些事件时设置监听器.例如,所有的view允许设置一个监听器,当view得到或失去 焦点时就会通知你.你可以通过setOnFocusChangeListener(View.OnFocusChangeListener)来设置这样的 一个监听器.其它的view还提供一些更多的特别的监听器.例如,Button提供一个监听器当按钮被按下时通知客户端.
  • 设置是否可见: 可以用setVisibility(int)设置view是否可见.

提示: Android 框架是负责对view进行测量,布局和绘制. 你不应该直接调用执行这些动作的方法,除非你是直接实现了一个 ViewGroup.

 

Implementing a Custom View  实现一个自定义的 View

 

要实现一个自定义的view,首先要覆写一些标准方法,这些方法是框架在所有的view上都会调用的. 这些方法不必全都覆写.实际上,从最简单的开始,可以只覆写onDraw(android.graphics.Canvas).

 

CategoryMethodsDescription
CreationConstructorsThere is a form of the constructor that are called when the view is created from code and a form that is called when the view is inflated from a layout file. The second form should parse and apply any attributes defined in the layout file.
onFinishInflate() Called after a view and all of its children has been inflated from XML.
LayoutonMeasure(int, int) Called to determine the size requirements for this view and all of its children.
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.
DrawingonDraw(Canvas) Called when the view should render its content.
Event processingonKeyDown(int, KeyEvent) Called when a new key event occurs.
onKeyUp(int, KeyEvent) Called when a key up event occurs.
onTrackballEvent(MotionEvent) Called when a trackball motion event occurs.
onTouchEvent(MotionEvent) Called when a touch screen motion event occurs.
FocusonFocusChanged(boolean, int, Rect) Called when the view gains or loses focus.
onWindowFocusChanged(boolean) Called when the window containing the view gains or loses focus.
AttachingonAttachedToWindow() 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 

 

view 可能有一个与它相关联的整数id.id通常是在XML布局文件中分配的.用来取得特定的view.通常形式是这样的:

  • 在布局文件中定义一个按钮,分配一个唯一的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 );

 

view的ID在不同的view树之间不必是唯一的,但保证它们在你要搜索的内容中是唯一的是一个好的实践.

 

Position  位置

 

view在几何学上是一个长方形.view有一个位置,用坐标表示左上的顶点. 还有两个尺寸,表示宽度和高度. 位置和尺寸的单位都是像素.

 

可以通过调用getLeft()和getTop()方法得到view的位置. 第一个得到view的X坐标,第二个得到view的Y坐标.这些方法都是返回view相对于它们父组件的坐标.

 

另外,还有几个方便的方法可以避免不必要的计算,getRight()和getBotton(). getRight() = getLeft()+getWidth()

 

Size, padding and margins  尺寸, 内边距,外边距

view的尺寸是用width和height表示的. 一个view实际上有两组宽度和高度值.

 

一组就是 measured widthmeasured height . 这组尺寸定义了一个view在它父组件的内部是多大(参照 Layout 获得更多细节.)它们可以通过方法 getMeasuredWidth()和getMeasuredHeight() 得到.

 

另一组就是width 和 height , 或者是叫做 drawing widthdrawing height.  这组尺寸定义了view在绘制时和布局之后在屏幕上的实际大小,这组值与 measured widthmeasured height  可能相同也可能不同. 这组值通过getWidth()和getHeight() 获得

 

测量view的尺寸,要考虑它的内边距.内边距用像素表示上下左右各个部分的距离.内边距可以用来偏移view的内容.

 

view可以定义内边距,但不能定义外边距. view group可以定义外边距.可以参照 ViewGroup 和ViewGroup.MarginLayoutParams 获取更多信息.

 

Layout  布局

 

布局共包含两个处理过程:测量过程和布局过程.测量过程在measure(int, int)方法中实现,它是按照view树自顶向下进行处理.按照递归顺序处理尺度标准.布局过程在layout(int,int,int,int)方法中进行,也是按自顶向下的顺序处理. 在布局过程中,每个父view负责根据测量过程中计算出的尺度摆放好每个子view的位置.

 

当一个view的measure()方法返回后,它的getMeasuredWidth()和getMeasuredHeight()方法的返回值必须被设置,所有后代的也必须已设置.view的 measured width 和measured height必须要考虑到父view的限制.这样才能保证在测量过程的最后,所有的父view可以接受它们的子view的尺度.父view可能对子view多次调用measure().例如,父view可能先不加限制地对所有子view进行一次测量,看所有的子view要占多大的空间,如果所有子view的和太大或太小,父view会用实际的数字再重新调用一次measure().

 

测量过程用两个类来时行尺寸交流.View.MeasureSpec用来告诉父view它们想要如何被测量和被摆放.LayoutParams类则只是描述它的宽和高想要多大.尺度可以设为以下值的一个:

  • 一个确定的数字
  • MATCH_PARENT, 想要跟它的父view一样大(减掉内边距)
  • WARP_CONTENT, 刚好能包含它的内容就行了(加上内边距)

LayoutParams有不同的子类来对应ViewGroup的不同子类.例如,AbsoluteLayout有它自己对应的LayoutParams的子类,可以额外地设置X值和Y值.

 

MeasureSpec用来在树中自顶向下地传递需求.MeasureSpec可以是以下三种模式之一:

  • UNSPECIFIED: 父view用来测量子view需要多大的尺度.例如,LinearLayout对它的子类调用measure(),height设为UNSPECIFIED,width设为240,这样可以得到当宽度为240时,子view的高度为多少.
  • EXACTLY:父view为子view设置一个固定值.子view必须使用这个值,并保证它的后代也要适应这个值.
  • AT_MOST:父view为子view设置一个最大值.子view保证它和它的后代适应这个值.

然后看一下  requestLayout()方法是什么意思,用来干什么. 这个方法一般是view确信它不能适应现在的边界时对自己调用.

 

Drawing 绘制

 

绘制是通过遍历view树并且渲染每个在有效区内的view.树是有顺序的,父view会在子view之前被绘制,兄弟view之间按照在树中出现的顺序绘制.如果为view设置了可绘制的背景,那么背景会在view的onDraw()方法调用之前被绘制.

 

框架不会绘制在有效区之外的view.

 

强制一个view进行绘制,可以调用invalidate()方法.

 

Event Handling and Threading 事件处理和线程

 

基本过程如下:

  1. 一个事件到来,分发到适当的view.view处理事件并通知所有的监听器.
  2. 如果事件处理过程中,边界需要改变,调用requestLayout()方法
  3. 相似地,如果处理过程中view的外观需要改变,则调用invalidate()方法
  4. 如果以上两个方法都需要调用,框架会处理好view树的测量,布局和绘制.

注意: 整个的view树是放在单个的线程进行处理的.当你对任何view调用任何方法时必须是在UI线程中.如果你在别的线程中进行工作,并想在那个线程中对view进行更新, 你应该使用Handler. (android.os.Handler)

 

Focus Handling  焦点处理

 

框架来处理焦点的转移.包括view被移除或隐藏时,或新的view可用时.view通过isFocusable()指示它们是否可以获得焦点,通过setFocusable(boolean)设置是否可以获得焦点.在触摸模式下,则用isFocusableInTouchMode() 和 setFocusableInTouchMode(boolean).

 

焦点移动根据一个算法来找到给定方向上最近的邻居.在极少数情况下,算法可能与开发者希望的行为不一致.在这种情况下,你可以用以下的XML属性来提供明确的行为:

  • nextFocusDown
  • nextFocusLeft
  • nextFocusRight
  • nextFocusUp

让特定的view获得焦点,可以调用requestFocus()方法

 

Touch Mode  触摸模式

 

当用户直接用键盘操作时,要有一个"活动的"项目来指示哪个项目会得到输入.当设备有在触摸功能,用户使用触摸功能时,不需要总是高亮或获得焦点.这会激活一个叫做"触摸模式"的用户交互模式.

 

对于一个有触摸功能的设备,当用户摸到屏幕时,设备会进入触摸模式.这之后,只有isFocusableInTouchMode()返回true的view才会获得焦点,如文本输入框.其它可触摸的view,像是按钮,被触摸时不会获得焦点,只会触发click监听器.

 

在任何时候,只要用户直接击打键盘,如D-pad,view会退出触摸模式,并找一个view来获得焦点,用户可以再次使用键盘与程序交互.

 

触摸模式状态是通过Activity维护的,调用isInTouchMode()来看设备是否处于触摸模式.

 

Scrolling  滚动

 

框架为view提供了内在的滚动支持.包括跟踪X和Y坐标和绘制滚动条的机制.参照 scrollBy(int,int),scrollTo(int, int)和awakenScrollBars() 获得更多细节.

 

Tags 标签

 

跟ID不同,标签不是用来区分view的. Tags根本上是可以与view关联的额外信息.通常做为一种方便的手段来存储数据,这样就不用放到一个单独的结构中.

 

Animation 动画

 

你可以将一个Animation对象附加到一个view上,用setAnimation(Animation)或startAnimation(Animation)方法.animation会随着时间改变view的尺度,旋转,透明度等等.如果动画附加到的view有后代,那么以这个view为根的整棵view树都会被影响.当动画开始后,框架会负责view的重绘直到动画完成.

 

从Android3.0开始,让view产生动画的首选API是android.animation包中的API.

 

Security 安全

 

Sometimes it is essential that an application be able to verify that an action is being performed with the full knowledge and consent of the user, such as granting a permission request, making a purchase or clicking on an advertisement. Unfortunately, a malicious application could try to spoof the user into performing these actions, unaware, by concealing the intended purpose of the view. As a remedy, the framework offers a touch filtering mechanism that can be used to improve the security of views that provide access to sensitive functionality.

To enable touch filtering, call setFilterTouchesWhenObscured(boolean) or set the android:filterTouchesWhenObscured layout attribute to true. When enabled, the framework will discard touches that are received whenever the view's window is obscured by another visible window. As a result, the view will not receive touches whenever a toast, dialog or other window appears above the view's window.

For more fine-grained control over security, consider overriding the onFilterTouchEventForSecurity(MotionEvent) method to implement your own security policy. See also FLAG_WINDOW_IS_OBSCURED .

See Also

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值