Android 视图(View)概述

来源:互联网 发布:淘宝客扣分在哪里看 编辑:程序博客网 时间:2024/05/07 17:33

视图(View)是一个矩形区域,它负责这个区域里的绘制和事件处理。视图类是Android用户界面的基础类之一。视图组(ViewGroup)是视图的子类,是一个容器,专门负责布局。视图组本身没有可绘制的元素。
        开发用户界面可以先阅读开发者向导的用户界面(User Interface)部分。
        该文章包含:
                声明布局
                创建菜单
                公用布局对象
                AdapterView绑定数据
                处理UI事件
                应用风格(styles)或主题(themes)
                自定义组件
                Android怎样绘制视图

使用视图
        一个窗口中的所有视图是一个树形结构。你可以通过代码创建视图,也可以通过XML布局文件来创建。文本、图像都是视图的派生类。
        视图和其子类具有如下共同特性:
         设置属性,例如设置文本视图的文本。不同的子类具有不同的属性,这些属性在设计时可以设定。
         设置焦点,为了响应用户输入,Android框架会处理焦点的转移。要把焦点转移到特定视图上,可以使用requestFocus()函数。
         设置监听器(listener),视图可以让客户端设置监听器,特定事件发生时这些监听器会收到通知。例如,视图得到或失去焦点时,会收到关于焦点的通知。你可以使用setOnFocusChangeListener(View.OnFocusChangeListener)来注册监听器。例如,按钮Button就有一个点击事件的监听器。
         设置可见性,用setVisibility(int)显示和隐藏视图。
        Android框架负责视图的测量(measuring)、布局(laying out)、绘制(drawing)。一般情况你不需要调用这些方法,除非你重载ViewGroup这样的布局类。

自定义视图
        自定义视图需要重载下列一些方法。
       

IDs
        视图有整数ID,这些ID一般在XML布局文件中分配。一般的样式
        定义一个按钮并分配一个唯一ID
         <Button id="@+id/my_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/my_button_text"/>
        onCreate函数创建视图时,查找一个按钮
                Button myButton = (Button) findViewById(R.id.my_button);
        视图ID并不要求是全局唯一,不过为了便于搜索最好在视图树的局部是唯一。

位置
        视图在几何上就是一个矩形,左上角的left和top坐标定位,宽width和高height表示尺寸大小,单位是像素pixel。
        使用getLeft()和getTop()获取左上角位置,这些位置都是相对于父视图。
        此外还有几个方便方法getRight()和getBottom()获得右边和底部位置。

尺寸,内间距padding,外间距margins
        视图的尺寸用宽和高表示,一个视图有两对宽高值。
        第一对宽高值是测量值(measured width, measured height),测量值是子视图相对父视图的尺寸大小期望值。可以用getMeasuredWidth()和getMeasuredHeight()获取。
        第二对宽高值是实际值,实际尺寸是视图完成布局后绘制时用到的值。
        测量尺寸大小时要计算内间距padding,内间距表示了视图内各个子控件到父控件上下左右四条边的间距。
        普通视图不支持外间距,只有ViewGroup支持。详见ViewGroup.MarginLayoutParams。

