Android的Window类(一) Android的GUI层并不复杂。它的复杂度类似于WGUI这类基于布局和对话框的GUI,与MFC、QT等大型框架没有可比性,甚至飞漫魏永明的MiniGUI都比它复杂许多。您也许会问,这样简单的GUI如何实现浏览器呢?原因很简单,浏览器有自己一套GUI。Android浏览器(WebKit)的GUI和Android的GUI实用同一套GDI——Skia,但GUI层是完全不同的设计,分别自成体系。 Windown类,位于代码树frameworks/base/core/java/android/view/Windowjava.java文件。连同注释,这个文件总共一千多行,它概括了Android窗口的基本属性和基本功能。 Window属性列举如下: FEATURE_OPTIONS_PANEL = 0; 功能不明,参见后面的说明(默认使能) FEATURE_NO_TITLE = 1; 无标题栏 FEATURE_PROGRESS = 2; 在标题栏上显示加载进度,例如webview加载网页时(条状进度条) FEATURE_LEFT_ICON = 3; 在标题栏左侧显示一个图标 FEATURE_RIGHT_ICON = 4; 在标题栏右侧显示一个图标 FEATURE_INDETERMINATE_PROGRESS = 5; 不确定的进度(圆圈状等待图标) FEATURE_CONTEXT_MENU = 6; 上下文菜单,相当于PC上的右键菜单(默认使能) FEATURE_CUSTOM_TITLE = 7; 自定义标题栏,该属性不能与其他标题栏属性合用 FEATURE_OPENGL = 8; 如果开启OpenGL,那么2D将由OpenGL处理(OpenGL中2D是3D的子集) PROGRESS_VISIBILITY_ON = -1; 进度条可见 PROGRESS_VISIBILITY_OFF = -2; 进度条不可见 PROGRESS_INDETERMINATE_ON = -3; 开启不确定模式 PROGRESS_INDETERMINATE_OFF = -4; 关闭不确定模式 PROGRESS_START = 0; 第一进度条的最小值 PROGRESS_END = 10000; 第一进度条的最大值 PROGRESS_SECONDARY_START = 20000; 第二进度条的最小值 PROGRESS_SECONDARY_END = 30000; 第二进度条的最大值 *说明:FEATURE_OPTIONS_PANEL的意思大概是:当用户选中菜单时,窗口将调用onOptionsItemSelected函数,以处理菜单功能。如果没有FEATURE_OPTIONS_PANEL选项,那么菜单就不响应了?没试过,网上也没找到。 应用示例: 1、隐藏标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); 2、在标题栏显示进度条 requestWindowFeature(Window.FEATURE_PROGRESS); setContentView(R.layout.progressbar_1); setProgressBarVisibility(true); final ProgressBar progressHorizontal = (ProgressBar)findViewById(R.id.progress_horizontal); setProgress(progressHorizontal.getProgress() * 100); setSecondaryProgress(progressHorizontal.getSecondaryProgress()* 100); 3、使用自定义标题栏 requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.xxx); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.my_title_bar); 4、清除标题栏内容,而区域保留 ((ViewGroup)getWindow().findViewById(com.android.internal.R.id.title_container)).removeAllViews(); 5、隐藏标题栏 ((ViewGroup)getWindow(). findViewById(com.android.internal.R.id.title_container)).setVisibility(View.GONE); 6、显示标题栏 ...setVisibility(View.VISIBLE); 其他注意事项 (1) requestWindowFeature()要在setContentView()之前调用; (2) 设置各种Feature,是具有排它性的,一旦设置,后续不可更改为别的类型; (3)当使用TabHost(由ActivityGroup派生)时,各个Tab里的Activity,要么都是NO_TITLE,要么都是CUSTOM_TITLE,无法分别进行设置。 Android的Window类(二) Window类除去一大堆FEATURE_属性之外,剩下的内容无外乎两大部分: 一、定义Callback接口,它包含一系列dispatchXxxx函数和一系列onXxxx函数,用于处理UI事件; 二、定义了自己的WindowManager——LocalWindowManager。主要修改了addView函数,设置title。 Callback接口包含以下函数: public boolean dispatchKeyEvent(KeyEventevent); 处理Key事件。至少,你的代码要调用superDispatchKeyEvent函数。 public booleandispatchTouchEvent(MotionEvent event); 处理touch事件。至少,你的代码要调用superDispatchTouchEvent函数。 public booleandispatchTrackballEvent(MotionEvent event); 处理trackball事件。至少,你的代码要调用superDispatchTrackballEvent函数。 public booleandispatchPopulateAccessibilityEvent(AccessibilityEventevent); 处理Accessibility事件(辅助事件,如焦点变化,按钮被点击等),处理完成后返回true。 创建显示panel的view 可返回null,将为你创建默认content(通常是一个menu)。 应返回放置panel的顶层view。 public View onCreatePanelView(intfeatureId); 初始化panel菜单,如果onCreatePanelView函数返回null将调用此函数,创建一个标准菜单,你可以向它添加菜单项。只有当panel第一次显示时方调用此函数。如果返回false,panel将无法显示。 public boolean onCreatePanelMenu(intfeatureId, Menu menu); 每次panel窗口显示前,都会调用此函数。应当返回true,如果返回false将不显示。 public boolean onPreparePanel(intfeatureId, View view, Menu menu); 当用户打开panel的菜单时被调用。当菜单样式切换时也会调用。例如,从图标菜单切换至扩展菜单。 返回true允许菜单打开,返回false阻止菜单打开。 public boolean onMenuOpened(intfeatureId, Menu menu); 用户选择菜单项。 public boolean onMenuItemSelected(intfeatureId, MenuItem item); 当前窗口属性改变。 public voidonWindowAttributesChanged(WindowManager.LayoutParamsattrs); 窗口的view发生改变。 public voidonContentChanged(); 窗口焦点变化。 public void onWindowFocusChanged(booleanhasFocus); 窗口附加到窗口管理器上。 public voidonAttachedToWindow(); 窗口从窗口管理器上摘除。 public voidonDetachedFromWindow(); panel关闭时被调用。 如果一个后续的panel将展开(此panel为后续panel腾出空间),则不会调用此函数。 public void onPanelClosed(int featureId,Menu menu); 当用户按下了search按钮。 如果启动了搜索界面则返回true,如果不能执行则返回false。 public booleanonSearchRequested(); WindowManager干什么?它并不是什么“窗口管理器”,WindowManagerService才是窗口管理器。名字叫的玄乎,而实际上WindowManager主要管理一堆状态字,而这些状态字里,最常用的就是LayoutParams。 派生关系如下: ViewManager | ---- >WindowManager ViewManager只有三个函数:addView,updateViewLayout,removeView。 而WindowManager的LayoutParams子类内容十分丰富。其实WindowManager.java的主要内容就是由这个类定义构成。它的定义如下: public static class LayoutParams extendsViewGroup.LayoutParams implementsParcelable 派生关系如下: ViewManager.LayoutParams | ---- >WindowManager.LayoutParams ViewManager的LayoutParams主要有两个宏,两个变量。 两个宏: FILL_PARENT WRAP_CONTENT 两个变量: width height WindowManager的LayoutParams就比较丰富了,咱们下回分解。 Android的Window类(三) WindowManager的LayoutParams子类,可用“内容丰富”一词形容。 如果忽略gravity属性,那么它表示窗口的绝对X位置。 什么是gravity属性呢?简单地说,就是窗口如何停靠。 当设置了Gravity.LEFT或Gravity.RIGHT之后,x值就表示到特定边的距离。 public intx; 如果忽略gravity属性,那么它表示窗口的绝对Y位置。 当设置了Gravity.TOP或Gravity.BOTTOM之后,y值就表示到特定边的距离。 public inty; 在纵向上,为关联的view预留了多少扩展空间(像素)。如果是0,那么此view不能被拉伸。 其他情况下,扩展空间(像素)将被widget所均分。 public floathorizontalWeight; public floatverticalWeight; 窗口类型。有3种主要类型: Applicationwindows:取值在 FIRST_APPLICATION_WINDOW和LAST_APPLICATION_WINDOW 之间。 是通常的、顶层的应用程序窗口。必须将token设置成activity的token。 Sub_windows:取值在 FIRST_SUB_WINDOW和 LAST_SUB_WINDOW 之间。 与顶层窗口相关联,token必须设置为它所附着的宿主窗口的token。 Systemwindows:取值在 FIRST_SYSTEM_WINDOW和 LAST_SYSTEM_WINDOW 之间。 用于特定的系统功能。它不能用于应用程序,使用时需要特殊权限。 public inttype; 下面定义了type的取值: 应用程序窗口。 public staticfinal int FIRST_APPLICATION_WINDOW = 1; 所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。 public staticfinal int TYPE_BASE_APPLICATION =1; 普通应哟功能程序窗口。token必须设置为Activity的token,以指出该窗口属谁。 public staticfinal int TYPE_APPLICATION = 2; 用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。 它用于让系统显示些信息,直到应用程序可以开启自己的窗口。 public staticfinal int TYPE_APPLICATION_STARTING = 3; 应用程序窗口结束。 public staticfinal int LAST_APPLICATION_WINDOW = 99; 子窗口。子窗口的Z序和坐标空间都依赖于他们的宿主窗口。 public staticfinal int FIRST_SUB_WINDOW = 1000; 面板窗口,显示于宿主窗口上层。 public staticfinal int TYPE_APPLICATION_PANEL =FIRST_SUB_WINDOW; 媒体窗口,例如视频。显示于宿主窗口下层。 public staticfinal int TYPE_APPLICATION_MEDIA =FIRST_SUB_WINDOW+1; 应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上) public staticfinal int TYPE_APPLICATION_SUB_PANEL =FIRST_SUB_WINDOW+2; 对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。 public staticfinal int TYPE_APPLICATION_ATTACHED_DIALOG =FIRST_SUB_WINDOW+3; 媒体信息。显示在媒体层和程序窗口之间,需要实现透明(半透明)效果。(例如显示字幕) public staticfinal int TYPE_APPLICATION_MEDIA_OVERLAY =FIRST_SUB_WINDOW+4; 子窗口结束。 public staticfinal int LAST_SUB_WINDOW = 1999; 系统窗口。非应用程序创建。 public staticfinal int FIRST_SYSTEM_WINDOW = 2000; 状态栏。只能有一个状态栏;它位于屏幕顶端,其他窗口都位于它下方。 public staticfinal int TYPE_STATUS_BAR =FIRST_SYSTEM_WINDOW; 搜索栏。只能有一个搜索栏;它位于屏幕上方。 public staticfinal int TYPE_SEARCH_BAR =FIRST_SYSTEM_WINDOW+1; 电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。 public staticfinal int TYPE_PHONE =FIRST_SYSTEM_WINDOW+2; 系统提示。它总是出现在应用程序窗口之上。 public staticfinal int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3; 锁屏窗口。 public staticfinal int TYPE_KEYGUARD =FIRST_SYSTEM_WINDOW+4; 信息窗口。用于显示toast。 public staticfinal int TYPE_TOAST =FIRST_SYSTEM_WINDOW+5; 系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。 public staticfinal int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6; 电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。 public staticfinal int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7; 系统对话框。(例如音量调节框)。 public staticfinal int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8; 锁屏时显示的对话框。 public staticfinal int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9; 系统内部错误提示,显示于所有内容之上。 public staticfinal int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10; 内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖。 public staticfinal int TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11; 内部输入法对话框,显示于当前输入法窗口之上。 public staticfinal int TYPE_INPUT_METHOD_DIALOG=FIRST_SYSTEM_WINDOW+12; 墙纸窗口。 public staticfinal int TYPE_WALLPAPER =FIRST_SYSTEM_WINDOW+13; 状态栏的滑动面板。 public staticfinal int TYPE_STATUS_BAR_PANEL =FIRST_SYSTEM_WINDOW+14; 系统窗口结束。 public staticfinal int LAST_SYSTEM_WINDOW = 2999; 指出窗口所使用的内存缓冲类型。默认为NORMAL。 public intmemoryType; 窗口缓冲位于主内存。 public staticfinal int MEMORY_TYPE_NORMAL = 0; 窗口缓冲位于可以被DMA访问,或者硬件加速的内存区域。 public staticfinal int MEMORY_TYPE_HARDWARE = 1; 窗口缓冲位于可被图形加速器访问的区域。 public staticfinal int MEMORY_TYPE_GPU = 2; 窗口缓冲不拥有自己的缓冲区,不能被锁定。缓冲区由本地方法提供。 public staticfinal int MEMORY_TYPE_PUSH_BUFFERS = 3; 行为选项/旗标,默认为none public intflags; 窗口之后的内容变暗。 public staticfinal int FLAG_DIM_BEHIND = 0x00000002; 窗口之后的内容变模糊。 public staticfinal int FLAG_BLUR_BEHIND = 0x00000004; 不许获得焦点。 不能获得按键输入焦点,所以不能向它发送按键或按钮事件。那些时间将发送给它后面的可以获得焦点的窗口。此选项还会设置FLAG_NOT_TOUCH_MODAL选项。设置此选项,意味着窗口不能与软输入法进行交互,所以它的Z序独立于任何活动的输入法(换句话说,它可以全屏显示,如果需要的话,可覆盖输入法窗口)。要修改这一行为,可参考FLAG_ALT_FOCUSALBE_IM选项。 public staticfinal int FLAG_NOT_FOCUSABLE = 0x00000008; 不接受触摸屏事件。 public staticfinal int FLAG_NOT_TOUCHABLE = 0x00000010; 当窗口可以获得焦点(没有设置FLAG_NOT_FOCUSALBE选项)时,仍然将窗口范围之外的点设备事件(鼠标、触摸屏)发送给后面的窗口处理。否则它将独占所有的点设备事件,而不管它们是不是发生在窗口范围之内。 public staticfinal int FLAG_NOT_TOUCH_MODAL = 0x00000020; 如果设置了这个标志,当设备休眠时,点击触摸屏,设备将收到这个第一触摸事件。 通常第一触摸事件被系统所消耗,用户不会看到他们点击屏幕有什么反应。 public staticfinal int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040; 当此窗口为用户可见时,保持设备常开,并保持亮度不变。 public staticfinal int FLAG_KEEP_SCREEN_ON = 0x00000080; 窗口占满整个屏幕,忽略周围的装饰边框(例如状态栏)。此窗口需考虑到装饰边框的内容。 public staticfinal int FLAG_LAYOUT_IN_SCREEN =0x00000100; 允许窗口扩展到屏幕之外。 public staticfinal int FLAG_LAYOUT_NO_LIMITS =0x00000200; 窗口显示时,隐藏所有的屏幕装饰(例如状态条)。使窗口占用整个显示区域。 public staticfinal int FLAG_FULLSCREEN = 0x00000400; 此选项将覆盖FLAG_FULLSCREEN选项,并强制屏幕装饰(如状态条)弹出。 public staticfinal int FLAG_FORCE_NOT_FULLSCREEN =0x00000800; 抖动。指的是对半透明的显示方法。又称“点透”。图形处理较差的设备往往用“点透”替代Alpha混合。 public staticfinal int FLAG_DITHER = 0x00001000; 不允许屏幕截图。 public staticfinal int FLAG_SECURE = 0x00002000; 一种特殊模式,布局参数用于指示显示比例。 public staticfinal int FLAG_SCALED = 0x00004000; 当屏幕有可能贴着脸时,这一选项可防止面颊对屏幕造成误操作。 public staticfinal int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000; 当请求布局时,你的窗口可能出现在状态栏的上面或下面,从而造成遮挡。当设置这一选项后,窗口管理器将确保窗口内容不会被装饰条(状态栏)盖住。 public staticfinal int FLAG_LAYOUT_INSET_DECOR = 0x00010000; 反转FLAG_NOT_FOCUSABLE选项。 如果同时设置了FLAG_NOT_FOCUSABLE选项和本选项,窗口将能够与输入法交互,允许输入法窗口覆盖; 如果FLAG_NOT_FOCUSABLE没有设置而设置了本选项,窗口不能与输入法交互,可以覆盖输入法窗口。 public staticfinal int FLAG_ALT_FOCUSABLE_IM = 0x00020000; 如果你设置了FLAG_NOT_TOUCH_MODAL,那么当触屏事件发生在窗口之外事,可以通过设置此标志接收到一个MotionEvent.ACTION_OUTSIDE事件。注意,你不会收到完整的down/move/up事件,只有第一次down事件时可以收到ACTION_OUTSIDE。 public staticfinal int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000; 当屏幕锁定时,窗口可以被看到。这使得应用程序窗口优先于锁屏界面。可配合FLAG_KEEP_SCREEN_ON选项点亮屏幕并直接显示在锁屏界面之前。可使用FLAG_DISMISS_KEYGUARD选项直接解除非加锁的锁屏状态。此选项只用于最顶层的全屏幕窗口。 public staticfinal int FLAG_SHOW_WHEN_LOCKED = 0x00080000; 请求系统墙纸显示在你的窗口后面。窗口必须是半透明的。 public staticfinal int FLAG_SHOW_WALLPAPER = 0x00100000; 窗口一旦显示出来,系统将点亮屏幕,正如用户唤醒设备那样。 public staticfinal int FLAG_TURN_SCREEN_ON = 0x00200000; 解除锁屏。只有锁屏界面不是加密的才能解锁。如果锁屏界面是加密的,那么用户解锁之后才能看到此窗口,除非设置了FLAG_SHOW_WHEN_LOCKED选项。 public staticfinal int FLAG_DISMISS_KEYGUARD = 0x00400000; 锁屏界面淡出时,继续运行它的动画。 public staticfinal int FLAG_KEEP_SURFACE_WHILE_ANIMATING =0x10000000; 以原始尺寸显示窗口。用于在兼容模式下运行程序。 public staticfinal int FLAG_COMPATIBLE_WINDOW = 0x20000000; 用于系统对话框。设置此选项的窗口将无条件获得焦点。 public staticfinal int FLAG_SYSTEM_ERROR = 0x40000000; 软输入法模式选项: public intsoftInputMode; 以下选项与输入法模式有关: 软输入区域是否可见。 public staticfinal int SOFT_INPUT_MASK_STATE = 0x0f; 未指定状态。 public staticfinal int SOFT_INPUT_STATE_UNSPECIFIED = 0; 不要修改软输入法区域的状态。 public staticfinal int SOFT_INPUT_STATE_UNCHANGED = 1; 隐藏输入法区域(当用户进入窗口时)。 public staticfinal int SOFT_INPUT_STATE_HIDDEN = 2; 当窗口获得焦点时,隐藏输入法区域。 public staticfinal int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3; 显示输入法区域(当用户进入窗口时)。 public staticfinal int SOFT_INPUT_STATE_VISIBLE = 4; 当窗口获得焦点时,显示输入法区域。 public staticfinal int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5; 窗口应当主动调整,以适应软输入窗口。 public staticfinal int SOFT_INPUT_MASK_ADJUST = 0xf0; 未指定状态,系统将根据窗口内容尝试选择一个输入法样式。 public staticfinal int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00; 当输入法显示时,允许窗口重新计算尺寸,使内容不被输入法所覆盖。 不可与SOFT_INPUT_ADJUSP_PAN混合使用;如果两个都没有设置,系统将根据窗口内容自动设置一个选项。 public staticfinal int SOFT_INPUT_ADJUST_RESIZE = 0x10; 输入法显示时平移窗口。它不需要处理尺寸变化,框架能够移动窗口以确保输入焦点可见。 不可与SOFT_INPUT_ADJUST_RESIZE混合使用;如果两个都没有设置,系统将根据窗口内容自动设置一个选项。 public staticfinal int SOFT_INPUT_ADJUST_PAN = 0x20; 当用户转至此窗口时,由系统自动设置,所以你不要设置它。 当窗口显示之后该标志自动清除。 public staticfinal int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100; Gravity设置 public intgravity; 水平边距,容器与widget之间的距离,占容器宽度的百分率。 public floathorizontalMargin; 纵向边距。 public floatverticalMargin; 期望的位图格式。默认为不透明。参考android.graphics.PixelFormat。 public intformat; 窗口所使用的动画设置。它必须是一个系统资源而不是应用程序资源,因为窗口管理器不能访问应用程序。 public intwindowAnimations; 整个窗口的半透明值,1.0表示不透明,0.0表示全透明。 public floatalpha = 1.0f; 当FLAG_DIM_BEHIND设置后生效。该变量指示后面的窗口变暗的程度。 1.0表示完全不透明,0.0表示没有变暗。 public floatdimAmount = 1.0f; 用来覆盖用户设置的屏幕亮度。表示应用用户设置的屏幕亮度。 从0到1调整亮度从暗到最亮发生变化。 public floatscreenBrightness = -1.0f; 窗口的标示符。 public IBindertoken = null; 此窗口所在的包名。 public StringpackageName = null; 屏幕方向,参见android.content.pm.ActivityInfo#screenOrientation。 public intscreenOrientation =ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 下面定义了各种“CHANGE”信息,为copyFrom函数所使用。 public staticfinal int LAYOUT_CHANGED =1<<0; public staticfinal int TYPE_CHANGED =1<<1; public staticfinal int FLAGS_CHANGED =1<<2; public staticfinal int FORMAT_CHANGED =1<<3; public staticfinal int ANIMATION_CHANGED =1<<4; public staticfinal int DIM_AMOUNT_CHANGED =1<<5; public staticfinal int TITLE_CHANGED =1<<6; public staticfinal int ALPHA_CHANGED =1<<7; public staticfinal int MEMORY_TYPE_CHANGED =1<<8; public staticfinal int SOFT_INPUT_MODE_CHANGED =1<<9; public staticfinal int SCREEN_ORIENTATION_CHANGED =1<<10; public staticfinal int SCREEN_BRIGHTNESS_CHANGED =1<<11; 在兼容模式下,备份/恢复参数所使用的内部缓冲区。 private int[]mCompatibilityParamsBackup = null;

更多相关文章

  1. 基于android的远程视频监控系统(已开放源码)
  2. Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程
  3. 关于安卓开发实现拖动条和星级评论
  4. Android(安卓)FrameLayout的显示效果
  5. Android标题栏各种设置
  6. Android中全屏无标题设置(Android学习随笔十一)
  7. Android三种方法设置ImageView的图片
  8. Android默认时区、语言设置
  9. Android组件学习笔记(连接互联网)

随机推荐

  1. 安卓加载模式(Android LauncherMode)
  2. Android百度定位获取经纬度
  3. 【Android(安卓)开发教程】ListView的总
  4. No.11 使用firewall配置的防火墙策略的生
  5. Android中使用代码开关GPS、移动网络(GPR
  6. Android通过ContentProvider往通讯录添加
  7. Android 中的style的使用
  8. GitHub 标星 2.5K+!教你通过玩游戏的方式
  9. android中完全退出当前应用程序的四种方
  10. HCIE-DC考试心得