界面构造
原文地址:http://www.cnblogs.com/duguguiyu/archive/2010/03/27/1698515.html
UI界面,对于每个应用而言,是它与用户进行交互的门脸。好的门脸,不只是是要亮丽可人,最好还能秀色可餐过目不忘,甚至还应该有涵养有气质,彬彬有理温柔耐心。
对于开发者来说,锻造这样的面容,不但需要高超的技艺,也需要有称手的工具和对得起党的料子。俗话说,朽木不可雕也,芙蓉不是一日炼成的,不是什么平台都能叫特能书。有套好用的UI框架,对于开发者而言,真有如沙漠中的甘露,而要是撞见了杯具的UI套件,整个界面开发就有如梦魇了。
Android的UI框架,最核心的,是资源和Layout体系,然后,通过完善的控件库,简明的接口设计,进一步帮助开发者,能够最快的搭建自己需要界面(听到这里,Symbian同学开始钻土...)。
UI控件
做UI,有时候就像搭积木,在Android中,这个最原子的积木块,就是View。所有其他的UI元素,都是派生于此类的子孙类们。
又从SDK中偷来张图,用来描述Android的UI控件结构,在每一个window下,这都是一个标准而完整的树结构。View有一个子类ViewGroup,它相当于一个容器类或者是复合控件,所有派生与ViewGroup的子类在这颗UI树中都可以承担着父节点的职责,而另一些绕过ViewGroup从View直通下来的,就只能蜷局在叶节点的范畴内了。
之所有说这是一个很标准的控件树,是因为父控件对子控件有绝对的掌控权,每个子控件的占地面积和位置,都是基于父控件来分配的,它能够接受和处理的事件,也是父控件派发下去的。这样的结构,被很多平台和框架广泛的认可,和传统的win开发和杯具的Symbian相比,虽然因为事件传播途径变长了,很多操作的效率变低了,但整个结构更有层次性,每个控件只需要多其父控件负责指挥子控件就好,职责明确,逻辑简单,利于开发和设计。
谈及任何平台的控件,都有一些不可避免的主题,比如,每个控件如何标识,如何设定大小和位置,如何接受和处理事件,如何绘制,诸如此类。
标识
在Android中,你可以为每个控件选择设定一个id,这个id的全局的唯一性不需要保证,但在某个局部的范围内具有可识别性,这样就可以通过这个id找到这个控件(如果不需要查找,就别设置了...)。
但是,在父控件中逐级的find比较,找到id匹配的控件,然后再做转型,是一个比较重量的操作,于是Android又为控件憋出另一个属性,tag。它接受任意object类型的数据,你可以把和这个控件对象相关的内容堆在里面。比如,在list中,我们常常将和每个list item相关的所有控件元素封装成一个object,扔到tag中,就不需要每次都去比较id进行寻找,更加高效快捷。
尺寸
在Android中,控件最重要的大小属性,就是width/height,开发者可以明确的指明控件的大小,可以设定成为fill_parent和wrap_content,这样的概念性的大小。丈量并设定控件的位置,是通过两步来进行的。
第一步是measure。它传入此控件的width/height信息,控件会根据自己的参数,计算出真实需要的width/height,然后调用setMeasuredDimension方法,缓存成成员变量,留作后用。
在计算出大小之后,会进行另一个步骤,layout。在这个过程中,父控件会计算其上各个子控件的位置,从而完成整个大小和位置的确定流程。整个measure和layout的流程,都是自上到下,从树顶往叶子来推进的。
当开发人员需要自定义控件的时候,可能需要关注这些内容,通过重载onMeasure和onLayout方法,可以定义自己控件的丈量方式。
事件
在Android中,所有的按键,触屏等事件,都是从顶至下进行分发的。每个ViewGroup的对象,会维系一个focused变量,它表示在这个父控件中具备focus的控件,当有按键时间发生的时候,会找到这个focused子控件,并传递给它。同理,触屏事件的分发也是类似,只不过和focus无关,父控件会遍历所有子控件,看看谁处于触碰位置,从而传递给谁。
另外还有一些事件,逻辑上并不是从顶至下发起的。比如,当你修改某个子控件的内容,使得该子控件的大小和内容都发生了变化,就需要进行控件的重排和重绘,这些操作不仅是子控件自己的事情,需要整个控件树上的所有控件都需要配合。在Android中,处理这类事情的实现策略是子控件维系一个
ViewParent对象,该对象象征着整个控件树的管理者,子控件产生影响整个控件树的事件时,会通知到ViewParent,ViewParent会将其转换成一个自顶向下的事件,分发下去。
Android的事件处理逻辑,采用的是观察者模式。Android的控件提供了一些列的add/set Listener的接口,使得外部观察者,有机会处理控件事件。比如,你需要在某个button被点击时做一些事情,你就需要派生一个View.OnClickListener对象作为观察者,调用该控件的setOnClickListener接口注册进去,当button被点击,就可以获得处理点击事件的机会了。当然,有的时候,你需要处理的逻辑更为复杂,光是站在外面围观叫好不能解决问题,可能就需要派生某个控件,去重载onXXXX之类的事件处理函数,进行更完整的控制。
焦点
对于一个非触屏的机器,焦点的维系是一个极其重要的事情,而在有触屏的年代,焦点的地位虽有所下降,但依然还是需要妥善保护的。
Android中,是以控件树为单位,来管理焦点的。每个控件,可以设置上下左右四向的focus转移对象。当在一个控件上发生焦点转移事件,Android会如前述,自顶向下根据设定好的焦点转移逻辑,跳转到正确的控件上。和Symbian相比,真是,真是。。。
Layout
Layout是一类特殊的ViewGroup控件,它们本身没有任何可显示内容,形如透明的玻璃盒子,存活的唯一理由,就是其中的内部结构,能够更好的摆放它的子控件们。
有了Layout的存在,控件和控件之间不再割裂的存在,而是更有机的结合在了一起,设定起来也更为方便。比Symbian那样人肉维系各个控件的关系,轻松自在多了。
更多
如上图所示,假设你做了个如同虚线框中结构的一个界面,通过Activity的
setContentView方法,塞进了Activity中,就会形成图示的一个逻辑关系。每一个Activity,都包含一个
Window对象,它表示的是一个顶级的一整屏幕上面的界面逻辑。在Android源码中,其实现是
MidWindow,它包含了一个
FrameLayout对象,呈现出来就是那种带着一个title的界面样子。自定义的一堆控件,会插进Window的界面部分,在Activity中,所有事件的处理逻辑,是Window先享用,没消费掉在交由这堆控件吃剩的。
在整个控件树的最顶端,是一个逻辑的树顶,
ViewParent,在源码中的实现是
ViewRoot。它是整个控件树和
WindowManager之间的事件信息的翻译者。WindowManager是Android中一个重要的服务。它将用户的操作,翻译成为指令,发送给呈现在界面上的各个Window。Activity,会将顶级的控件注册到WindowManager中,当用户真是触碰屏幕或键盘的时候,WindowManager就会通知到,而当控件有一些请求产生,也会经由ViewParent送回到WindowManager中。从而完成整个通信流程。
分享到:
相关推荐
【标题】"安卓Android源码——飞碟说欢迎界面.zip" 涉及的主要知识点是Android应用程序开发,特别是用户界面(UI)的设计与实现。在这个压缩包中,开发者分享了飞碟说应用的欢迎界面源代码,这是一个常见的启动屏幕,...
"安卓Android源码——MyAppWeixin(仿微信界面).zip" 这个标题表明我们讨论的是一个关于安卓(Android)平台的开源项目,名为"MyAppWeixin",其主要目的是模仿微信的用户界面。这通常意味着开发者可能已经实现了微信...
【Android源码解析——构建高仿QQ登录界面】 在安卓(Android)开发中,源码是学习和理解系统运行机制以及应用开发的关键。本压缩包"安卓Android源码——高仿QQ登陆.zip"提供了一个模仿QQ登录界面的示例,这对于...
本资源“安卓Android源码——android打电话源码.rar”提供了一种深入理解如何在Android应用程序中实现打电话功能的方式。通过分析这个源码,我们可以学习到如何在Android系统中集成电话拨打功能,并了解相关API和...
本资源"安卓Android源码——android 自定义对话框.zip"包含了实现自定义对话框的源代码,这对于理解和实践Android应用的界面定制具有重要意义。 首先,我们要理解Android系统提供的默认对话框类`AlertDialog`和`...
本文将聚焦于Android源码,通过对"安卓Android源码——挨踢Club.zip"的剖析,探讨Android系统的内部构造和关键组件,帮助开发者深化对Android的理解。 首先,我们来了解一下Android源码的基本结构。Android源码主要...
本资源“安卓Android源码——Intent.rar”可能包含了Intent的详细源代码分析,帮助开发者深入理解Intent的工作原理。 1. **Intent基础概念**: Intent在Android中扮演着“信使”的角色,它携带数据并指明一个操作...
在安卓开发中,ArrayAdapter是一种常用的适配器,它用于将数据集与视图组件(如...这个资料包"安卓Android源码——(列表之ArrayAdapter适配)"提供的示例代码可以帮助你深入理解ArrayAdapter的使用,通过实践加深理解。
这个"Android源码——进度条源码.zip"压缩包很可能是包含了一个关于自定义进度条的源代码示例。下面我们将深入探讨Android进度条的基本使用、自定义以及源码分析。 1. **Android内置进度条类型**: - **...
本资料"Android源码——Intent切换.zip"很可能是关于Intent在Android应用开发中的详细解析,包括Intent的创建、使用方式以及源码分析。 首先,Intent分为显式Intent和隐式Intent两种类型。显式Intent明确指定了要...
"安卓Android源码——path时间控件.zip" 提供了一个使用Path类实现的时间选择器的源代码示例。Path类在Android图形库中用于构建和绘制复杂的2D图形路径,它允许开发者创建自定义的图形视图。本文将深入探讨Path类...
本教程将通过分析“安卓Android源码——解析json_dome.zip”中的内容,深入讲解如何在Android应用中解析JSON数据。 首先,我们需要了解Android SDK提供的一些关键类来处理JSON,主要包括`JSONObject`和`JSONArray`...
本压缩包"Android源码——查询工具源代码.zip"包含的是一套用于查询Android系统的源代码工具,这对于我们学习、调试和优化Android应用或者系统服务具有极大价值。下面,我们将详细探讨Android源码中的查询工具以及...
在Android开发中,Dialog是一种非常常见的用户界面组件,它用于显示临时信息或向用户征求一些简单输入。在标题“android dialog —— 日期和时间选择对话框.zip”中提到的,我们将探讨如何在Android应用中创建和使用...
《深入解析Android源码——基于switch-backport-master》 Android操作系统是全球最受欢迎的移动设备操作系统之一,其开源特性使得开发者可以深入理解系统的工作原理并进行定制化开发。本篇文章将聚焦于“switch-...
【安卓Android源码——Facebook客户端.zip】是一个包含Facebook客户端源代码的压缩文件,这对于学习和研究Android应用开发,特别是社交应用的实现具有重要的价值。在这个压缩包中,开发者可以深入理解Facebook应用...
【标题】"安卓Android源码——jamendo-开源在线音乐.zip"揭示了这是一份关于Android平台上的开源在线音乐应用项目——jamendo的源代码。Jamendo是一个知名的平台,它提供免费、合法的音乐流媒体服务,专注于独立艺术...
6. **UI设计**:使用Android Studio的布局编辑器设计用户界面,可能包括登录表单、错误提示等元素。 7. **异步处理**:为了防止网络操作阻塞主线程,源码可能使用AsyncTask、IntentService或现代的Coroutines、...
【Android 源码——天气预报源码】是一款基于Android平台的开源项目,它展示了如何在Android设备上实现天气信息的获取与展示。这个压缩包包含了一整套完整的天气应用源代码,对于开发者来说,是一个深入理解Android...
《Android源码——安全卫士源码》 在Android开发领域,深入理解源码是提升技术能力的关键步骤。本资源提供了“安全卫士”的源代码,让我们有机会一窥这款应用的内部构造,学习如何构建一个功能强大的手机安全保护...