布局Layout
        布局分两个阶段(pass):测量阶段(measure pass)和布局阶段(layout pass)。测量阶段在measure(int, int)方法中实现,整个过程就是从上至下的视图树遍历。在这个递归过程,每个视图都提供尺寸大小描述。测量阶段的最后,每个视图都保存了自己的测量结果。布局阶段在layout(int, int, int, int)函数中实现,这也是一个从上至下的过程。在布局阶段,每个父视图使用测量阶段的估算值为子视图安排位置和大小。
        当视图的measure()方法返回后,它和它的子控件的测量值都已经计算出来了。子控件的测量值都要考虑父视图的区域限制,这就保证了在测试阶段结束时,每个父视图能接受其所有子控件的测量结果。子控件的measure()方法可能被多次调用。例如,包含了尺寸不确定的子控件,父控件会对每个子控件调用一次measure()方法,然后再对尺寸明确的子控件调用measure()方法,这样作是为了保证没有确切尺寸的子控件不至于太大或太小。
        测量阶段会用到两个类:View.MeasureSpec和LayoutParams。视图使用View.MeasureSpec类来表明自己所期望的位置和测量方式,LayoutParams则是来表明自己期待的大小。
        它们都可以使用下面的值:
                确切的数值
                MATCH_PARENT,在父控件里尽可能的大(除去内间距padding值)。
                WRAP_CONTENT,尽可能的小,只要能容纳自己的子控件即可(加上内间距padding值)。
        LayoutParams有一些派生类,会被视图组ViewGroup用到。例如,AbsoluteLayout包含了X和Y值,用来描述布局时的绝对位置。
        MeasureSpecs在父视图向子控件询问布局期望时会被用到。它有三种模式:
        UNSPECIFIED,未指定,父控件向子控件询问布局期望值。例如,线性布局类LinearLayout想知道子控件在宽为240的时候高的期望值,便可以调用子控件的measure()方法,并在传递参数中指定高为UNSPECIFIED,宽为确定值240像素。
        EXACTLY,确定值,父控件指定子控件的尺寸,并要求该子控件的子控件也必须适应这个尺寸。
        AT_MOST,最大值,父控件指定子控件的最大尺寸,并要求该子控件的子控件也必须适应这个尺寸。
        当视图想父控件再次对自己执行布局操作时,可以调用requestLayout(),一般在视图的尺寸发生改变时会有这种需求。

绘制Drawing
        绘制按照视图树的顺序执行。视图绘制时会先绘制子控件。如果视图的背景可见,视图会在调用onDraw函数之前绘制背景。
        强制重绘,可以使用invalidate()。

事件处理和线程
        事件的基本流程如下:
                1。事件分配给相应视图,视图处理它,并通知相关监听器。
                2。操作过程中如果发生视图的尺寸变化,则该视图用调用requestLayout()方法,向父控件请求再次布局。
                3。操作过程中如果发生视图的外观变化,则该视图用调用invalidate()方法,请求重绘。
                4。如果requestLayout()或invalidate()有一个被调用,框架会对视图树进行相关的测量、布局和绘制。
        注意,视图树是单线程操作,直接调用其它视图的方法必须要在UI线程里。跨线程的操作必须使用句柄Handler。

焦点处理
        框架处理焦点的转移,来响应用户输入。isFocusable()函数表示视图是否能接受焦点。setFocusable(boolean)函数可以改变视图能否接受焦点。触摸屏模式(Touch Mode)的相关函数是isFocusableInTouchMode()和setFocusableInTouchMode(boolean)。
        焦点转移按照就近算法。按哪个方向就近可以在XML布局文件中配置。
         nextFocusDown
         nextFocusLeft
         nextFocusRight
         nextFocusUp
        视图请求焦点可以使用requestFocus()。

触摸屏模式Touch Mode
        当用户使用方向键盘(D-pad)操作时,当前控件需要聚焦高亮来提示用户。但是对于触摸屏,就不再需要这种高亮了。我们管这种模式叫触摸屏模式。
        用户一接触触摸屏设备就进入触摸屏模式。从此,只有isFocusableInTouchMode()函数返回true的视图才能聚焦高亮,例如文本框。而按钮就不需要在触摸屏模式下高亮了。
        用户一接触方向键,界面就退出触摸屏模式,并找到当前哪个视图需要聚焦高亮,以便用户在键盘模式下也能确认正在操作的控件。
        触摸屏模式是全局性的,跨Activity的。isInTouchMode()函数可以获得是否在触摸屏模式下。

滚动Scrolling
        视图本身支持滚动,包括XY的偏移位置和滚动条的绘制。

标签Tag
        标签用于储藏对象

动画Animation
        视图可以附加Animation对象,setAnimation(Animation)设置动画,startAnimation(Animation)启动动画。Animation可以按时间轴改变视图的位移、缩放大小、旋转角度和透明度,来制造动画效果。Animation的效果是包括了该视图的子视图。动画启动后,框架就负责重绘该视图。

原创粉丝点击